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

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date: 2010-03-15 11:12:36 +0100 (Mo, 15 Mrz 2010) $
Version:   $Revision: 21745 $

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 "mitkTestingMacros.h"
#include "mitkPlanarArrow.h"
#include "mitkPlaneGeometry.h"

class mitkPlanarArrowTestClass
{

public:

static void TestPlanarArrowPlacement( mitk::PlanarArrow::Pointer PlanarArrow )
{
  // Test for correct minimum number of control points in cross-mode
  MITK_TEST_CONDITION( PlanarArrow->GetMinimumNumberOfControlPoints() == 2, "Minimum number of control points" );

  // Test for correct maximum number of control points in cross-mode
  MITK_TEST_CONDITION( PlanarArrow->GetMaximumNumberOfControlPoints() == 2, "Maximum number of control points" );

  // Initial placement of PlanarArrow
  mitk::Point2D p0;
  p0[0] = 00.0; p0[1] = 0.0;
  PlanarArrow->PlaceFigure( p0 );

  // Add second control point
  mitk::Point2D p1;
  p1[0] = 50.0; p1[1] = 00.0;
  PlanarArrow->SetControlPoint(1, p1 );

  // Test for number of control points
  MITK_TEST_CONDITION( PlanarArrow->GetNumberOfControlPoints() == 2, "Number of control points after placement" );

  // Test for number of polylines
  const mitk::PlanarFigure::VertexContainerType* polyLine0 = PlanarArrow->GetPolyLine( 0 );
  MITK_TEST_CONDITION( PlanarArrow->GetPolyLinesSize() == 1, "Number of polylines after placement" );

  // Get polylines and check if the generated coordinates are OK
  const mitk::Point2D& pp0 = polyLine0->ElementAt( 0 );
  const mitk::Point2D& pp1 = polyLine0->ElementAt( 1 );
  MITK_TEST_CONDITION( ((pp0 == p0) && (pp1 == p1))
    || ((pp0 == p1) && (pp1 == p0)), "Correct polyline 1" );

  // Test for number of measurement features
  // none yet

}
};
/**
 * mitkPlanarArrowTest tests the methods and behavior of mitk::PlanarArrow with sub-tests:
 *
 * 1. Instantiation and basic tests
 *
 */
int mitkPlanarArrowTest(int /* argc */, char* /*argv*/[])
{
  // always start with this!
  MITK_TEST_BEGIN("PlanarArrow")

  // create PlaneGeometry on which to place the PlanarArrow
  mitk::PlaneGeometry::Pointer planeGeometry = mitk::PlaneGeometry::New();
  planeGeometry->InitializeStandardPlane( 100.0, 100.0 );

  // **************************************************************************
  // 1. Instantiation and basic tests
  mitk::PlanarArrow::Pointer PlanarArrow = mitk::PlanarArrow::New();
  PlanarArrow->SetGeometry2D( planeGeometry );

  // first test: did this work?
  MITK_TEST_CONDITION_REQUIRED( PlanarArrow.IsNotNull(), "Testing instantiation" );

  // Test placement of PlanarArrow by control points
  mitkPlanarArrowTestClass::TestPlanarArrowPlacement( PlanarArrow );

  // always end with this!
  MITK_TEST_END();
}
<commit_msg>CHG (#3579): corrected test of control points for planar Arrow<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date: 2010-03-15 11:12:36 +0100 (Mo, 15 Mrz 2010) $
Version:   $Revision: 21745 $

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 "mitkTestingMacros.h"
#include "mitkPlanarArrow.h"
#include "mitkPlaneGeometry.h"

class mitkPlanarArrowTestClass
{

public:

static void TestPlanarArrowPlacement( mitk::PlanarArrow::Pointer PlanarArrow )
{
  // Test for correct minimum number of control points in cross-mode
  MITK_TEST_CONDITION( PlanarArrow->GetMinimumNumberOfControlPoints() == 2, "Minimum number of control points" );

  // Test for correct maximum number of control points in cross-mode
  MITK_TEST_CONDITION( PlanarArrow->GetMaximumNumberOfControlPoints() == 2, "Maximum number of control points" );

  // Initial placement of PlanarArrow
  mitk::Point2D p0;
  p0[0] = 00.0; p0[1] = 0.0;
  PlanarArrow->PlaceFigure( p0 );

  // Add second control point
  mitk::Point2D p1;
  p1[0] = 50.0; p1[1] = 00.0;
  PlanarArrow->SetControlPoint(1, p1 );

  // Test for number of control points
  MITK_TEST_CONDITION( PlanarArrow->GetNumberOfControlPoints() == 2, "Number of control points after placement" );

  // Test for number of polylines
  const mitk::PlanarFigure::VertexContainerType* polyLine0 = PlanarArrow->GetPolyLine( 0 );
  MITK_TEST_CONDITION( PlanarArrow->GetPolyLinesSize() == 1, "Number of polylines after placement" );

  // Get polylines and check if the generated coordinates are OK
  const mitk::Point2D& pp0 = polyLine0->ElementAt( 0 );
  const mitk::Point2D& pp1 = polyLine0->ElementAt( 1 );
  MITK_TEST_CONDITION( (pp0 == p0) && (pp1 == p1), "Correct polyline 1" );

  // Test for number of measurement features
  // none yet

}
};
/**
 * mitkPlanarArrowTest tests the methods and behavior of mitk::PlanarArrow with sub-tests:
 *
 * 1. Instantiation and basic tests
 *
 */
int mitkPlanarArrowTest(int /* argc */, char* /*argv*/[])
{
  // always start with this!
  MITK_TEST_BEGIN("PlanarArrow")

  // create PlaneGeometry on which to place the PlanarArrow
  mitk::PlaneGeometry::Pointer planeGeometry = mitk::PlaneGeometry::New();
  planeGeometry->InitializeStandardPlane( 100.0, 100.0 );

  // **************************************************************************
  // 1. Instantiation and basic tests
  mitk::PlanarArrow::Pointer PlanarArrow = mitk::PlanarArrow::New();
  PlanarArrow->SetGeometry2D( planeGeometry );

  // first test: did this work?
  MITK_TEST_CONDITION_REQUIRED( PlanarArrow.IsNotNull(), "Testing instantiation" );

  // Test placement of PlanarArrow by control points
  mitkPlanarArrowTestClass::TestPlanarArrowPlacement( PlanarArrow );

  // always end with this!
  MITK_TEST_END();
}
<|endoftext|>


<commit_before>/*
    This file is part of KOrganizer.
    Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

// $Id$

#include <qfile.h>

#include <kapplication.h>
//#include <kconfig.h>
#include <kstandarddirs.h>

#include "configdialog.h"

#include "holidaySettings.h"
#include "holidays.h"

class HolidaysFactory : public CalendarDecorationFactory {
  public:
    CalendarDecoration *create() { return new Holidays; }
};

extern "C" {
  void *init_libkorg_holidays()
  {
    return (new HolidaysFactory);
  }
}

extern "C" {
  char *parse_holidays(const char *, int year, short force);
  /** \internal */
  struct holiday {
    char            *string;        /* name of holiday, 0=not a holiday */
    unsigned short  dup;            /* reference count */
  };
  extern struct holiday holiday[366];
}

Holidays::Holidays()
{
  HolidaySettings::self()->readConfig();
  QString holiday( HolidaySettings::holidays() );

  mHolidayFile = locate("data","korganizer/holiday_" + holiday);

  yearLast = 0;
}

Holidays::~Holidays()
{
}

QString Holidays::shortText(const QDate &date)
{
  return getHoliday(date);
}

QString Holidays::info()
{
  return i18n("This plugin provides holidays.");
}

void Holidays::configure(QWidget *parent)
{
  ConfigDialog *dlg = new ConfigDialog(parent);
  dlg->exec();
  delete dlg;
}

QString Holidays::getHoliday(const QDate &qd)
{
  //static int lastYear = 0;
  int lastYear = 0;

  if (mHolidayFile.isEmpty()) return QString::null;

  //if ((lastYear == 0) || (qd.year() != lastYear)) {
  if ((yearLast == 0) || (qd.year() != yearLast)) {
      yearLast = qd.year();
      lastYear = qd.year() - 1900; // silly parse_year takes 2 digit year...
      parse_holidays(QFile::encodeName(mHolidayFile), lastYear, 1);
  }

  if (holiday[qd.dayOfYear()-1].string) {
    QString holidayname = QString::fromUtf8(holiday[qd.dayOfYear()-1].string);
    return holidayname;
  } else {
    return QString::null;
  }
}
<commit_msg>Commit Patch by Michael Buchau, which prevents the crash. Not sure it fixes the actual cause of the crash. Coolo also says it works, so trust him...<commit_after>/*
    This file is part of KOrganizer.
    Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

// $Id$

#include <qfile.h>

#include <kapplication.h>
//#include <kconfig.h>
#include <kstandarddirs.h>

#include "configdialog.h"

#include "holidaySettings.h"
#include "holidays.h"

class HolidaysFactory : public CalendarDecorationFactory {
  public:
    CalendarDecoration *create() { return new Holidays; }
};

extern "C" {
  void *init_libkorg_holidays()
  {
    return (new HolidaysFactory);
  }
}

extern "C" {
  char *parse_holidays(const char *, int year, short force);
  /** \internal */
  struct holiday {
    char            *string;        /* name of holiday, 0=not a holiday */
    unsigned short  dup;            /* reference count */
  };
  extern struct holiday holiday[366];
}

Holidays::Holidays()
{
  HolidaySettings::self()->readConfig();
  QString holiday( HolidaySettings::holidays() );

  mHolidayFile = locate("data","korganizer/holiday_" + holiday);

  yearLast = 0;
}

Holidays::~Holidays()
{
}

QString Holidays::shortText(const QDate &date)
{
  return getHoliday(date);
}

QString Holidays::info()
{
  return i18n("This plugin provides holidays.");
}

void Holidays::configure(QWidget *parent)
{
  ConfigDialog *dlg = new ConfigDialog(parent);
  dlg->exec();
  delete dlg;
}

QString Holidays::getHoliday(const QDate &qd)
{
  //static int lastYear = 0;
  int lastYear = 0;

  if (mHolidayFile.isEmpty() || qd.isNull()) return QString::null;

  //if ((lastYear == 0) || (qd.year() != lastYear)) {
  if ((yearLast == 0) || (qd.year() != yearLast)) {
      yearLast = qd.year();
      lastYear = qd.year() - 1900; // silly parse_year takes 2 digit year...
      parse_holidays(QFile::encodeName(mHolidayFile), lastYear, 1);
  }

  if (holiday[qd.dayOfYear()-1].string) {
    QString holidayname = QString::fromUtf8(holiday[qd.dayOfYear()-1].string);
    return holidayname;
  } else {
    return QString::null;
  }
}
<|endoftext|>


<commit_before>#include <stdlib.h>
#include <stdio.h>
#include "mkl.h" // MKL Standard Lib
#include "mkl_lapacke.h" // MKL LAPACK
#include <cmath>
#include "ode.h"

void newt(double t, double *uprev, double *uguess,
	  double *g, PARAMETER param);
/**< Helper function to compute the next newton step
   for solving a system of equations

   @return (by reference) uguess, the next newton step
   @param param: structure containing number of equations, number of
   time steps, initial and final time, time step
   @param t: current time step
   @param u: function value at the current time step
   @param uprev: previous newton guess
   @param g: ODE specific value
*/

void jac(double t, double *u, double *J, PARAMETER param);
/**< Helper function to the jacobian matrix (using finite differences)
   for advancing the solution from time t(n) to t(n+1) using an
   implicit Euler step on a system of equations

   @return (by reference) J, the Jacobian for the newton step
   @param param: structure containing number of equations, number of
   time steps, initial and final time, time step
   @param t: current time step
   @param u: function value at the current time step
*/

/*
void rhs(double t, double *u, PARAMETER param, double *f) {
  //simplifying ode for debugging
  f[0] = t*u[0]*u[0];
  f[1] = t*u[1]*u[1];
}
*/

void rhs(double t, double *u, PARAMETER param, double *f) {
  double A = 1.0;
  double B = 3.0;
  double alpha = 0.02;
  double dx = 1.0/(param.neq+1);
  int Nx = param.neq/2;

  f[0] = A+u[0]*u[0]*u[Nx] -(B+1.0)*u[0] +alpha/dx/dx*(u[1]-2*u[0]+1.0);
  f[Nx-1] = A+u[Nx-1]*u[Nx-1]*u[2*Nx-1] -(B+1.0)*u[Nx-1]
    + alpha/dx/dx*(1.0-2*u[Nx-1]+u[Nx-2]);

  f[Nx] = B*u[0]- u[0]*u[0]*u[Nx] + alpha/dx/dx*(u[Nx+1]-2*u[Nx]+3.0);
  f[2*Nx-1] = B*u[Nx-1]- u[Nx-1]*u[Nx-1]*u[2*Nx-1]
    + alpha/dx/dx*(3.0-2*u[2*Nx-1]+u[2*Nx-2]);

  for (int i=1; i<Nx-1; i++) {
    f[i] = A + u[i]*u[i]*u[Nx+i] -(B+1.0)*u[i] +alpha/dx/dx*(u[i+1]-2*u[i]+u[i-1]);
    f[Nx+i] = B*u[i]- u[i]*u[i]*u[Nx+i] + alpha/dx/dx*(u[Nx+i+1]-2*u[Nx+i]+u[Nx+i-1]);
  }
}

void newt(double t, double *uprev, double * Kguess,
	  double *g, PARAMETER param, BUTCHER rk) {

  // note: creation and subsequent deletion of temp variables may lead
  // to an unfair benchmark comparison.
  double * temp = new double[param.neq];
  double * ftemp = new double[param.neq];

  int start_ind;
  for (int ss =0; ss<rk.S; ss++) {

    // initialize
    for (int i =0; i<param.neq; i++) {
      temp[i] = uprev[i];
    }

    // compute temp = y + a_ij*K_j
    for (int s = 0; s<rk.S; s++) {
      double fact = rk.A[ss][s]*param.dt;
      start_ind = s*param.neq;
      for (int i = 0; i<param.neq; i++) {
	temp[i] = temp[i] + fact*Kguess[start_ind+i];
      }
    }

    rhs(t+rk.c[ss]*param.dt,temp,param,ftemp);
    start_ind = ss*param.neq;
    for (int i =0; i<param.neq; i++) {
      g[start_ind+i] = Kguess[start_ind+i]-ftemp[i];
    }
  }

  delete [] temp;
  delete [] ftemp;

  /*  for (int i =0; i<param.neq*rk.S; i++) {
    printf("%d, %g\n",i,g[i]);
  }
  printf("\n");
  */

}

void jac(double t, double *uprev, double *Kguess,
	 double *J, PARAMETER param, BUTCHER rk) {

  double d = 1e-5; // numerical jacobian approximation

  double *g1;
  double *g2;

  // need to allocate memory
  g1 = new double[rk.S*param.neq];
  g2 = new double[rk.S*param.neq];

  // note, instead of using newt, use rhs for efficiency
  newt(t,uprev,Kguess,g1,param,rk);

  for (int i =0; i<param.neq*rk.S; i++) {
    Kguess[i] = Kguess[i] + d;
    newt(t,uprev,Kguess,g2,param,rk);
    Kguess[i] = Kguess[i] - d;

    for (int j = 0; j < param.neq*rk.S; j++) {
      J[j*param.neq*rk.S + i] = (g2[j]-g1[j])/d;
    }
  }

  /*
  for (int i = 0; i<param.neq; i++) {
    for (int j = 0; j<param.neq; j++) {
      u1[j] = u[j];
    }
    u1[i] = u1[i] + d;

    rhs(t,u1,param,f1);

    for (int j = 0; j<param.neq; j++) {
      J[j*param.neq+i] = -param.dt*(f1[j]-f[j])/d;
    }
    J[i*param.neq+i] = 1.0+J[i*param.neq+i];
  }
  */

  // need to delete memory
  delete [] g1;
  delete [] g2;
}

void step(double t, double* uold, PARAMETER param, double* unew, BUTCHER rk) {
  // t is current time

  double NEWTON_TOL = 1.0e-12;
  int NEWTON_MAXSTEP = 1000;

  typedef double *pdoub;

  pdoub J;
  pdoub stepsize;

  int neq = param.neq*rk.S;
  stepsize = new double[neq];

  J = new double[neq*neq];

  // initialize memory for stage weights
  double * K = new double [neq];
  double * Ktemp = new double[param.neq];

  // try and find a good initial guess
  double * ftemp = new double[param.neq];
  rhs(t,uold,param,ftemp);

  double * temp = new double[param.neq];

  for (int s = 0; s<rk.S; s++){

    for (int i =0; i< param.neq; i++) {
      temp[i] = uold[i] + rk.c[s]*param.dt*ftemp[i];
    }

    rhs(t+rk.c[s]*param.dt,temp,param,Ktemp);

    for (int i = 0; i < param.neq; i++) {
      K[s*param.neq+i] = Ktemp[i];
    }
  }

  delete [] temp;
  delete [] ftemp;
  delete [] Ktemp;

  double maxstepsize;

  int counter=0;
  int * pivot = new int[neq];

  //iterate until stages K_i, i=0..s-1 converge
  while (1) {

    // finding zero of nonlinear system.  residual stored in stepsized
    newt(t,uold,K,stepsize,param,rk);

    // compute numerical Jacobian
    jac(t,uold,K,J,param,rk);

    int info;
    int nrhs = 1;

    // blas linear solve
    info = LAPACKE_dgesv(LAPACK_ROW_MAJOR, neq,
		  nrhs, J, neq,pivot,stepsize,1);

    // check for convergence
    maxstepsize = 0.0;
    for (int i = 0; i<neq; i++) {
      if (std::abs(stepsize[i])>maxstepsize) {
	maxstepsize = std::abs(stepsize[i]);
      }
    }

    // updated Kguess using stepsize
    for (int i =0; i<neq; i++) {
      K[i] = K[i] - stepsize[i];
    }

    // if update sufficiently small enough
    if ( maxstepsize < NEWTON_TOL) {
      break;
    }

    counter++;
    //error if too many steps
    if (counter > NEWTON_MAXSTEP) {
      fprintf(stderr,"max newton iterations reached\n");
      exit(42);
    }
  } // end newton iteration

  // form solution from stage weights
  for (int i =0; i<param.neq; i++) {
    unew[i] = uold[i];
  }

  for (int s = 0; s < rk.S; s++) {
    for (int i=0; i<param.neq; i++) {
      unew[i] = unew[i] + param.dt*rk.b[s]*K[s*param.neq+i];
    }
  }

  delete [] pivot;
  delete [] stepsize;
  delete [] J;
  delete [] K;

  /*
  printf("exiting\n");
  exit(42);
  */
}
<commit_msg>changing newton tol for radau integrator<commit_after>#include <stdlib.h>
#include <stdio.h>
#include "mkl.h" // MKL Standard Lib
#include "mkl_lapacke.h" // MKL LAPACK
#include <cmath>
#include "ode.h"

void newt(double t, double *uprev, double *uguess,
	  double *g, PARAMETER param);
/**< Helper function to compute the next newton step
   for solving a system of equations

   @return (by reference) uguess, the next newton step
   @param param: structure containing number of equations, number of
   time steps, initial and final time, time step
   @param t: current time step
   @param u: function value at the current time step
   @param uprev: previous newton guess
   @param g: ODE specific value
*/

void jac(double t, double *u, double *J, PARAMETER param);
/**< Helper function to the jacobian matrix (using finite differences)
   for advancing the solution from time t(n) to t(n+1) using an
   implicit Euler step on a system of equations

   @return (by reference) J, the Jacobian for the newton step
   @param param: structure containing number of equations, number of
   time steps, initial and final time, time step
   @param t: current time step
   @param u: function value at the current time step
*/

/*
void rhs(double t, double *u, PARAMETER param, double *f) {
  //simplifying ode for debugging
  f[0] = t*u[0]*u[0];
  f[1] = t*u[1]*u[1];
}
*/

void rhs(double t, double *u, PARAMETER param, double *f) {
  double A = 1.0;
  double B = 3.0;
  double alpha = 0.02;
  double dx = 1.0/(param.neq+1);
  int Nx = param.neq/2;

  f[0] = A+u[0]*u[0]*u[Nx] -(B+1.0)*u[0] +alpha/dx/dx*(u[1]-2*u[0]+1.0);
  f[Nx-1] = A+u[Nx-1]*u[Nx-1]*u[2*Nx-1] -(B+1.0)*u[Nx-1]
    + alpha/dx/dx*(1.0-2*u[Nx-1]+u[Nx-2]);

  f[Nx] = B*u[0]- u[0]*u[0]*u[Nx] + alpha/dx/dx*(u[Nx+1]-2*u[Nx]+3.0);
  f[2*Nx-1] = B*u[Nx-1]- u[Nx-1]*u[Nx-1]*u[2*Nx-1]
    + alpha/dx/dx*(3.0-2*u[2*Nx-1]+u[2*Nx-2]);

  for (int i=1; i<Nx-1; i++) {
    f[i] = A + u[i]*u[i]*u[Nx+i] -(B+1.0)*u[i] +alpha/dx/dx*(u[i+1]-2*u[i]+u[i-1]);
    f[Nx+i] = B*u[i]- u[i]*u[i]*u[Nx+i] + alpha/dx/dx*(u[Nx+i+1]-2*u[Nx+i]+u[Nx+i-1]);
  }
}

void newt(double t, double *uprev, double * Kguess,
	  double *g, PARAMETER param, BUTCHER rk) {

  // note: creation and subsequent deletion of temp variables may lead
  // to an unfair benchmark comparison.
  double * temp = new double[param.neq];
  double * ftemp = new double[param.neq];

  int start_ind;
  for (int ss =0; ss<rk.S; ss++) {

    // initialize
    for (int i =0; i<param.neq; i++) {
      temp[i] = uprev[i];
    }

    // compute temp = y + a_ij*K_j
    for (int s = 0; s<rk.S; s++) {
      double fact = rk.A[ss][s]*param.dt;
      start_ind = s*param.neq;
      for (int i = 0; i<param.neq; i++) {
	temp[i] = temp[i] + fact*Kguess[start_ind+i];
      }
    }

    rhs(t+rk.c[ss]*param.dt,temp,param,ftemp);
    start_ind = ss*param.neq;
    for (int i =0; i<param.neq; i++) {
      g[start_ind+i] = Kguess[start_ind+i]-ftemp[i];
    }
  }

  delete [] temp;
  delete [] ftemp;

  /*  for (int i =0; i<param.neq*rk.S; i++) {
    printf("%d, %g\n",i,g[i]);
  }
  printf("\n");
  */

}

void jac(double t, double *uprev, double *Kguess,
	 double *J, PARAMETER param, BUTCHER rk) {

  double d = 1e-5; // numerical jacobian approximation

  double *g1;
  double *g2;

  // need to allocate memory
  g1 = new double[rk.S*param.neq];
  g2 = new double[rk.S*param.neq];

  // note, instead of using newt, use rhs for efficiency
  newt(t,uprev,Kguess,g1,param,rk);

  for (int i =0; i<param.neq*rk.S; i++) {
    Kguess[i] = Kguess[i] + d;
    newt(t,uprev,Kguess,g2,param,rk);
    Kguess[i] = Kguess[i] - d;

    for (int j = 0; j < param.neq*rk.S; j++) {
      J[j*param.neq*rk.S + i] = (g2[j]-g1[j])/d;
    }
  }

  /*
  for (int i = 0; i<param.neq; i++) {
    for (int j = 0; j<param.neq; j++) {
      u1[j] = u[j];
    }
    u1[i] = u1[i] + d;

    rhs(t,u1,param,f1);

    for (int j = 0; j<param.neq; j++) {
      J[j*param.neq+i] = -param.dt*(f1[j]-f[j])/d;
    }
    J[i*param.neq+i] = 1.0+J[i*param.neq+i];
  }
  */

  // need to delete memory
  delete [] g1;
  delete [] g2;
}

void step(double t, double* uold, PARAMETER param, double* unew, BUTCHER rk) {
  // t is current time

  double NEWTON_TOL = 1.0e-12;
  int NEWTON_MAXSTEP = 10;

  typedef double *pdoub;

  pdoub J;
  pdoub stepsize;

  int neq = param.neq*rk.S;
  stepsize = new double[neq];

  J = new double[neq*neq];

  // initialize memory for stage weights
  double * K = new double [neq];
  double * Ktemp = new double[param.neq];

  // try and find a good initial guess
  double * ftemp = new double[param.neq];
  rhs(t,uold,param,ftemp);

  double * temp = new double[param.neq];

  for (int s = 0; s<rk.S; s++){

    for (int i =0; i< param.neq; i++) {
      temp[i] = uold[i] + rk.c[s]*param.dt*ftemp[i];
    }

    rhs(t+rk.c[s]*param.dt,temp,param,Ktemp);

    for (int i = 0; i < param.neq; i++) {
      K[s*param.neq+i] = Ktemp[i];
    }
  }

  delete [] temp;
  delete [] ftemp;
  delete [] Ktemp;

  double maxstepsize;

  int counter=0;
  int * pivot = new int[neq];

  //iterate until stages K_i, i=0..s-1 converge
  while (1) {

    // finding zero of nonlinear system.  residual stored in stepsized
    newt(t,uold,K,stepsize,param,rk);

    // compute numerical Jacobian
    jac(t,uold,K,J,param,rk);

    int info;
    int nrhs = 1;

    // blas linear solve
    info = LAPACKE_dgesv(LAPACK_ROW_MAJOR, neq,
		  nrhs, J, neq,pivot,stepsize,1);

    // check for convergence
    maxstepsize = 0.0;
    for (int i = 0; i<neq; i++) {
      if (std::abs(stepsize[i])>maxstepsize) {
	maxstepsize = std::abs(stepsize[i]);
      }
    }

    // updated Kguess using stepsize
    for (int i =0; i<neq; i++) {
      K[i] = K[i] - stepsize[i];
    }

    // if update sufficiently small enough
    if ( maxstepsize < NEWTON_TOL) {
      break;
    }

    counter++;
    //error if too many steps
    if (counter > NEWTON_MAXSTEP) {
      fprintf(stderr,"max newton iterations reached\n");
      exit(42);
    }
  } // end newton iteration

  // form solution from stage weights
  for (int i =0; i<param.neq; i++) {
    unew[i] = uold[i];
  }

  for (int s = 0; s < rk.S; s++) {
    for (int i=0; i<param.neq; i++) {
      unew[i] = unew[i] + param.dt*rk.b[s]*K[s*param.neq+i];
    }
  }

  delete [] pivot;
  delete [] stepsize;
  delete [] J;
  delete [] K;

  /*
  printf("exiting\n");
  exit(42);
  */
}
<|endoftext|>


<commit_before>/* OpenSceneGraph example, osgdrawinstanced.
*
*  Permission is hereby granted, free of charge, to any person obtaining a copy
*  of this software and associated documentation files (the "Software"), to deal
*  in the Software without restriction, including without limitation the rights
*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*  copies of the Software, and to permit persons to whom the Software is
*  furnished to do so, subject to the following conditions:
*
*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
*  THE SOFTWARE.
*/
//
// This code is copyright (c) 2008 Skew Matrix Software LLC. You may use
// the code under the licensing terms described above.
//

#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Geometry>
#include <osg/Texture2D>

#include <osgDB/WriteFile>

#include <iostream>

void
createDAIGeometry( osg::Geometry& geom, int nInstances=1 )
{
    const float halfDimX( .5 );
    const float halfDimZ( .5 );

    osg::Vec3Array* v = new osg::Vec3Array;
    v->resize( 4 );
    geom.setVertexArray( v );

    // Geometry for a single quad.
    (*v)[ 0 ] = osg::Vec3( -halfDimX, 0., -halfDimZ );
    (*v)[ 1 ] = osg::Vec3( halfDimX, 0., -halfDimZ );
    (*v)[ 2 ] = osg::Vec3( halfDimX, 0., halfDimZ );
    (*v)[ 3 ] = osg::Vec3( -halfDimX, 0., halfDimZ );

    // Use the DrawArraysInstanced PrimitiveSet and tell it to draw 1024 instances.
    geom.addPrimitiveSet( new osg::DrawArrays( GL_QUADS, 0, 4, nInstances ) );
}

osg::StateSet*
createStateSet()
{
    osg::ref_ptr< osg::StateSet > ss = new osg::StateSet;

    // Create a vertex program that references the gl_InstanceID to
    // render each instance uniquely. gl_InstanceID will be in the range
    // 0 to numInstances-1 (1023 in our case).
    std::string vertexSource =
        "uniform sampler2D osgLogo; \n"
        "uniform float osg_SimulationTime; \n"

        "void main() \n"
        "{ \n"
            // Using the instance ID, generate "texture coords" for this instance.
            "vec2 tC; \n"
            "float r = float(gl_InstanceID) / 32.; \n"
            "tC.s = fract( r ); tC.t = floor( r ) / 32.; \n"
            // Get the color from the OSG logo.
            "gl_FrontColor = texture2D( osgLogo, tC ); \n"

            // Use the (scaled) tex coord to translate the position of the vertices.
            "vec4 pos = vec4( tC.s * 48., 0., tC.t * 48., 1. ); \n"

            // Compute a rotation angle from the instanceID and elapsed time.
            "float timeOffset = gl_InstanceID / (32. * 32.); \n"
            "float angle = ( osg_SimulationTime - timeOffset ) * 6.283; \n"
            "float sa = sin( angle ); \n"
            "float ca = cos( angle ); \n"
            // New orientation, rotate around z axis.
            "vec4 newX = vec4( ca, sa, 0., 0. ); \n"
            "vec4 newY = vec4( sa, ca, 0., 0. ); \n"
            "vec4 newZ = vec4( 0., 0., 1., 0. ); \n"
            "mat4 mV = mat4( newX, newY, newZ, pos ); \n"
            "gl_Position = ( gl_ModelViewProjectionMatrix * mV * gl_Vertex ); \n"
        "} \n";

    osg::ref_ptr< osg::Shader > vertexShader = new osg::Shader();
    vertexShader->setType( osg::Shader::VERTEX );
    vertexShader->setShaderSource( vertexSource );

    osg::ref_ptr< osg::Program > program = new osg::Program();
    program->addShader( vertexShader.get() );

    ss->setAttribute( program.get(),
        osg::StateAttribute::ON | osg::StateAttribute::PROTECTED );

    osg::ref_ptr< osg::Image> iLogo = osgDB::readRefImageFile( "Images/osg128.png" );
    if( !iLogo.valid() )
    {
        osg::notify( osg::ALWAYS ) << "Can't open image file osg128.png" << std::endl;
        return( NULL );
    }
    osg::Texture2D* texLogo = new osg::Texture2D( iLogo.get() );
    texLogo->setFilter( osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR );
    texLogo->setFilter( osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR );

    ss->setTextureAttribute( 0, texLogo );

    osg::ref_ptr< osg::Uniform > texLogoUniform =
        new osg::Uniform( "osgLogo", 0 );
    ss->addUniform( texLogoUniform.get() );

    return( ss.release() );
}

int main( int argc, char **argv )
{
    osg::ArgumentParser arguments(&argc, argv);

   // Make a scene graph consisting of a single Geode, containing
    // a single Geometry, and a single PrimitiveSet.
    osg::ref_ptr< osg::Geode > geode = new osg::Geode;

    osg::ref_ptr< osg::Geometry > geom = new osg::Geometry;
    // Configure the Geometry for use with EXT_draw_arrays:
    // DL off and buffer objects on.
    geom->setUseDisplayList( false );
    geom->setUseVertexBufferObjects( true );
    // OSG has no clue where out vertex shader will place the geometric data,
    // so specify an initial bound to allow proper culling and near/far computation.
    osg::BoundingBox bb( -1., -.1, -1., 49., 1., 49. );
    geom->setInitialBound( bb );
    // Add geometric data and the PrimitiveSet. Specify numInstances as 32*32 or 1024.
    createDAIGeometry( *geom, 32*32 );
    geode->addDrawable( geom.get() );

    // Create a StateSet to render the instanced Geometry.
    osg::ref_ptr< osg::StateSet > ss = createStateSet();
    geode->setStateSet( ss.get() );

    // osgDB::writeNodeFile(*geode, "instanced.osgt");

    osgViewer::Viewer viewer(arguments);
    viewer.setSceneData( geode.get() );
    return viewer.run();
}
<commit_msg>add version and required extension<commit_after>/* OpenSceneGraph example, osgdrawinstanced.
*
*  Permission is hereby granted, free of charge, to any person obtaining a copy
*  of this software and associated documentation files (the "Software"), to deal
*  in the Software without restriction, including without limitation the rights
*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*  copies of the Software, and to permit persons to whom the Software is
*  furnished to do so, subject to the following conditions:
*
*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
*  THE SOFTWARE.
*/
//
// This code is copyright (c) 2008 Skew Matrix Software LLC. You may use
// the code under the licensing terms described above.
//

#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Geometry>
#include <osg/Texture2D>

#include <osgDB/WriteFile>

#include <iostream>

void
createDAIGeometry( osg::Geometry& geom, int nInstances=1 )
{
    const float halfDimX( .5 );
    const float halfDimZ( .5 );

    osg::Vec3Array* v = new osg::Vec3Array;
    v->resize( 4 );
    geom.setVertexArray( v );

    // Geometry for a single quad.
    (*v)[ 0 ] = osg::Vec3( -halfDimX, 0., -halfDimZ );
    (*v)[ 1 ] = osg::Vec3( halfDimX, 0., -halfDimZ );
    (*v)[ 2 ] = osg::Vec3( halfDimX, 0., halfDimZ );
    (*v)[ 3 ] = osg::Vec3( -halfDimX, 0., halfDimZ );

    // Use the DrawArraysInstanced PrimitiveSet and tell it to draw 1024 instances.
    geom.addPrimitiveSet( new osg::DrawArrays( GL_QUADS, 0, 4, nInstances ) );
}

osg::StateSet*
createStateSet()
{
    osg::ref_ptr< osg::StateSet > ss = new osg::StateSet;

    // Create a vertex program that references the gl_InstanceID to
    // render each instance uniquely. gl_InstanceID will be in the range
    // 0 to numInstances-1 (1023 in our case).
    std::string vertexSource =
        "#version 120\n"
        "#extension GL_ARB_draw_instanced : enable\n"
        "uniform sampler2D osgLogo; \n"
        "uniform float osg_SimulationTime; \n"

        "void main() \n"
        "{ \n"
            // Using the instance ID, generate "texture coords" for this instance.
            "vec2 tC; \n"
            "float r = float(gl_InstanceID) / 32.; \n"
            "tC.s = fract( r ); tC.t = floor( r ) / 32.; \n"
            // Get the color from the OSG logo.
            "gl_FrontColor = texture2D( osgLogo, tC ); \n"

            // Use the (scaled) tex coord to translate the position of the vertices.
            "vec4 pos = vec4( tC.s * 48., 0., tC.t * 48., 1. ); \n"

            // Compute a rotation angle from the instanceID and elapsed time.
            "float timeOffset = gl_InstanceID / (32. * 32.); \n"
            "float angle = ( osg_SimulationTime - timeOffset ) * 6.283; \n"
            "float sa = sin( angle ); \n"
            "float ca = cos( angle ); \n"
            // New orientation, rotate around z axis.
            "vec4 newX = vec4( ca, sa, 0., 0. ); \n"
            "vec4 newY = vec4( sa, ca, 0., 0. ); \n"
            "vec4 newZ = vec4( 0., 0., 1., 0. ); \n"
            "mat4 mV = mat4( newX, newY, newZ, pos ); \n"
            "gl_Position = ( gl_ModelViewProjectionMatrix * mV * gl_Vertex ); \n"
        "} \n";

    osg::ref_ptr< osg::Shader > vertexShader = new osg::Shader();
    vertexShader->setType( osg::Shader::VERTEX );
    vertexShader->setShaderSource( vertexSource );

    osg::ref_ptr< osg::Program > program = new osg::Program();
    program->addShader( vertexShader.get() );

    ss->setAttribute( program.get(),
        osg::StateAttribute::ON | osg::StateAttribute::PROTECTED );

    osg::ref_ptr< osg::Image> iLogo = osgDB::readRefImageFile( "Images/osg128.png" );
    if( !iLogo.valid() )
    {
        osg::notify( osg::ALWAYS ) << "Can't open image file osg128.png" << std::endl;
        return( NULL );
    }
    osg::Texture2D* texLogo = new osg::Texture2D( iLogo.get() );
    texLogo->setFilter( osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR );
    texLogo->setFilter( osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR );

    ss->setTextureAttribute( 0, texLogo );

    osg::ref_ptr< osg::Uniform > texLogoUniform =
        new osg::Uniform( "osgLogo", 0 );
    ss->addUniform( texLogoUniform.get() );

    return( ss.release() );
}

int main( int argc, char **argv )
{
    osg::ArgumentParser arguments(&argc, argv);

   // Make a scene graph consisting of a single Geode, containing
    // a single Geometry, and a single PrimitiveSet.
    osg::ref_ptr< osg::Geode > geode = new osg::Geode;

    osg::ref_ptr< osg::Geometry > geom = new osg::Geometry;
    // Configure the Geometry for use with EXT_draw_arrays:
    // DL off and buffer objects on.
    geom->setUseDisplayList( false );
    geom->setUseVertexBufferObjects( true );
    // OSG has no clue where out vertex shader will place the geometric data,
    // so specify an initial bound to allow proper culling and near/far computation.
    osg::BoundingBox bb( -1., -.1, -1., 49., 1., 49. );
    geom->setInitialBound( bb );
    // Add geometric data and the PrimitiveSet. Specify numInstances as 32*32 or 1024.
    createDAIGeometry( *geom, 32*32 );
    geode->addDrawable( geom.get() );

    // Create a StateSet to render the instanced Geometry.
    osg::ref_ptr< osg::StateSet > ss = createStateSet();
    geode->setStateSet( ss.get() );

    // osgDB::writeNodeFile(*geode, "instanced.osgt");

    osgViewer::Viewer viewer(arguments);
    viewer.setSceneData( geode.get() );
    return viewer.run();
}
<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/
#include <mitkContourModelMapper2D.h>

#include <vtkPoints.h>
#include <vtkCellArray.h>
#include <vtkAppendPolyData.h>
#include <vtkProperty.h>
#include <vtkPlane.h>
#include <vtkCutter.h>
#include <vtkStripper.h>
#include <vtkTubeFilter.h>
#include <vtkSphereSource.h>

mitk::ContourModelMapper2D::ContourModelMapper2D()
{
}

mitk::ContourModelMapper2D::~ContourModelMapper2D()
{
}

const mitk::ContourModel* mitk::ContourModelMapper2D::GetInput( void )
{
  //convient way to get the data from the dataNode
  return static_cast< const mitk::ContourModel * >( this->GetData() );
}

vtkProp* mitk::ContourModelMapper2D::GetVtkProp(mitk::BaseRenderer* renderer)
{
  //return the actor corresponding to the renderer
  return m_LSH.GetLocalStorage(renderer)->m_Actor;
}

void mitk::ContourModelMapper2D::MitkRenderOverlay(BaseRenderer* renderer)
{
  if ( this->IsVisible(renderer)==false )
    return;
  if ( this->GetVtkProp(renderer)->GetVisibility() )
  {
    this->GetVtkProp(renderer)->RenderOverlay(renderer->GetVtkRenderer());
  }
}

void mitk::ContourModelMapper2D::MitkRenderOpaqueGeometry(BaseRenderer* renderer)
{
  if ( this->IsVisible( renderer )==false )
    return;
  if ( this->GetVtkProp(renderer)->GetVisibility() )
  {
    this->GetVtkProp(renderer)->RenderOpaqueGeometry( renderer->GetVtkRenderer() );
  }
}

void mitk::ContourModelMapper2D::MitkRenderTranslucentGeometry(BaseRenderer* renderer)
{
  if ( this->IsVisible(renderer)==false )
    return;
  if ( this->GetVtkProp(renderer)->GetVisibility() )
  {
    this->GetVtkProp(renderer)->RenderTranslucentPolygonalGeometry(renderer->GetVtkRenderer());
  }
}

void mitk::ContourModelMapper2D::MitkRenderVolumetricGeometry(BaseRenderer* renderer)
{
  if(IsVisible(renderer)==false)
    return;
  if ( GetVtkProp(renderer)->GetVisibility() )
  {
    this->GetVtkProp(renderer)->RenderVolumetricGeometry(renderer->GetVtkRenderer());
  }
}

void mitk::ContourModelMapper2D::GenerateDataForRenderer( mitk::BaseRenderer *renderer )
{
  /*++ convert the contour to vtkPolyData and set it as input for our mapper ++*/

  LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);

  mitk::ContourModel* inputContour  = static_cast< mitk::ContourModel* >( this->GetData() );

  unsigned int timestep = renderer->GetTimeStep();

  //if there's something to be rendered
  if( inputContour->GetNumberOfVertices(timestep) > 0)
  {
    localStorage->m_OutlinePolyData = this->CreateVtkPolyDataFromContour(inputContour, renderer);
  }

  this->ApplyContourProperties(renderer);

  localStorage->m_Mapper->SetInput(localStorage->m_OutlinePolyData);

}

void mitk::ContourModelMapper2D::Update(mitk::BaseRenderer* renderer)
{
  if ( !this->IsVisible( renderer ) )
  {
    return;
  }

  //check if there is something to be rendered
  mitk::ContourModel* data  = static_cast< mitk::ContourModel*>( this->GetData() );
  if ( data == NULL )
  {
    return;
  }

  // Calculate time step of the input data for the specified renderer (integer value)
  this->CalculateTimeStep( renderer );

    LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);

  // Check if time step is valid
  const TimeSlicedGeometry *dataTimeGeometry = data->GetTimeSlicedGeometry();
  if ( ( dataTimeGeometry == NULL )
    || ( dataTimeGeometry->GetTimeSteps() == 0 )
    || ( !dataTimeGeometry->IsValidTime( renderer->GetTimeStep() ) ) )
  {
    //clear the rendered polydata
    localStorage->m_Mapper->RemoveAllInputs();//SetInput(vtkSmartPointer<vtkPolyData>::New());
    return;
  }

  const DataNode *node = this->GetDataNode();
  data->UpdateOutputInformation();

  //check if something important has changed and we need to rerender
  if ( (localStorage->m_LastUpdateTime < node->GetMTime()) //was the node modified?
    || (localStorage->m_LastUpdateTime < data->GetPipelineMTime()) //Was the data modified?
    || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldGeometry2DUpdateTime()) //was the geometry modified?
    || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldGeometry2D()->GetMTime())
    || (localStorage->m_LastUpdateTime < node->GetPropertyList()->GetMTime()) //was a property modified?
    || (localStorage->m_LastUpdateTime < node->GetPropertyList(renderer)->GetMTime()) )
  {
    this->GenerateDataForRenderer( renderer );
  }

  // since we have checked that nothing important has changed, we can set
  // m_LastUpdateTime to the current time
  localStorage->m_LastUpdateTime.Modified();
}

vtkSmartPointer<vtkPolyData> mitk::ContourModelMapper2D::CreateVtkPolyDataFromContour(mitk::ContourModel* inputContour, mitk::BaseRenderer* renderer)
{
  unsigned int timestep = this->GetTimestep();

  /* First of all convert the control points of the contourModel to vtk points
  * and add lines in between them
  */
  //the points to draw
  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
  //the lines to connect the points
  vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
  // Create a polydata to store everything in
  vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();

  vtkSmartPointer<vtkAppendPolyData> appendPoly = vtkSmartPointer<vtkAppendPolyData>::New();

  //iterate over all control points
  mitk::ContourModel::VertexIterator current = inputContour->IteratorBegin(timestep);
  mitk::ContourModel::VertexIterator next = inputContour->IteratorBegin(timestep);
  if(next != inputContour->IteratorEnd(timestep))
  {
    next++;

    mitk::ContourModel::VertexIterator end = inputContour->IteratorEnd(timestep);

    while(next != end)
    {
      mitk::ContourModel::VertexType* currentControlPoint = *current;
      mitk::ContourModel::VertexType* nextControlPoint = *next;

      vtkIdType p1 = points->InsertNextPoint(currentControlPoint->Coordinates[0], currentControlPoint->Coordinates[1], currentControlPoint->Coordinates[2]);
      vtkIdType p2 = points->InsertNextPoint(nextControlPoint->Coordinates[0], nextControlPoint->Coordinates[1], nextControlPoint->Coordinates[2]);
      //add the line between both contorlPoints
      lines->InsertNextCell(2);
      lines->InsertCellPoint(p1);
      lines->InsertCellPoint(p2);

      if ( currentControlPoint->IsActive )
      {
        vtkSmartPointer<vtkSphereSource> sphere = vtkSmartPointer<vtkSphereSource>::New();

        sphere->SetRadius(1.5);
        sphere->SetCenter(currentControlPoint->Coordinates[0], currentControlPoint->Coordinates[1], currentControlPoint->Coordinates[2]);
        sphere->Update();
        appendPoly->AddInput(sphere->GetOutput());
      }

      current++;
      next++;
    }// while (it!=end)

    //check if last control point is enabled to draw it
    if ( (*current)->IsActive )
    {
      vtkSmartPointer<vtkSphereSource> sphere = vtkSmartPointer<vtkSphereSource>::New();

      sphere->SetRadius(1.5);
      sphere->SetCenter((*current)->Coordinates[0], (*current)->Coordinates[1], (*current)->Coordinates[2]);

      appendPoly->AddInput(sphere->GetOutput());
      sphere->Update();
    }

    /* If the contour is closed an additional line has to be created between the very first point
    * and the last point
    */
    if(inputContour->IsClosed(timestep))
    {
      //add a line from the last to the first control point
      mitk::ContourModel::VertexType* firstControlPoint = *(inputContour->IteratorBegin(timestep));
      mitk::ContourModel::VertexType* lastControlPoint = *(--(inputContour->IteratorEnd(timestep)));
      vtkIdType p2 = points->InsertNextPoint(lastControlPoint->Coordinates[0], lastControlPoint->Coordinates[1], lastControlPoint->Coordinates[2]);
      vtkIdType p1 = points->InsertNextPoint(firstControlPoint->Coordinates[0], firstControlPoint->Coordinates[1], firstControlPoint->Coordinates[2]);

      //add the line between both contorlPoints
      lines->InsertNextCell(2);
      lines->InsertCellPoint(p1);
      lines->InsertCellPoint(p2);
    }//end if(isClosed)

    // Create a polydata to store everything in
    vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
    // Add the points to the dataset
    polyData->SetPoints(points);
    // Add the lines to the dataset
    polyData->SetLines(lines);

    //check for the worldgeometry from the current render window
    mitk::PlaneGeometry* currentWorldGeometry = dynamic_cast<mitk::PlaneGeometry*>( const_cast<mitk::Geometry2D*>(renderer->GetCurrentWorldGeometry2D()));
    if (currentWorldGeometry)
    {
      //slice through the data to get a 2D representation of the (possible) 3D contour

      //needed because currently there is no outher solution if the contour is within the plane
      vtkSmartPointer<vtkTubeFilter> tubeFilter = vtkSmartPointer<vtkTubeFilter>::New();
      tubeFilter->SetInput(polyData);
      tubeFilter->SetRadius(0.05);

      //origin and normal of vtkPlane
      mitk::Point3D origin = currentWorldGeometry->GetOrigin();
      mitk::Vector3D normal = currentWorldGeometry->GetNormal();

      //the implicit function to slice through the polyData
      vtkSmartPointer<vtkPlane> plane = vtkSmartPointer<vtkPlane>::New();
      plane->SetOrigin(origin[0], origin[1], origin[2]);
      plane->SetNormal(normal[0], normal[1], normal[2]);

      //cuts through vtkPolyData with a given implicit function. In our case a plane
      vtkSmartPointer<vtkCutter> cutter = vtkSmartPointer<vtkCutter>::New();

      cutter->SetCutFunction(plane);
      //cutter->SetInput(polyData);
      cutter->SetInputConnection(tubeFilter->GetOutputPort());

      //we want the scalars of the input - so turn off generating the scalars within vtkCutter
      cutter->GenerateCutScalarsOff();
      cutter->Update();

      polyData= cutter->GetOutput();

    }//end if(worldGeometry)
    appendPoly->AddInput(polyData);

  }//end if (it != end)
  appendPoly->Update();
  vtkSmartPointer<vtkPolyData> poly = appendPoly->GetOutput();
  return poly;
}

void mitk::ContourModelMapper2D::ApplyContourProperties(mitk::BaseRenderer* renderer)
{
  LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);

  float binaryOutlineWidth(1.0);
  if (this->GetDataNode()->GetFloatProperty( "contour width", binaryOutlineWidth, renderer ))
  {
    localStorage->m_Actor->GetProperty()->SetLineWidth(binaryOutlineWidth);
  }

  //make sure that directional lighting isn't used for our contour
  localStorage->m_Actor->GetProperty()->SetAmbient(1.0);
  localStorage->m_Actor->GetProperty()->SetDiffuse(0.0);
  localStorage->m_Actor->GetProperty()->SetSpecular(0.0);

  //set the color of the contour
  localStorage->m_Actor->GetProperty()->SetColor(0.9, 1.0, 0.1);
}

/*+++++++++++++++++++ LocalStorage part +++++++++++++++++++++++++*/

mitk::ContourModelMapper2D::LocalStorage* mitk::ContourModelMapper2D::GetLocalStorage(mitk::BaseRenderer* renderer)
{
  return m_LSH.GetLocalStorage(renderer);
}

mitk::ContourModelMapper2D::LocalStorage::LocalStorage()
{
  m_Mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  m_Actor = vtkSmartPointer<vtkActor>::New();
  m_OutlinePolyData = vtkSmartPointer<vtkPolyData>::New();

  //set the mapper for the actor
  m_Actor->SetMapper(m_Mapper);
}

void mitk::ContourModelMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite)
{
  node->AddProperty( "color", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite );
  node->AddProperty( "contour width", mitk::FloatProperty::New( 1.0 ), renderer, overwrite );

  Superclass::SetDefaultProperties(node, renderer, overwrite);
}<commit_msg>create polydata restructured<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/
#include <mitkContourModelMapper2D.h>

#include <vtkPoints.h>
#include <vtkCellArray.h>
#include <vtkAppendPolyData.h>
#include <vtkProperty.h>
#include <vtkPlane.h>
#include <vtkCutter.h>
#include <vtkStripper.h>
#include <vtkTubeFilter.h>
#include <vtkSphereSource.h>

mitk::ContourModelMapper2D::ContourModelMapper2D()
{
}

mitk::ContourModelMapper2D::~ContourModelMapper2D()
{
}

const mitk::ContourModel* mitk::ContourModelMapper2D::GetInput( void )
{
  //convient way to get the data from the dataNode
  return static_cast< const mitk::ContourModel * >( this->GetData() );
}

vtkProp* mitk::ContourModelMapper2D::GetVtkProp(mitk::BaseRenderer* renderer)
{
  //return the actor corresponding to the renderer
  return m_LSH.GetLocalStorage(renderer)->m_Actor;
}

void mitk::ContourModelMapper2D::MitkRenderOverlay(BaseRenderer* renderer)
{
  if ( this->IsVisible(renderer)==false )
    return;
  if ( this->GetVtkProp(renderer)->GetVisibility() )
  {
    this->GetVtkProp(renderer)->RenderOverlay(renderer->GetVtkRenderer());
  }
}

void mitk::ContourModelMapper2D::MitkRenderOpaqueGeometry(BaseRenderer* renderer)
{
  if ( this->IsVisible( renderer )==false )
    return;
  if ( this->GetVtkProp(renderer)->GetVisibility() )
  {
    this->GetVtkProp(renderer)->RenderOpaqueGeometry( renderer->GetVtkRenderer() );
  }
}

void mitk::ContourModelMapper2D::MitkRenderTranslucentGeometry(BaseRenderer* renderer)
{
  if ( this->IsVisible(renderer)==false )
    return;
  if ( this->GetVtkProp(renderer)->GetVisibility() )
  {
    this->GetVtkProp(renderer)->RenderTranslucentPolygonalGeometry(renderer->GetVtkRenderer());
  }
}

void mitk::ContourModelMapper2D::MitkRenderVolumetricGeometry(BaseRenderer* renderer)
{
  if(IsVisible(renderer)==false)
    return;
  if ( GetVtkProp(renderer)->GetVisibility() )
  {
    this->GetVtkProp(renderer)->RenderVolumetricGeometry(renderer->GetVtkRenderer());
  }
}

void mitk::ContourModelMapper2D::GenerateDataForRenderer( mitk::BaseRenderer *renderer )
{
  /*++ convert the contour to vtkPolyData and set it as input for our mapper ++*/

  LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);

  mitk::ContourModel* inputContour  = static_cast< mitk::ContourModel* >( this->GetData() );

  unsigned int timestep = renderer->GetTimeStep();

  //if there's something to be rendered
  if( inputContour->GetNumberOfVertices(timestep) > 0)
  {
    localStorage->m_OutlinePolyData = this->CreateVtkPolyDataFromContour(inputContour, renderer);
  }

  this->ApplyContourProperties(renderer);

  localStorage->m_Mapper->SetInput(localStorage->m_OutlinePolyData);

}

void mitk::ContourModelMapper2D::Update(mitk::BaseRenderer* renderer)
{
  if ( !this->IsVisible( renderer ) )
  {
    return;
  }

  //check if there is something to be rendered
  mitk::ContourModel* data  = static_cast< mitk::ContourModel*>( this->GetData() );
  if ( data == NULL )
  {
    return;
  }

  // Calculate time step of the input data for the specified renderer (integer value)
  this->CalculateTimeStep( renderer );

    LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);

  // Check if time step is valid
  const TimeSlicedGeometry *dataTimeGeometry = data->GetTimeSlicedGeometry();
  if ( ( dataTimeGeometry == NULL )
    || ( dataTimeGeometry->GetTimeSteps() == 0 )
    || ( !dataTimeGeometry->IsValidTime( renderer->GetTimeStep() ) ) )
  {
    //clear the rendered polydata
    localStorage->m_Mapper->RemoveAllInputs();//SetInput(vtkSmartPointer<vtkPolyData>::New());
    return;
  }

  const DataNode *node = this->GetDataNode();
  data->UpdateOutputInformation();

  //check if something important has changed and we need to rerender
  if ( (localStorage->m_LastUpdateTime < node->GetMTime()) //was the node modified?
    || (localStorage->m_LastUpdateTime < data->GetPipelineMTime()) //Was the data modified?
    || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldGeometry2DUpdateTime()) //was the geometry modified?
    || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldGeometry2D()->GetMTime())
    || (localStorage->m_LastUpdateTime < node->GetPropertyList()->GetMTime()) //was a property modified?
    || (localStorage->m_LastUpdateTime < node->GetPropertyList(renderer)->GetMTime()) )
  {
    this->GenerateDataForRenderer( renderer );
  }

  // since we have checked that nothing important has changed, we can set
  // m_LastUpdateTime to the current time
  localStorage->m_LastUpdateTime.Modified();
}

vtkSmartPointer<vtkPolyData> mitk::ContourModelMapper2D::CreateVtkPolyDataFromContour(mitk::ContourModel* inputContour, mitk::BaseRenderer* renderer)
{
  unsigned int timestep = this->GetTimestep();
  // Create a polydata to store everything in
  vtkSmartPointer<vtkPolyData> resultingPolyData = vtkSmartPointer<vtkPolyData>::New();

  /* First of all convert the control points of the contourModel to vtk points
  * and add lines in between them
  */
  //the points to draw
  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
  //the lines to connect the points
  vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
  // Create a polydata to store everything in
  vtkSmartPointer<vtkPolyData> polyDataIn3D = vtkSmartPointer<vtkPolyData>::New();

  vtkSmartPointer<vtkAppendPolyData> appendPoly = vtkSmartPointer<vtkAppendPolyData>::New();

  //iterate over all control points
  mitk::ContourModel::VertexIterator current = inputContour->IteratorBegin(timestep);
  mitk::ContourModel::VertexIterator next = inputContour->IteratorBegin(timestep);
  if(next != inputContour->IteratorEnd(timestep))
  {
    next++;

    mitk::ContourModel::VertexIterator end = inputContour->IteratorEnd(timestep);

    while(next != end)
    {
      mitk::ContourModel::VertexType* currentControlPoint = *current;
      mitk::ContourModel::VertexType* nextControlPoint = *next;

      vtkIdType p1 = points->InsertNextPoint(currentControlPoint->Coordinates[0], currentControlPoint->Coordinates[1], currentControlPoint->Coordinates[2]);
      vtkIdType p2 = points->InsertNextPoint(nextControlPoint->Coordinates[0], nextControlPoint->Coordinates[1], nextControlPoint->Coordinates[2]);
      //add the line between both contorlPoints
      lines->InsertNextCell(2);
      lines->InsertCellPoint(p1);
      lines->InsertCellPoint(p2);

      if ( currentControlPoint->IsActive )
      {
        vtkSmartPointer<vtkSphereSource> sphere = vtkSmartPointer<vtkSphereSource>::New();

        sphere->SetRadius(1.5);
        sphere->SetCenter(currentControlPoint->Coordinates[0], currentControlPoint->Coordinates[1], currentControlPoint->Coordinates[2]);
        sphere->Update();
        appendPoly->AddInput(sphere->GetOutput());
      }

      current++;
      next++;
    }//end while (it!=end)

    //check if last control point is enabled to draw it
    if ( (*current)->IsActive )
    {
      vtkSmartPointer<vtkSphereSource> sphere = vtkSmartPointer<vtkSphereSource>::New();

      sphere->SetRadius(1.5);
      sphere->SetCenter((*current)->Coordinates[0], (*current)->Coordinates[1], (*current)->Coordinates[2]);

      appendPoly->AddInput(sphere->GetOutput());
      sphere->Update();
    }

    /* If the contour is closed an additional line has to be created between the very first point
    * and the last point
    */
    if(inputContour->IsClosed(timestep))
    {
      //add a line from the last to the first control point
      mitk::ContourModel::VertexType* firstControlPoint = *(inputContour->IteratorBegin(timestep));
      mitk::ContourModel::VertexType* lastControlPoint = *(--(inputContour->IteratorEnd(timestep)));
      vtkIdType p2 = points->InsertNextPoint(lastControlPoint->Coordinates[0], lastControlPoint->Coordinates[1], lastControlPoint->Coordinates[2]);
      vtkIdType p1 = points->InsertNextPoint(firstControlPoint->Coordinates[0], firstControlPoint->Coordinates[1], firstControlPoint->Coordinates[2]);

      //add the line between both contorlPoints
      lines->InsertNextCell(2);
      lines->InsertCellPoint(p1);
      lines->InsertCellPoint(p2);
    }//end if(isClosed)

    // Add the points to the dataset
    polyDataIn3D->SetPoints(points);
    // Add the lines to the dataset
    polyDataIn3D->SetLines(lines);

    appendPoly->AddInput(polyDataIn3D);
    appendPoly->Update();

    //check for the worldgeometry from the current render window
    mitk::PlaneGeometry* currentWorldGeometry = dynamic_cast<mitk::PlaneGeometry*>( const_cast<mitk::Geometry2D*>(renderer->GetCurrentWorldGeometry2D()));
    if (currentWorldGeometry)
    {
      //slice through the data to get a 2D representation of the (possible) 3D contour

      //needed because currently there is no outher solution if the contour is within the plane
      vtkSmartPointer<vtkTubeFilter> tubeFilter = vtkSmartPointer<vtkTubeFilter>::New();
      tubeFilter->SetInput(appendPoly->GetOutput());
      tubeFilter->SetRadius(0.05);

      //origin and normal of vtkPlane
      mitk::Point3D origin = currentWorldGeometry->GetOrigin();
      mitk::Vector3D normal = currentWorldGeometry->GetNormal();

      //the implicit function to slice through the polyData
      vtkSmartPointer<vtkPlane> plane = vtkSmartPointer<vtkPlane>::New();
      plane->SetOrigin(origin[0], origin[1], origin[2]);
      plane->SetNormal(normal[0], normal[1], normal[2]);

      //cuts through vtkPolyData with a given implicit function. In our case a plane
      vtkSmartPointer<vtkCutter> cutter = vtkSmartPointer<vtkCutter>::New();

      cutter->SetCutFunction(plane);

      cutter->SetInputConnection(tubeFilter->GetOutputPort());

      //we want the scalars of the input - so turn off generating the scalars within vtkCutter
      cutter->GenerateCutScalarsOff();
      cutter->Update();

      //set to 2D representation of the contour
      resultingPolyData= cutter->GetOutput();

    }//end if(worldGeometry)
    else
    {
      //set to 3D polyData
      resultingPolyData = polyDataIn3D;
    }

  }//end if (it != end)

  return resultingPolyData;
}

void mitk::ContourModelMapper2D::ApplyContourProperties(mitk::BaseRenderer* renderer)
{
  LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer);

  float binaryOutlineWidth(1.0);
  if (this->GetDataNode()->GetFloatProperty( "contour width", binaryOutlineWidth, renderer ))
  {
    localStorage->m_Actor->GetProperty()->SetLineWidth(binaryOutlineWidth);
  }

  //make sure that directional lighting isn't used for our contour
  localStorage->m_Actor->GetProperty()->SetAmbient(1.0);
  localStorage->m_Actor->GetProperty()->SetDiffuse(0.0);
  localStorage->m_Actor->GetProperty()->SetSpecular(0.0);

  //set the color of the contour
  localStorage->m_Actor->GetProperty()->SetColor(0.9, 1.0, 0.1);
}

/*+++++++++++++++++++ LocalStorage part +++++++++++++++++++++++++*/

mitk::ContourModelMapper2D::LocalStorage* mitk::ContourModelMapper2D::GetLocalStorage(mitk::BaseRenderer* renderer)
{
  return m_LSH.GetLocalStorage(renderer);
}

mitk::ContourModelMapper2D::LocalStorage::LocalStorage()
{
  m_Mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  m_Actor = vtkSmartPointer<vtkActor>::New();
  m_OutlinePolyData = vtkSmartPointer<vtkPolyData>::New();

  //set the mapper for the actor
  m_Actor->SetMapper(m_Mapper);
}

void mitk::ContourModelMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite)
{
  node->AddProperty( "color", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite );
  node->AddProperty( "contour width", mitk::FloatProperty::New( 1.0 ), renderer, overwrite );

  Superclass::SetDefaultProperties(node, renderer, overwrite);
}<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.

Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.

============================================================================*/

#include "QmitkNewSegmentationDialog.h"

#include <itkRGBPixel.h>

#include <QAbstractItemModel>
#include <QColorDialog>
#include <QStringListModel>
#include <qlabel.h>
#include <qlayout.h>
#include <qlineedit.h>
#include <qpushbutton.h>

QmitkNewSegmentationDialog::QmitkNewSegmentationDialog(QWidget *parent)
  : QDialog(parent) // true, modal
  , selectedOrgan(tr("undefined"))
  , newOrganEntry(false)
{
  QDialog::setFixedSize(250, 105);

  QBoxLayout *verticalLayout = new QVBoxLayout(this);
  verticalLayout->setMargin(5);
  verticalLayout->setSpacing(5);

  // to enter a name for the segmentation
  lblPrompt = new QLabel(tr("Name and color of the segmentation"), this);
  verticalLayout->addWidget(lblPrompt);

  // to choose a color
  btnColor = new QPushButton("", this);
  btnColor->setFixedWidth(25);
  btnColor->setAutoFillBackground(true);
  btnColor->setStyleSheet("background-color:rgb(255,0,0)");

  connect(btnColor, SIGNAL(clicked()), this, SLOT(onColorBtnClicked()));

  lineEditName = new QLineEdit("", this);
  QStringList completionList;
  completionList << "";
  completer = new QCompleter(completionList);
  completer->setCaseSensitivity(Qt::CaseInsensitive);
  lineEditName->setCompleter(completer);

  connect(completer, SIGNAL(activated(const QString &)), this, SLOT(onColorChange(const QString &)));

  QBoxLayout *horizontalLayout2 = new QHBoxLayout();
  verticalLayout->addLayout(horizontalLayout2);
  horizontalLayout2->addWidget(btnColor);
  horizontalLayout2->addWidget(lineEditName);

  // buttons for closing the dialog
  btnOk = new QPushButton(tr("Ok"), this);
  btnOk->setDefault(true);
  connect(btnOk, SIGNAL(clicked()), this, SLOT(onAcceptClicked()));

  QPushButton *btnCancel = new QPushButton(tr("Cancel"), this);
  connect(btnCancel, SIGNAL(clicked()), this, SLOT(reject()));

  QBoxLayout *horizontalLayout = new QHBoxLayout();
  verticalLayout->addLayout(horizontalLayout);
  horizontalLayout->setSpacing(5);
  horizontalLayout->addStretch();
  horizontalLayout->addWidget(btnOk);
  horizontalLayout->addWidget(btnCancel);

  lineEditName->setFocus();
}

QmitkNewSegmentationDialog::~QmitkNewSegmentationDialog()
{
}

const QString QmitkNewSegmentationDialog::GetSegmentationName()
{
  return m_SegmentationName;
}

mitk::Color QmitkNewSegmentationDialog::GetColor()
{
  mitk::Color colorProperty;
  if (m_Color.spec() == 0)
  {
    colorProperty.SetRed(1);
    colorProperty.SetGreen(0);
    colorProperty.SetBlue(0);
  }
  else
  {
    colorProperty.SetRed(m_Color.redF());
    colorProperty.SetGreen(m_Color.greenF());
    colorProperty.SetBlue(m_Color.blueF());
  }
  return colorProperty;
}

const char *QmitkNewSegmentationDialog::GetOrganType()
{
  return selectedOrgan.toLocal8Bit().constData();
}

void QmitkNewSegmentationDialog::SetSegmentationName(const QString &segmentationName)
{
  lineEditName->setText(segmentationName);
}

void QmitkNewSegmentationDialog::SetColor(const mitk::Color &color)
{
  m_Color.setRedF(color.GetRed());
  m_Color.setGreenF(color.GetGreen());
  m_Color.setBlueF(color.GetBlue());

  btnColor->setStyleSheet(QString("background-color:rgb(%1, %2, %3)").arg(m_Color.red()).arg(m_Color.green()).arg(m_Color.blue()));
}

void QmitkNewSegmentationDialog::SetSuggestionList(QStringList organColorList)
{
  QStringList::iterator iter;
  for (iter = organColorList.begin(); iter != organColorList.end(); ++iter)
  {
    QString &element = *iter;
    QString colorName = element.right(7);
    QColor color(colorName);
    QString organName = element.left(element.size() - 7);

    organList.push_back(organName);
    colorList.push_back(color);
  }

  QStringListModel *completeModel = static_cast<QStringListModel *>(completer->model());
  completeModel->setStringList(organList);
}

void QmitkNewSegmentationDialog::setPrompt(const QString &prompt)
{
  lblPrompt->setText(prompt);
}

void QmitkNewSegmentationDialog::onAcceptClicked()
{
  m_SegmentationName = lineEditName->text();
  accept();
}

void QmitkNewSegmentationDialog::onNewOrganNameChanged(const QString &newText)
{
  if (!newText.isEmpty())
  {
    btnOk->setEnabled(true);
  }

  selectedOrgan = newText;
  SetSegmentationName(newText);
}

void QmitkNewSegmentationDialog::onColorBtnClicked()
{
  m_Color = QColorDialog::getColor();
  if (m_Color.spec() == 0)
  {
    m_Color.setRed(255);
    m_Color.setGreen(0);
    m_Color.setBlue(0);
  }
  btnColor->setStyleSheet(QString("background-color:rgb(%1, %2, %3)").arg(m_Color.red()).arg(m_Color.green()).arg(m_Color.blue()));
}

void QmitkNewSegmentationDialog::onColorChange(const QString &completedWord)
{
  if (organList.contains(completedWord))
  {
    int j = organList.indexOf(completedWord);
    m_Color = colorList.at(j);
    btnColor->setStyleSheet(QString("background-color:rgb(%1, %2, %3)").arg(m_Color.red()).arg(m_Color.green()).arg(m_Color.blue()));
  }
}
<commit_msg>Preserve color selection<commit_after>/*============================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center (DKFZ)
All rights reserved.

Use of this source code is governed by a 3-clause BSD license that can be
found in the LICENSE file.

============================================================================*/

#include "QmitkNewSegmentationDialog.h"

#include <itkRGBPixel.h>

#include <QAbstractItemModel>
#include <QColorDialog>
#include <QStringListModel>
#include <qlabel.h>
#include <qlayout.h>
#include <qlineedit.h>
#include <qpushbutton.h>

QmitkNewSegmentationDialog::QmitkNewSegmentationDialog(QWidget *parent)
  : QDialog(parent) // true, modal
  , selectedOrgan(tr("undefined"))
  , newOrganEntry(false)
{
  QDialog::setFixedSize(250, 105);

  QBoxLayout *verticalLayout = new QVBoxLayout(this);
  verticalLayout->setMargin(5);
  verticalLayout->setSpacing(5);

  // to enter a name for the segmentation
  lblPrompt = new QLabel(tr("Name and color of the segmentation"), this);
  verticalLayout->addWidget(lblPrompt);

  // to choose a color
  m_Color.setRed(255);
  m_Color.setGreen(0);
  m_Color.setBlue(0);

  btnColor = new QPushButton("", this);
  btnColor->setFixedWidth(25);
  btnColor->setAutoFillBackground(true);
  btnColor->setStyleSheet(QString("background-color:rgb(%1, %2, %3)").arg(m_Color.red()).arg(m_Color.green()).arg(m_Color.blue()));

  connect(btnColor, SIGNAL(clicked()), this, SLOT(onColorBtnClicked()));

  lineEditName = new QLineEdit("", this);
  QStringList completionList;
  completionList << "";
  completer = new QCompleter(completionList);
  completer->setCaseSensitivity(Qt::CaseInsensitive);
  lineEditName->setCompleter(completer);

  connect(completer, SIGNAL(activated(const QString &)), this, SLOT(onColorChange(const QString &)));

  QBoxLayout *horizontalLayout2 = new QHBoxLayout();
  verticalLayout->addLayout(horizontalLayout2);
  horizontalLayout2->addWidget(btnColor);
  horizontalLayout2->addWidget(lineEditName);

  // buttons for closing the dialog
  btnOk = new QPushButton(tr("Ok"), this);
  btnOk->setDefault(true);
  connect(btnOk, SIGNAL(clicked()), this, SLOT(onAcceptClicked()));

  QPushButton *btnCancel = new QPushButton(tr("Cancel"), this);
  connect(btnCancel, SIGNAL(clicked()), this, SLOT(reject()));

  QBoxLayout *horizontalLayout = new QHBoxLayout();
  verticalLayout->addLayout(horizontalLayout);
  horizontalLayout->setSpacing(5);
  horizontalLayout->addStretch();
  horizontalLayout->addWidget(btnOk);
  horizontalLayout->addWidget(btnCancel);

  lineEditName->setFocus();
}

QmitkNewSegmentationDialog::~QmitkNewSegmentationDialog()
{
}

const QString QmitkNewSegmentationDialog::GetSegmentationName()
{
  return m_SegmentationName;
}

mitk::Color QmitkNewSegmentationDialog::GetColor()
{
  mitk::Color colorProperty;
  if (m_Color.isValid())
  {
    colorProperty.SetRed(m_Color.redF());
    colorProperty.SetGreen(m_Color.greenF());
    colorProperty.SetBlue(m_Color.blueF());
  }
  else
  {
    colorProperty.SetRed(1);
    colorProperty.SetGreen(0);
    colorProperty.SetBlue(0);
  }
  return colorProperty;
}

const char *QmitkNewSegmentationDialog::GetOrganType()
{
  return selectedOrgan.toLocal8Bit().constData();
}

void QmitkNewSegmentationDialog::SetSegmentationName(const QString &segmentationName)
{
  lineEditName->setText(segmentationName);
}

void QmitkNewSegmentationDialog::SetColor(const mitk::Color &color)
{
  m_Color.setRedF(color.GetRed());
  m_Color.setGreenF(color.GetGreen());
  m_Color.setBlueF(color.GetBlue());

  btnColor->setStyleSheet(QString("background-color:rgb(%1, %2, %3)").arg(m_Color.red()).arg(m_Color.green()).arg(m_Color.blue()));
}

void QmitkNewSegmentationDialog::SetSuggestionList(QStringList organColorList)
{
  QStringList::iterator iter;
  for (iter = organColorList.begin(); iter != organColorList.end(); ++iter)
  {
    QString &element = *iter;
    QString colorName = element.right(7);
    QColor color(colorName);
    QString organName = element.left(element.size() - 7);

    organList.push_back(organName);
    colorList.push_back(color);
  }

  QStringListModel *completeModel = static_cast<QStringListModel *>(completer->model());
  completeModel->setStringList(organList);
}

void QmitkNewSegmentationDialog::setPrompt(const QString &prompt)
{
  lblPrompt->setText(prompt);
}

void QmitkNewSegmentationDialog::onAcceptClicked()
{
  m_SegmentationName = lineEditName->text();
  accept();
}

void QmitkNewSegmentationDialog::onNewOrganNameChanged(const QString &newText)
{
  if (!newText.isEmpty())
  {
    btnOk->setEnabled(true);
  }

  selectedOrgan = newText;
  SetSegmentationName(newText);
}

void QmitkNewSegmentationDialog::onColorBtnClicked()
{
  auto selectedColor = QColorDialog::getColor(m_Color);
  if (selectedColor.isValid())
  {
    m_Color = selectedColor;
    btnColor->setStyleSheet(QString("background-color:rgb(%1, %2, %3)").arg(m_Color.red()).arg(m_Color.green()).arg(m_Color.blue()));
  }
}

void QmitkNewSegmentationDialog::onColorChange(const QString &completedWord)
{
  if (organList.contains(completedWord))
  {
    int j = organList.indexOf(completedWord);
    m_Color = colorList.at(j);
    btnColor->setStyleSheet(QString("background-color:rgb(%1, %2, %3)").arg(m_Color.red()).arg(m_Color.green()).arg(m_Color.blue()));
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * Licensed 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 <folly/FileUtil.h>
#include <folly/experimental/TestUtil.h>
#include <folly/experimental/symbolizer/Elf.h>
#include <folly/portability/GTest.h>

using folly::symbolizer::ElfFile;

// Add some symbols for testing. Note that we have to be careful with type
// signatures here to prevent name mangling
uint64_t kIntegerValue = 1234567890UL;
const char* kStringValue = "coconuts";
const char* const kDefaultElf = "/proc/self/exe";
class ElfTest : public ::testing::Test {
 protected:
  ElfFile elfFile_{kDefaultElf};
};

TEST_F(ElfTest, IntegerValue) {
  auto sym = elfFile_.getSymbolByName("kIntegerValue");
  EXPECT_NE(nullptr, sym.first) << "Failed to look up symbol kIntegerValue";
  EXPECT_EQ(kIntegerValue, elfFile_.getSymbolValue<uint64_t>(sym.second));
}

TEST_F(ElfTest, PointerValue) {
  auto sym = elfFile_.getSymbolByName("kStringValue");
  EXPECT_NE(nullptr, sym.first) << "Failed to look up symbol kStringValue";
  ElfW(Addr) addr = elfFile_.getSymbolValue<ElfW(Addr)>(sym.second);
  const char* str = &elfFile_.getAddressValue<const char>(addr);
  EXPECT_STREQ(kStringValue, str);
}

TEST_F(ElfTest, iterateProgramHeaders) {
  auto phdr = elfFile_.iterateProgramHeaders(
      [](auto& h) { return h.p_type == PT_LOAD; });
  EXPECT_NE(nullptr, phdr);
  EXPECT_GE(phdr->p_filesz, 0);
}

TEST_F(ElfTest, TinyNonElfFile) {
  folly::test::TemporaryFile tmpFile;
  const static folly::StringPiece contents = "!";
  folly::writeFull(tmpFile.fd(), contents.data(), contents.size());

  ElfFile elfFile;
  auto res = elfFile.openNoThrow(tmpFile.path().c_str());
  EXPECT_EQ(ElfFile::kInvalidElfFile, res.code);
  EXPECT_STREQ("not an ELF file (too short)", res.msg);
}

TEST_F(ElfTest, NonElfScript) {
  folly::test::TemporaryFile tmpFile;
  const static folly::StringPiece contents =
      "#!/bin/sh\necho I'm small non-ELF executable\n";
  folly::writeFull(tmpFile.fd(), contents.data(), contents.size());

  ElfFile elfFile;
  auto res = elfFile.openNoThrow(tmpFile.path().c_str());
  EXPECT_EQ(ElfFile::kInvalidElfFile, res.code);
  EXPECT_STREQ("invalid ELF magic", res.msg);
}

TEST_F(ElfTest, FailToOpenLargeFilename) {
  // ElfFile used to segfault if it failed to open large filenames
  folly::test::TemporaryDirectory tmpDir;
  auto elfFile = std::make_unique<ElfFile>(); // on the heap so asan can see it
  auto const largeNonExistingName = (tmpDir.path() / std::string(1000, 'x'));
  ASSERT_EQ(
      ElfFile::kSystemError,
      elfFile->openNoThrow(largeNonExistingName.c_str()));
  ASSERT_EQ(
      ElfFile::kSystemError,
      elfFile->openNoThrow(largeNonExistingName.c_str()));
  EXPECT_EQ(ElfFile::kSuccess, elfFile->openNoThrow(kDefaultElf));
}
<commit_msg>Make folly/experimental/symbolizer/test:elf_tests work if compiled as PIE.<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * Licensed 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 <folly/FileUtil.h>
#include <folly/experimental/TestUtil.h>
#include <folly/experimental/symbolizer/Elf.h>
#include <folly/portability/GTest.h>
#include <sys/auxv.h>

using folly::symbolizer::ElfFile;

// Add some symbols for testing. Note that we have to be careful with type
// signatures here to prevent name mangling
uint64_t kIntegerValue = 1234567890UL;
const char* kStringValue = "coconuts";
const char* const kDefaultElf = "/proc/self/exe";
class ElfTest : public ::testing::Test {
 protected:
  ElfFile elfFile_{kDefaultElf};
};

TEST_F(ElfTest, IntegerValue) {
  auto sym = elfFile_.getSymbolByName("kIntegerValue");
  EXPECT_NE(nullptr, sym.first) << "Failed to look up symbol kIntegerValue";
  EXPECT_EQ(kIntegerValue, elfFile_.getSymbolValue<uint64_t>(sym.second));
}

TEST_F(ElfTest, PointerValue) {
  auto sym = elfFile_.getSymbolByName("kStringValue");
  EXPECT_NE(nullptr, sym.first) << "Failed to look up symbol kStringValue";
  ElfW(Addr) addr = elfFile_.getSymbolValue<ElfW(Addr)>(sym.second);
  // Let's check the address for the symbol against our own copy of
  // kStringValue.
  auto binaryBase = getauxval(AT_PHDR) - 0x40; // address of our own image
  EXPECT_EQ(
      static_cast<const void*>(&kStringValue),
      reinterpret_cast<const void*>(
          binaryBase +
          (sym.second->st_value - sym.first->sh_addr + sym.first->sh_offset)));
  if (addr != 0) {
    // Only do this check if we have a non-PIE. For the PIE case, the compiler
    // could put a 0 in the .data section for kStringValue, and then rely on
    // the dynamic linker to fill in the actual pointer to the .rodata section
    // via relocation; the actual offset of the string is encoded in the
    // .rela.dyn section, which isn't parsed in the current implementation of
    // ElfFile.
    const char* str = &elfFile_.getAddressValue<const char>(addr);
    EXPECT_STREQ(kStringValue, str);
  }
}

TEST_F(ElfTest, iterateProgramHeaders) {
  auto phdr = elfFile_.iterateProgramHeaders(
      [](auto& h) { return h.p_type == PT_LOAD; });
  EXPECT_NE(nullptr, phdr);
  EXPECT_GE(phdr->p_filesz, 0);
}

TEST_F(ElfTest, TinyNonElfFile) {
  folly::test::TemporaryFile tmpFile;
  const static folly::StringPiece contents = "!";
  folly::writeFull(tmpFile.fd(), contents.data(), contents.size());

  ElfFile elfFile;
  auto res = elfFile.openNoThrow(tmpFile.path().c_str());
  EXPECT_EQ(ElfFile::kInvalidElfFile, res.code);
  EXPECT_STREQ("not an ELF file (too short)", res.msg);
}

TEST_F(ElfTest, NonElfScript) {
  folly::test::TemporaryFile tmpFile;
  const static folly::StringPiece contents =
      "#!/bin/sh\necho I'm small non-ELF executable\n";
  folly::writeFull(tmpFile.fd(), contents.data(), contents.size());

  ElfFile elfFile;
  auto res = elfFile.openNoThrow(tmpFile.path().c_str());
  EXPECT_EQ(ElfFile::kInvalidElfFile, res.code);
  EXPECT_STREQ("invalid ELF magic", res.msg);
}

TEST_F(ElfTest, FailToOpenLargeFilename) {
  // ElfFile used to segfault if it failed to open large filenames
  folly::test::TemporaryDirectory tmpDir;
  auto elfFile = std::make_unique<ElfFile>(); // on the heap so asan can see it
  auto const largeNonExistingName = (tmpDir.path() / std::string(1000, 'x'));
  ASSERT_EQ(
      ElfFile::kSystemError,
      elfFile->openNoThrow(largeNonExistingName.c_str()));
  ASSERT_EQ(
      ElfFile::kSystemError,
      elfFile->openNoThrow(largeNonExistingName.c_str()));
  EXPECT_EQ(ElfFile::kSuccess, elfFile->openNoThrow(kDefaultElf));
}
<|endoftext|>


<commit_before>using namespace GeFiCa;
// calculate and save fields of a square point-pontact (SPC) HPGe
void calculateFields(const char *output="SPC.root")
{
   SquarePointContact detector;
   detector.Bias[0]=-70*volt; // bias on point contact
   detector.Bias[1]=0; // ground outer contact

   detector.Height=1.0*cm;
   detector.Width=detector.Length=1.8*cm;
   detector.WrapAroundW=detector.WrapAroundL=detector.Length;

   detector.PointContactW=0.6*mm;
   detector.PointContactL=0.6*mm;
   detector.PointContactH=0.1*mm;

   detector.BottomImpurity=4e9/cm3; detector.TopImpurity=4e9/cm3;

   int nx=50;
   int ny=50; // precision: 0.1 mm
   int nz=100; // precision: 0.1 mm
   XYZ grid(nx,ny,nz);
   grid.SetupWith(detector);
   grid.RelaxationFactor=1.94;
   grid.SuccessiveOverRelax();

   TFile file(output,"recreate");
   detector.Write();
   grid.Write();
   file.Close();
}
<commit_msg>updated grid size<commit_after>using namespace GeFiCa;
// calculate and save fields of a square point-pontact (SPC) HPGe
void calculateFields(const char *output="SPC.root")
{
   SquarePointContact detector;
   detector.Bias[0]=-70*volt; // bias on point contact
   detector.Bias[1]=0; // ground outer contact

   detector.Height=1.0*cm;
   detector.Width=detector.Length=1.8*cm;
   detector.WrapAroundW=detector.WrapAroundL=detector.Length;

   detector.PointContactW=0.6*mm;
   detector.PointContactL=0.6*mm;
   detector.PointContactH=0.1*mm;

   detector.BottomImpurity=4e9/cm3; detector.TopImpurity=4e9/cm3;

   XYZ grid(61,61,51);
   grid.SetupWith(detector);
   grid.RelaxationFactor=1.94;
   grid.SuccessiveOverRelax();

   TFile file(output,"recreate");
   detector.Write();
   grid.Write();
   file.Close();
}
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include <dispatch/dispatch.h>
#include <stdio.h>

#define DISPATCH_RUNTIME_STDLIB_INTERFACE __attribute__((__visibility__("default")))

#if USE_OBJC
@protocol OS_dispatch_source;
@protocol OS_dispatch_source_mach_send;
@protocol OS_dispatch_source_mach_recv;
@protocol OS_dispatch_source_memorypressure;
@protocol OS_dispatch_source_proc;
@protocol OS_dispatch_source_read;
@protocol OS_dispatch_source_signal;
@protocol OS_dispatch_source_timer;
@protocol OS_dispatch_source_data_add;
@protocol OS_dispatch_source_data_or;
@protocol OS_dispatch_source_data_replace;
@protocol OS_dispatch_source_vnode;
@protocol OS_dispatch_source_write;

// #include <dispatch/private.h>
__attribute__((constructor))
static void _dispatch_overlay_constructor() {
  Class source = objc_lookUpClass("OS_dispatch_source");
  if (source) {
    class_addProtocol(source, @protocol(OS_dispatch_source));
    class_addProtocol(source, @protocol(OS_dispatch_source_mach_send));
    class_addProtocol(source, @protocol(OS_dispatch_source_mach_recv));
    class_addProtocol(source, @protocol(OS_dispatch_source_memorypressure));
    class_addProtocol(source, @protocol(OS_dispatch_source_proc));
    class_addProtocol(source, @protocol(OS_dispatch_source_read));
    class_addProtocol(source, @protocol(OS_dispatch_source_signal));
    class_addProtocol(source, @protocol(OS_dispatch_source_timer));
    class_addProtocol(source, @protocol(OS_dispatch_source_data_add));
    class_addProtocol(source, @protocol(OS_dispatch_source_data_or));
    class_addProtocol(source, @protocol(OS_dispatch_source_data_replace));
    class_addProtocol(source, @protocol(OS_dispatch_source_vnode));
    class_addProtocol(source, @protocol(OS_dispatch_source_write));
  }
}

#endif /* USE_OBJC */

// Replicate the SWIFT_CC(swift) calling convention macro from
// swift/include/swift/Runtime/Config.h because it is
// quite awkward to include Config.h and its recursive includes
// in dispatch. This define must be manually kept in synch
#define SWIFT_CC(CC) SWIFT_CC_##CC
#if SWIFT_USE_SWIFTCALL
#define SWIFT_CC_swift __attribute__((swiftcall))
#else
#define SWIFT_CC_swift
#endif

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" dispatch_queue_attr_t
_swift_dispatch_queue_concurrent(void) {
  return DISPATCH_QUEUE_CONCURRENT;
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" void
_swift_dispatch_apply_current(size_t iterations, __attribute__((__noescape__)) void (^block)(size_t)) {
  dispatch_apply(iterations, (dispatch_queue_t _Nonnull)0, block);
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" dispatch_queue_t
_swift_dispatch_get_main_queue(void) {
  return dispatch_get_main_queue();
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" dispatch_data_t
_swift_dispatch_data_empty(void) {
  return dispatch_data_empty;
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" dispatch_block_t
_swift_dispatch_data_destructor_default(void) {
  return DISPATCH_DATA_DESTRUCTOR_DEFAULT;
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" dispatch_block_t
_swift_dispatch_data_destructor_free(void) {
  return _dispatch_data_destructor_free;
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" dispatch_block_t
_swift_dispatch_data_destructor_munmap(void) {
  return _dispatch_data_destructor_munmap;
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" dispatch_block_t
_swift_dispatch_block_create_with_qos_class(dispatch_block_flags_t flags, dispatch_qos_class_t qos, int relative_priority, dispatch_block_t block) {
  return dispatch_block_create_with_qos_class(flags, qos, relative_priority, block);
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" dispatch_block_t
_swift_dispatch_block_create_noescape(dispatch_block_flags_t flags, dispatch_block_t block) {
  return dispatch_block_create(flags, block);
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" void
_swift_dispatch_block_cancel(dispatch_block_t block) {
  dispatch_block_cancel(block);
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" long
_swift_dispatch_block_wait(dispatch_block_t block, dispatch_time_t timeout) {
  return dispatch_block_wait(block, timeout);
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" void
_swift_dispatch_block_notify(dispatch_block_t block, dispatch_queue_t queue, dispatch_block_t notification_block) {
  dispatch_block_notify(block, queue, notification_block);
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" long
_swift_dispatch_block_testcancel(dispatch_block_t block) {
  return dispatch_block_testcancel(block);
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" void
_swift_dispatch_async(dispatch_queue_t queue, dispatch_block_t block) {
  dispatch_async(queue, block);
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" void
_swift_dispatch_group_async(dispatch_group_t group, dispatch_queue_t queue, dispatch_block_t block) {
  dispatch_group_async(group, queue, block);
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" void
_swift_dispatch_sync(dispatch_queue_t queue, dispatch_block_t block) {
  dispatch_sync(queue, block);
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" void
_swift_dispatch_release(dispatch_object_t obj) {
  dispatch_release(obj);
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" void
_swift_dispatch_retain(dispatch_object_t obj) {
  dispatch_retain(obj);
}

#define SOURCE(t)                                                              \
  SWIFT_CC(swift)                                                              \
  DISPATCH_RUNTIME_STDLIB_INTERFACE extern "C" dispatch_source_type_t  \
  _swift_dispatch_source_type_##t(void) {                                      \
    return DISPATCH_SOURCE_TYPE_##t;                                           \
  }

SOURCE(DATA_ADD)
SOURCE(DATA_OR)
SOURCE(DATA_REPLACE)
#if HAVE_MACH
SOURCE(MACH_SEND)
SOURCE(MACH_RECV)
SOURCE(MEMORYPRESSURE)
#endif
#ifndef __linux__
SOURCE(PROC)
#endif
SOURCE(READ)
SOURCE(SIGNAL)
SOURCE(TIMER)
#ifndef __linux__
SOURCE(VNODE)
#endif
SOURCE(WRITE)

// See comment in CFFuntime.c explaining why objc_retainAutoreleasedReturnValue is needed.
extern "C" void swift_retain(void *);
extern "C" void * objc_retainAutoreleasedReturnValue(void *obj) {
    if (obj) {
        swift_retain(obj);
        return obj;
    }
    else return NULL;
}
<commit_msg>pr_objc: Expose objc_retainAutoreleasedReturnValue()<commit_after>//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include <dispatch/dispatch.h>
#include <stdio.h>

#define DISPATCH_RUNTIME_STDLIB_INTERFACE __attribute__((__visibility__("default")))

#if USE_OBJC
@protocol OS_dispatch_source;
@protocol OS_dispatch_source_mach_send;
@protocol OS_dispatch_source_mach_recv;
@protocol OS_dispatch_source_memorypressure;
@protocol OS_dispatch_source_proc;
@protocol OS_dispatch_source_read;
@protocol OS_dispatch_source_signal;
@protocol OS_dispatch_source_timer;
@protocol OS_dispatch_source_data_add;
@protocol OS_dispatch_source_data_or;
@protocol OS_dispatch_source_data_replace;
@protocol OS_dispatch_source_vnode;
@protocol OS_dispatch_source_write;

// #include <dispatch/private.h>
__attribute__((constructor))
static void _dispatch_overlay_constructor() {
  Class source = objc_lookUpClass("OS_dispatch_source");
  if (source) {
    class_addProtocol(source, @protocol(OS_dispatch_source));
    class_addProtocol(source, @protocol(OS_dispatch_source_mach_send));
    class_addProtocol(source, @protocol(OS_dispatch_source_mach_recv));
    class_addProtocol(source, @protocol(OS_dispatch_source_memorypressure));
    class_addProtocol(source, @protocol(OS_dispatch_source_proc));
    class_addProtocol(source, @protocol(OS_dispatch_source_read));
    class_addProtocol(source, @protocol(OS_dispatch_source_signal));
    class_addProtocol(source, @protocol(OS_dispatch_source_timer));
    class_addProtocol(source, @protocol(OS_dispatch_source_data_add));
    class_addProtocol(source, @protocol(OS_dispatch_source_data_or));
    class_addProtocol(source, @protocol(OS_dispatch_source_data_replace));
    class_addProtocol(source, @protocol(OS_dispatch_source_vnode));
    class_addProtocol(source, @protocol(OS_dispatch_source_write));
  }
}

#endif /* USE_OBJC */

// Replicate the SWIFT_CC(swift) calling convention macro from
// swift/include/swift/Runtime/Config.h because it is
// quite awkward to include Config.h and its recursive includes
// in dispatch. This define must be manually kept in synch
#define SWIFT_CC(CC) SWIFT_CC_##CC
#if SWIFT_USE_SWIFTCALL
#define SWIFT_CC_swift __attribute__((swiftcall))
#else
#define SWIFT_CC_swift
#endif

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" dispatch_queue_attr_t
_swift_dispatch_queue_concurrent(void) {
  return DISPATCH_QUEUE_CONCURRENT;
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" void
_swift_dispatch_apply_current(size_t iterations, __attribute__((__noescape__)) void (^block)(size_t)) {
  dispatch_apply(iterations, (dispatch_queue_t _Nonnull)0, block);
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" dispatch_queue_t
_swift_dispatch_get_main_queue(void) {
  return dispatch_get_main_queue();
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" dispatch_data_t
_swift_dispatch_data_empty(void) {
  return dispatch_data_empty;
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" dispatch_block_t
_swift_dispatch_data_destructor_default(void) {
  return DISPATCH_DATA_DESTRUCTOR_DEFAULT;
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" dispatch_block_t
_swift_dispatch_data_destructor_free(void) {
  return _dispatch_data_destructor_free;
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" dispatch_block_t
_swift_dispatch_data_destructor_munmap(void) {
  return _dispatch_data_destructor_munmap;
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" dispatch_block_t
_swift_dispatch_block_create_with_qos_class(dispatch_block_flags_t flags, dispatch_qos_class_t qos, int relative_priority, dispatch_block_t block) {
  return dispatch_block_create_with_qos_class(flags, qos, relative_priority, block);
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" dispatch_block_t
_swift_dispatch_block_create_noescape(dispatch_block_flags_t flags, dispatch_block_t block) {
  return dispatch_block_create(flags, block);
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" void
_swift_dispatch_block_cancel(dispatch_block_t block) {
  dispatch_block_cancel(block);
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" long
_swift_dispatch_block_wait(dispatch_block_t block, dispatch_time_t timeout) {
  return dispatch_block_wait(block, timeout);
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" void
_swift_dispatch_block_notify(dispatch_block_t block, dispatch_queue_t queue, dispatch_block_t notification_block) {
  dispatch_block_notify(block, queue, notification_block);
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" long
_swift_dispatch_block_testcancel(dispatch_block_t block) {
  return dispatch_block_testcancel(block);
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" void
_swift_dispatch_async(dispatch_queue_t queue, dispatch_block_t block) {
  dispatch_async(queue, block);
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" void
_swift_dispatch_group_async(dispatch_group_t group, dispatch_queue_t queue, dispatch_block_t block) {
  dispatch_group_async(group, queue, block);
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" void
_swift_dispatch_sync(dispatch_queue_t queue, dispatch_block_t block) {
  dispatch_sync(queue, block);
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" void
_swift_dispatch_release(dispatch_object_t obj) {
  dispatch_release(obj);
}

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" void
_swift_dispatch_retain(dispatch_object_t obj) {
  dispatch_retain(obj);
}

#define SOURCE(t)                                                              \
  SWIFT_CC(swift)                                                              \
  DISPATCH_RUNTIME_STDLIB_INTERFACE extern "C" dispatch_source_type_t  \
  _swift_dispatch_source_type_##t(void) {                                      \
    return DISPATCH_SOURCE_TYPE_##t;                                           \
  }

SOURCE(DATA_ADD)
SOURCE(DATA_OR)
SOURCE(DATA_REPLACE)
#if HAVE_MACH
SOURCE(MACH_SEND)
SOURCE(MACH_RECV)
SOURCE(MEMORYPRESSURE)
#endif
#ifndef __linux__
SOURCE(PROC)
#endif
SOURCE(READ)
SOURCE(SIGNAL)
SOURCE(TIMER)
#ifndef __linux__
SOURCE(VNODE)
#endif
SOURCE(WRITE)

#if !USE_OBJC

// For CF functions with 'Get' semantics, the compiler currently assumes that
// the result is autoreleased and must be retained. It does so on all platforms
// by emitting a call to objc_retainAutoreleasedReturnValue. On Darwin, this is
// implemented by the ObjC runtime. On non-ObjC platforms, there is no runtime,
// and therefore we have to stub it out here ourselves. The compiler will
// eventually call swift_release to balance the retain below. This is a
// workaround until the compiler no longer emits this callout on non-ObjC
// platforms.
extern "C" void swift_retain(void *);

SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
extern "C" void * objc_retainAutoreleasedReturnValue(void *obj) {
    if (obj) {
        swift_retain(obj);
        return obj;
    }
    else return NULL;
}

#endif // !USE_OBJC
<|endoftext|>