<commit_before>#ifndef AFFINE_INVARIANT_FEATURES_RESULT_MATCHER
#define AFFINE_INVARIANT_FEATURES_RESULT_MATCHER

#include <vector>

#include <affine_invariant_features/parallel_tasks.hpp>
#include <affine_invariant_features/results.hpp>

#include <boost/bind.hpp>
#include <boost/ref.hpp>

#include <opencv2/calib3d.hpp>
#include <opencv2/core.hpp>
#include <opencv2/features2d.hpp>

namespace affine_invariant_features {

class ResultMatcher {
public:
  ResultMatcher(const Results &reference) : reference_(reference) {
    switch (reference_.normType) {
    case cv::NORM_L2:
      matcher_ = new cv::FlannBasedMatcher(new cv::flann::KDTreeIndexParams(4));
      break;
    case cv::NORM_HAMMING:
      matcher_ = new cv::FlannBasedMatcher(new cv::flann::LshIndexParams(6, 12, 1));
      break;
    }

    CV_Assert(matcher_);

    matcher_->add(reference_.descriptors);
    matcher_->train();
  }

  virtual ~ResultMatcher() {}

  const Results &getReference() const { return reference_; }

  void match(const Results &source, cv::Matx33f &transform,
             std::vector< cv::DMatch > &matches) const {
    // initiate outputs
    transform = cv::Matx33f::eye();
    matches.clear();

    // find the 1st & 2nd matches for each descriptor in the source
    std::vector< std::vector< cv::DMatch > > all_matches;
    matcher_->knnMatch(source.descriptors, all_matches, 2);

    // filter unique matches whose 1st is enough better than 2nd
    std::vector< cv::DMatch > unique_matches;
    for (std::vector< std::vector< cv::DMatch > >::const_iterator m = all_matches.begin();
         m != all_matches.end(); ++m) {
      if (m->size() < 2) {
        continue;
      }
      if ((*m)[0].distance > 0.75 * (*m)[1].distance) {
        continue;
      }
      unique_matches.push_back((*m)[0]);
    }
    if (unique_matches.size() < 4) {
      // cv::findHomography requires 4 or more point pairs
      return;
    }

    // further filter matches compatible to a registration
    std::vector< unsigned char > mask;
    {
      std::vector< cv::Point2f > source_points;
      std::vector< cv::Point2f > reference_points;
      for (std::vector< cv::DMatch >::const_iterator m = unique_matches.begin();
           m != unique_matches.end(); ++m) {
        source_points.push_back(source.keypoints[m->queryIdx].pt);
        reference_points.push_back(reference_.keypoints[m->trainIdx].pt);
      }
      transform = cv::findHomography(source_points, reference_points, cv::RANSAC, 5., mask);
    }

    // pack the final matches
    for (std::size_t i = 0; i < unique_matches.size(); ++i) {
      if (mask[i] == 0) {
        continue;
      }
      matches.push_back(unique_matches[i]);
    }
  }

  static void parallelMatch(const std::vector< ResultMatcher > &matchers, const Results &source,
                            std::vector< cv::Matx33f > &transforms,
                            std::vector< std::vector< cv::DMatch > > &matches_array) {
    // initiate output
    const int ntasks(matchers.size());
    transforms.resize(ntasks);
    matches_array.resize(ntasks);

    // populate tasks
    ParallelTasks tasks;
    for (int i = 0; i < ntasks; ++i) {
      tasks.push_back(boost::bind(&ResultMatcher::match, &matchers[i], boost::ref(source),
                                  boost::ref(transforms[i]), boost::ref(matches_array[i])));
    }

    // do paralell matching
    cv::parallel_for_(cv::Range(0, ntasks), tasks);
  }

private:
  const Results reference_;
  cv::Ptr< cv::DescriptorMatcher > matcher_;
};
}

#endif<commit_msg>change parallelMatch interface<commit_after>#ifndef AFFINE_INVARIANT_FEATURES_RESULT_MATCHER
#define AFFINE_INVARIANT_FEATURES_RESULT_MATCHER

#include <vector>

#include <affine_invariant_features/parallel_tasks.hpp>
#include <affine_invariant_features/results.hpp>

#include <boost/bind.hpp>
#include <boost/ref.hpp>

#include <opencv2/calib3d.hpp>
#include <opencv2/core.hpp>
#include <opencv2/features2d.hpp>

namespace affine_invariant_features {

class ResultMatcher {
public:
  ResultMatcher(const Results &reference) : reference_(reference) {
    switch (reference_.normType) {
    case cv::NORM_L2:
      matcher_ = new cv::FlannBasedMatcher(new cv::flann::KDTreeIndexParams(4));
      break;
    case cv::NORM_HAMMING:
      matcher_ = new cv::FlannBasedMatcher(new cv::flann::LshIndexParams(6, 12, 1));
      break;
    }

    CV_Assert(matcher_);

    matcher_->add(reference_.descriptors);
    matcher_->train();
  }

  virtual ~ResultMatcher() {}

  const Results &getReference() const { return reference_; }

  void match(const Results &source, cv::Matx33f &transform,
             std::vector< cv::DMatch > &matches) const {
    // initiate outputs
    transform = cv::Matx33f::eye();
    matches.clear();

    // find the 1st & 2nd matches for each descriptor in the source
    std::vector< std::vector< cv::DMatch > > all_matches;
    matcher_->knnMatch(source.descriptors, all_matches, 2);

    // filter unique matches whose 1st is enough better than 2nd
    std::vector< cv::DMatch > unique_matches;
    for (std::vector< std::vector< cv::DMatch > >::const_iterator m = all_matches.begin();
         m != all_matches.end(); ++m) {
      if (m->size() < 2) {
        continue;
      }
      if ((*m)[0].distance > 0.75 * (*m)[1].distance) {
        continue;
      }
      unique_matches.push_back((*m)[0]);
    }
    if (unique_matches.size() < 4) {
      // cv::findHomography requires 4 or more point pairs
      return;
    }

    // further filter matches compatible to a registration
    std::vector< unsigned char > mask;
    {
      std::vector< cv::Point2f > source_points;
      std::vector< cv::Point2f > reference_points;
      for (std::vector< cv::DMatch >::const_iterator m = unique_matches.begin();
           m != unique_matches.end(); ++m) {
        source_points.push_back(source.keypoints[m->queryIdx].pt);
        reference_points.push_back(reference_.keypoints[m->trainIdx].pt);
      }
      transform = cv::findHomography(source_points, reference_points, cv::RANSAC, 5., mask);
    }

    // pack the final matches
    for (std::size_t i = 0; i < unique_matches.size(); ++i) {
      if (mask[i] == 0) {
        continue;
      }
      matches.push_back(unique_matches[i]);
    }
  }

  static void parallelMatch(const std::vector< cv::Ptr< ResultMatcher > > &matchers,
                            const Results &source, std::vector< cv::Matx33f > &transforms,
                            std::vector< std::vector< cv::DMatch > > &matches_array) {
    // initiate output
    const int ntasks(matchers.size());
    transforms.resize(ntasks);
    matches_array.resize(ntasks);

    // populate tasks
    ParallelTasks tasks;
    for (int i = 0; i < ntasks; ++i) {
      if (matchers[i]) {
        tasks.push_back(boost::bind(&ResultMatcher::match, matchers[i].get(), boost::ref(source),
                                    boost::ref(transforms[i]), boost::ref(matches_array[i])));
      }
    }

    // do paralell matching
    cv::parallel_for_(cv::Range(0, ntasks), tasks);
  }

private:
  const Results reference_;
  cv::Ptr< cv::DescriptorMatcher > matcher_;
};
}

#endif<|endoftext|>


<commit_before>
// Copyright (c) 2012, 2013 Pierre MOULON.

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef OPENMVG_ROBUST_ESTIMATION_LMEDS_H_
#define OPENMVG_ROBUST_ESTIMATION_LMEDS_H_

#include "openMVG/robust_estimation/rand_sampling.hpp"
#include "openMVG/robust_estimation/robust_ransac_tools.hpp"

#include <algorithm>
#include <limits>
#include <vector>

namespace openMVG {
namespace robust{

/// \brief Variant of RANSAC using Least Median of Squares.
/// \details Instead of using a fixed threshold to distinguish inlier/outlier,
/// find the threshold at 1-\a outlierRatio quantile of residuals and keep the
/// parameters minimizing this threshold. The final threshold
/// returned in \a outlierThreshold is a multiple of this and can be used to
/// filter out outliers.
/// LMedS : Z. Zhang. Determining The Epipolar Geometry And Its Uncertainty. A Review
/// IJCV 1998
template <typename Kernel>
  double LeastMedianOfSquares(const Kernel &kernel,
	  typename Kernel::Model * model = nullptr,
    double* outlierThreshold = nullptr,
    double outlierRatio=0.5,
	  double minProba=0.99)
{
  const size_t min_samples = Kernel::MINIMUM_SAMPLES;
  const size_t total_samples = kernel.NumSamples();

	std::vector<double> residuals(total_samples); // Array for storing residuals
  std::vector<size_t> vec_sample(min_samples);

	double dBestMedian = std::numeric_limits<double>::max();

	// Required number of iterations is evaluated from outliers ratio
	const size_t N = (min_samples<total_samples)?
		getNumSamples(minProba, outlierRatio, min_samples): 0;

	for (size_t i=0; i < N; i++) {

    // Get Samples indexes
    UniformSample(min_samples, total_samples, vec_sample);

    // Estimate parameters: the solutions are stored in a vector
    std::vector<typename Kernel::Model> models;
    kernel.Fit(vec_sample, &models);

		// Now test the solutions on the whole data
		for (size_t k = 0; k < models.size(); ++k) {
      //Compute Residuals :
      for (size_t l = 0; l < total_samples; ++l) {
        double error = kernel.Error(l, models[k]);
        residuals[l] = error;
      }

			// Compute median
			std::vector<double>::iterator itMedian = residuals.begin() +
				std::size_t( total_samples*(1.-outlierRatio) );
			std::nth_element(residuals.begin(), itMedian, residuals.end());
			double median = *itMedian;

			// Store best solution
			if(median < dBestMedian) {
				dBestMedian = median;
				if (model) (*model) = models[k];
			}
		}
	}

	// This array of precomputed values corresponds to the inverse
	//  cumulative function for a normal distribution. For more information
	//  consult the litterature (Robust Regression for Outlier Detection,
	//  rouseeuw-leroy). The values are computed for each 5%
	static const double ICDF[21] = {
		1.4e16, 15.94723940, 7.957896558, 5.287692054,
		3.947153876, 3.138344200, 2.595242369, 2.203797543,
		1.906939402, 1.672911853, 1.482602218, 1.323775627,
		1.188182950, 1.069988721, 0.9648473415, 0.8693011162,
		0.7803041458, 0.6946704675, 0.6079568319,0.5102134568,
		0.3236002672
	};

	// Evaluate the outlier threshold
	if(outlierThreshold) {
		double sigma = ICDF[int((1.-outlierRatio)*20.)] *
			(1. + 5. / double(total_samples - min_samples));
		*outlierThreshold = (double)(sigma * sigma * dBestMedian * 4.);
    if (N==0) *outlierThreshold = std::numeric_limits<double>::max();
	}

	return dBestMedian;
}

} // namespace robust
} // namespace openMVG
#endif // OPENMVG_ROBUST_ESTIMATION_LMEDS_H_
<commit_msg>[robust] just formatting<commit_after>
// Copyright (c) 2012, 2013 Pierre MOULON.

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#pragma once

#include "openMVG/robust_estimation/rand_sampling.hpp"
#include "openMVG/robust_estimation/robust_ransac_tools.hpp"

#include <algorithm>
#include <limits>
#include <vector>

namespace openMVG {
namespace robust {

/// \brief Variant of RANSAC using Least Median of Squares.
/// \details Instead of using a fixed threshold to distinguish inlier/outlier,
/// find the threshold at 1-\a outlierRatio quantile of residuals and keep the
/// parameters minimizing this threshold. The final threshold
/// returned in \a outlierThreshold is a multiple of this and can be used to
/// filter out outliers.
/// LMedS : Z. Zhang. Determining The Epipolar Geometry And Its Uncertainty. A Review
/// IJCV 1998

template <typename Kernel>
double LeastMedianOfSquares(const Kernel &kernel,
                            typename Kernel::Model * model = nullptr,
                            double* outlierThreshold = nullptr,
                            double outlierRatio = 0.5,
                            double minProba = 0.99)
{
  const std::size_t min_samples = Kernel::MINIMUM_SAMPLES;
  const std::size_t total_samples = kernel.NumSamples();

  std::vector<double> residuals(total_samples); // Array for storing residuals
  std::vector<std::size_t> vec_sample(min_samples);

  double dBestMedian = std::numeric_limits<double>::max();

  // Required number of iterations is evaluated from outliers ratio
  const std::size_t N = (min_samples < total_samples) ?
          getNumSamples(minProba, outlierRatio, min_samples) : 0;

  for(std::size_t i = 0; i < N; i++)
  {

    // Get Samples indexes
    UniformSample(min_samples, total_samples, vec_sample);

    // Estimate parameters: the solutions are stored in a vector
    std::vector<typename Kernel::Model> models;
    kernel.Fit(vec_sample, &models);

    // Now test the solutions on the whole data
    for(std::size_t k = 0; k < models.size(); ++k)
    {
      //Compute Residuals :
      for(std::size_t l = 0; l < total_samples; ++l)
      {
        double error = kernel.Error(l, models[k]);
        residuals[l] = error;
      }

      // Compute median
      std::vector<double>::iterator itMedian = residuals.begin() +
              std::size_t(total_samples * (1. - outlierRatio));
      std::nth_element(residuals.begin(), itMedian, residuals.end());
      double median = *itMedian;

      // Store best solution
      if(median < dBestMedian)
      {
        dBestMedian = median;
        if(model)
        {
          (*model) = models[k];
        }
      }
    }
  }

  // This array of precomputed values corresponds to the inverse
  //  cumulative function for a normal distribution. For more information
  //  consult the litterature (Robust Regression for Outlier Detection,
  //  rouseeuw-leroy). The values are computed for each 5%
  static const double ICDF[21] = {
    1.4e16, 15.94723940, 7.957896558, 5.287692054,
    3.947153876, 3.138344200, 2.595242369, 2.203797543,
    1.906939402, 1.672911853, 1.482602218, 1.323775627,
    1.188182950, 1.069988721, 0.9648473415, 0.8693011162,
    0.7803041458, 0.6946704675, 0.6079568319, 0.5102134568,
    0.3236002672
  };

  // Evaluate the outlier threshold
  if(outlierThreshold)
  {
    double sigma = ICDF[int((1. - outlierRatio)*20.)] *
            (1. + 5. / double(total_samples - min_samples));
    *outlierThreshold = (double) (sigma * sigma * dBestMedian * 4.);
    if(N == 0)
    {
      *outlierThreshold = std::numeric_limits<double>::max();
    }
  }

  return dBestMedian;
}

} // namespace robust
} // namespace openMVG
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: CheckBox.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: obo $ $Date: 2004-11-16 10:35:44 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _FORMS_CHECKBOX_HXX_
#define _FORMS_CHECKBOX_HXX_

#ifndef EFORMS2_FORMS_SOURCE_COMPONENT_REFVALUECOMPONENT_HXX
#include "refvaluecomponent.hxx"
#endif

//.........................................................................
namespace frm
{

//==================================================================
//= OCheckBoxModel
//==================================================================
class OCheckBoxModel    :public OReferenceValueComponent
                        ,public ::comphelper::OAggregationArrayUsageHelper< OCheckBoxModel >
{
protected:
    sal_Int16   getState(const ::com::sun::star::uno::Any& rValue);

public:
    DECLARE_DEFAULT_LEAF_XTOR( OCheckBoxModel );

    // XServiceInfo
    IMPLEMENTATION_NAME(OCheckBoxModel);
    virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);

    // XPropertySetRef
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() throw(::com::sun::star::uno::RuntimeException);
    virtual cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();

    // XPersistObject
    virtual ::rtl::OUString SAL_CALL    getServiceName() throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL
        write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL
        read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

    // OAggregationArrayUsageHelper
    virtual void fillProperties(
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps,
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps
        ) const;
    IMPLEMENT_INFO_SERVICE()

protected:
    DECLARE_XCLONEABLE();

    // OBoundControlModel overridables
    virtual ::com::sun::star::uno::Any
                            translateDbColumnToControlValue( );
    virtual sal_Bool        commitControlValueToDbColumn( bool _bPostReset );
};

//==================================================================
//= OCheckBoxControl
//==================================================================
class OCheckBoxControl : public OBoundControl
{
public:
    OCheckBoxControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);

    // XServiceInfo
    IMPLEMENTATION_NAME(OCheckBoxControl);
    virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
};

//.........................................................................
}
//.........................................................................

#endif // _FORMS_CHECKBOX_HXX_

<commit_msg>INTEGRATION: CWS ooo19126 (1.8.90); FILE MERGED 2005/09/05 13:50:13 rt 1.8.90.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: CheckBox.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 22:34:33 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _FORMS_CHECKBOX_HXX_
#define _FORMS_CHECKBOX_HXX_

#ifndef EFORMS2_FORMS_SOURCE_COMPONENT_REFVALUECOMPONENT_HXX
#include "refvaluecomponent.hxx"
#endif

//.........................................................................
namespace frm
{

//==================================================================
//= OCheckBoxModel
//==================================================================
class OCheckBoxModel    :public OReferenceValueComponent
                        ,public ::comphelper::OAggregationArrayUsageHelper< OCheckBoxModel >
{
protected:
    sal_Int16   getState(const ::com::sun::star::uno::Any& rValue);

public:
    DECLARE_DEFAULT_LEAF_XTOR( OCheckBoxModel );

    // XServiceInfo
    IMPLEMENTATION_NAME(OCheckBoxModel);
    virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);

    // XPropertySetRef
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() throw(::com::sun::star::uno::RuntimeException);
    virtual cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();

    // XPersistObject
    virtual ::rtl::OUString SAL_CALL    getServiceName() throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL
        write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL
        read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

    // OAggregationArrayUsageHelper
    virtual void fillProperties(
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps,
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps
        ) const;
    IMPLEMENT_INFO_SERVICE()

protected:
    DECLARE_XCLONEABLE();

    // OBoundControlModel overridables
    virtual ::com::sun::star::uno::Any
                            translateDbColumnToControlValue( );
    virtual sal_Bool        commitControlValueToDbColumn( bool _bPostReset );
};

//==================================================================
//= OCheckBoxControl
//==================================================================
class OCheckBoxControl : public OBoundControl
{
public:
    OCheckBoxControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);

    // XServiceInfo
    IMPLEMENTATION_NAME(OCheckBoxControl);
    virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
};

//.........................................................................
}
//.........................................................................

#endif // _FORMS_CHECKBOX_HXX_

<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company.  For licensing terms and
** conditions see http://www.qt.io/terms-conditions.  For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights.  These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "addobjectvisitor.h"

#include <qmljs/parser/qmljsast_p.h>

using namespace QmlDesigner;
using namespace QmlDesigner::Internal;
using namespace QmlJS;
using namespace QmlJS::AST;

AddObjectVisitor::AddObjectVisitor(TextModifier &modifier,
                                   quint32 parentLocation,
                                   const QString &content,
                                   const PropertyNameList &propertyOrder):
    QMLRewriter(modifier),
    m_parentLocation(parentLocation),
    m_content(content),
    m_propertyOrder(propertyOrder)
{
}

bool AddObjectVisitor::visit(UiObjectBinding *ast)
{
    if (didRewriting())
        return false;

    if (ast->qualifiedTypeNameId->identifierToken.offset == m_parentLocation)
        insertInto(ast->initializer);

    return !didRewriting();
}

bool AddObjectVisitor::visit(UiObjectDefinition *ast)
{
    if (didRewriting())
        return false;

    if (ast->firstSourceLocation().offset == m_parentLocation)
        insertInto(ast->initializer);

    return !didRewriting();
}

// FIXME: duplicate code in the QmlJS::Rewriter class, remove this
void AddObjectVisitor::insertInto(UiObjectInitializer *ast)
{
    UiObjectMemberList *insertAfter = searchMemberToInsertAfter(ast->members, m_propertyOrder);

    int insertionPoint;
    int depth;
    QString textToInsert;
    if (insertAfter && insertAfter->member) {
        insertionPoint = insertAfter->member->lastSourceLocation().end();
        depth = calculateIndentDepth(insertAfter->member->lastSourceLocation());
        textToInsert += QStringLiteral("\n");
    } else {
        insertionPoint = ast->lbraceToken.end();
        depth = calculateIndentDepth(ast->lbraceToken) + indentDepth();
    }

    textToInsert += addIndentation(m_content, depth);
    replace(insertionPoint, 0, QStringLiteral("\n") + textToInsert);

    setDidRewriting(true);
}
<commit_msg>QmlDesigner:  Remove using namespace QmlJS::AST from AddObjectVisitor<commit_after>/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company.  For licensing terms and
** conditions see http://www.qt.io/terms-conditions.  For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights.  These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "addobjectvisitor.h"

#include <qmljs/parser/qmljsast_p.h>

using namespace QmlDesigner;
using namespace QmlDesigner::Internal;

AddObjectVisitor::AddObjectVisitor(QmlDesigner::TextModifier &modifier,
                                   quint32 parentLocation,
                                   const QString &content,
                                   const PropertyNameList &propertyOrder):
    QMLRewriter(modifier),
    m_parentLocation(parentLocation),
    m_content(content),
    m_propertyOrder(propertyOrder)
{
}

bool AddObjectVisitor::visit(QmlJS::AST::UiObjectBinding *ast)
{
    if (didRewriting())
        return false;

    if (ast->qualifiedTypeNameId->identifierToken.offset == m_parentLocation)
        insertInto(ast->initializer);

    return !didRewriting();
}

bool AddObjectVisitor::visit(QmlJS::AST::UiObjectDefinition *ast)
{
    if (didRewriting())
        return false;

    if (ast->firstSourceLocation().offset == m_parentLocation)
        insertInto(ast->initializer);

    return !didRewriting();
}

// FIXME: duplicate code in the QmlJS::Rewriter class, remove this
void AddObjectVisitor::insertInto(QmlJS::AST::UiObjectInitializer *ast)
{
    QmlJS::AST::UiObjectMemberList *insertAfter = searchMemberToInsertAfter(ast->members, m_propertyOrder);

    int insertionPoint;
    int depth;
    QString textToInsert;
    if (insertAfter && insertAfter->member) {
        insertionPoint = insertAfter->member->lastSourceLocation().end();
        depth = calculateIndentDepth(insertAfter->member->lastSourceLocation());
        textToInsert += QStringLiteral("\n");
    } else {
        insertionPoint = ast->lbraceToken.end();
        depth = calculateIndentDepth(ast->lbraceToken) + indentDepth();
    }

    textToInsert += addIndentation(m_content, depth);
    replace(insertionPoint, 0, QStringLiteral("\n") + textToInsert);

    setDidRewriting(true);
}
<|endoftext|>


<commit_before>//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// MultisampledRenderToTextureBenchmark:
//   Performance test for rendering to multisampled-render-to-texture attachments.
//

#include "ANGLEPerfTest.h"

#include <iostream>
#include <random>
#include <sstream>

#include "test_utils/gl_raii.h"
#include "util/shader_utils.h"

using namespace angle;

namespace
{
constexpr uint32_t kMultipassPassCount = 5;

struct MultisampledRenderToTextureParams final : public RenderTestParams
{
    MultisampledRenderToTextureParams()
    {
        iterationsPerStep = 1;
        trackGpuTime      = true;

        textureWidth  = 1920;
        textureHeight = 1080;

        multiplePasses   = false;
        withDepthStencil = false;
    }

    std::string story() const override;

    GLsizei textureWidth;
    GLsizei textureHeight;

    bool multiplePasses;
    bool withDepthStencil;
};

std::ostream &operator<<(std::ostream &os, const MultisampledRenderToTextureParams &params)
{
    return os << params.backendAndStory().substr(1);
}

std::string MultisampledRenderToTextureParams::story() const
{
    std::stringstream strstr;

    strstr << RenderTestParams::story();

    if (multiplePasses)
    {
        strstr << "_multipass";
    }

    if (withDepthStencil)
    {
        strstr << "_ds";
    }

    return strstr.str();
}

class MultisampledRenderToTextureBenchmark
    : public ANGLERenderTest,
      public ::testing::WithParamInterface<MultisampledRenderToTextureParams>
{
  public:
    MultisampledRenderToTextureBenchmark();

    void initializeBenchmark() override;
    void destroyBenchmark() override;
    void drawBenchmark() override;

  protected:
    void initShaders();

    GLuint mFramebuffer              = 0;
    GLuint mProgram                  = 0;
    GLuint mColorTexture             = 0;
    GLuint mDepthStencilRenderbuffer = 0;

    std::vector<uint8_t> mTextureData;
};

MultisampledRenderToTextureBenchmark::MultisampledRenderToTextureBenchmark()
    : ANGLERenderTest("MultisampledRenderToTexture", GetParam())
{
    // Crashes on nvidia+d3d11. http://crbug.com/945415
    if (GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
    {
        mSkipTest = true;
    }

    // Fails on Windows7 NVIDIA Vulkan, presumably due to old drivers. http://crbug.com/1096510
    if (IsWindows7() && IsNVIDIA() &&
        GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE)
    {
        mSkipTest = true;
    }
}

void MultisampledRenderToTextureBenchmark::initializeBenchmark()
{
    if (!IsGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"))
    {
        mSkipTest = true;
        return;
    }

    const auto &params = GetParam();

    initShaders();
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());

    glGenFramebuffers(1, &mFramebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);

    glGenTextures(1, &mColorTexture);
    glBindTexture(GL_TEXTURE_2D, mColorTexture);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, params.textureWidth, params.textureHeight, 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, nullptr);
    glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                                         mColorTexture, 0, 4);

    if (params.withDepthStencil)
    {
        glGenRenderbuffers(1, &mDepthStencilRenderbuffer);
        glBindRenderbuffer(GL_RENDERBUFFER, mDepthStencilRenderbuffer);
        glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8,
                                            params.textureWidth, params.textureHeight);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                                  mDepthStencilRenderbuffer);
    }

    ASSERT_GL_NO_ERROR();
}

void MultisampledRenderToTextureBenchmark::initShaders()
{
    constexpr char kVS[] = R"(void main()
{
    gl_Position = vec4(0, 0, 0, 1);
})";

    constexpr char kFS[] = R"(precision mediump float;
void main()
{
    gl_FragColor = vec4(0);
})";

    mProgram = CompileProgram(kVS, kFS);
    ASSERT_NE(0u, mProgram);

    glUseProgram(mProgram);

    ASSERT_GL_NO_ERROR();
}

void MultisampledRenderToTextureBenchmark::destroyBenchmark()
{
    glDeleteFramebuffers(1, &mFramebuffer);
    glDeleteRenderbuffers(1, &mDepthStencilRenderbuffer);
    glDeleteTextures(1, &mColorTexture);
    glDeleteProgram(mProgram);
}

void MultisampledRenderToTextureBenchmark::drawBenchmark()
{
    const auto &params = GetParam();

    GLTexture mDummyTexture;
    glBindTexture(GL_TEXTURE_2D, mDummyTexture);

    startGpuTimer();

    // Initially clear the color attachment to avoid having to load from the resolved image.  The
    // depth/stencil attachment doesn't need this as it's contents are always undefined between
    // render passes.
    glClear(GL_COLOR_BUFFER_BIT);

    const uint32_t passCount = params.multiplePasses ? kMultipassPassCount : 1;
    for (uint32_t pass = 0; pass < passCount; ++pass)
    {
        // Perform a draw just to have something in the render pass.  With the position attributes
        // not set, a constant default value is used, resulting in a very cheap draw.
        glDrawArrays(GL_TRIANGLES, 0, 3);

        // Force the render pass to break by cheaply reading back from the color attachment.
        glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 1, 1, 0);
    }
    stopGpuTimer();

    ASSERT_GL_NO_ERROR();
}

MultisampledRenderToTextureParams D3D11Params(bool multiplePasses, bool withDepthStencil)
{
    MultisampledRenderToTextureParams params;
    params.eglParameters    = egl_platform::D3D11();
    params.majorVersion     = 3;
    params.minorVersion     = 0;
    params.multiplePasses   = multiplePasses;
    params.withDepthStencil = withDepthStencil;
    return params;
}

MultisampledRenderToTextureParams OpenGLOrGLESParams(bool multiplePasses, bool withDepthStencil)
{
    MultisampledRenderToTextureParams params;
    params.eglParameters    = egl_platform::OPENGL_OR_GLES();
    params.majorVersion     = 3;
    params.minorVersion     = 0;
    params.multiplePasses   = multiplePasses;
    params.withDepthStencil = withDepthStencil;
    return params;
}

MultisampledRenderToTextureParams VulkanParams(bool multiplePasses, bool withDepthStencil)
{
    MultisampledRenderToTextureParams params;
    params.eglParameters    = egl_platform::VULKAN();
    params.majorVersion     = 3;
    params.minorVersion     = 0;
    params.multiplePasses   = multiplePasses;
    params.withDepthStencil = withDepthStencil;
    return params;
}

}  // anonymous namespace

TEST_P(MultisampledRenderToTextureBenchmark, Run)
{
    run();
}

using namespace params;

ANGLE_INSTANTIATE_TEST(MultisampledRenderToTextureBenchmark,
                       D3D11Params(false, false),
                       D3D11Params(true, true),
                       OpenGLOrGLESParams(false, false),
                       OpenGLOrGLESParams(true, true),
                       VulkanParams(false, false),
                       VulkanParams(true, false),
                       VulkanParams(false, true),
                       VulkanParams(true, true));
<commit_msg>Suppress MultisampledRenderToTextureBenchmark on Pixel2/GLES<commit_after>//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// MultisampledRenderToTextureBenchmark:
//   Performance test for rendering to multisampled-render-to-texture attachments.
//

#include "ANGLEPerfTest.h"

#include <iostream>
#include <random>
#include <sstream>

#include "test_utils/gl_raii.h"
#include "util/shader_utils.h"

using namespace angle;

namespace
{
constexpr uint32_t kMultipassPassCount = 5;

struct MultisampledRenderToTextureParams final : public RenderTestParams
{
    MultisampledRenderToTextureParams()
    {
        iterationsPerStep = 1;
        trackGpuTime      = true;

        textureWidth  = 1920;
        textureHeight = 1080;

        multiplePasses   = false;
        withDepthStencil = false;
    }

    std::string story() const override;

    GLsizei textureWidth;
    GLsizei textureHeight;

    bool multiplePasses;
    bool withDepthStencil;
};

std::ostream &operator<<(std::ostream &os, const MultisampledRenderToTextureParams &params)
{
    return os << params.backendAndStory().substr(1);
}

std::string MultisampledRenderToTextureParams::story() const
{
    std::stringstream strstr;

    strstr << RenderTestParams::story();

    if (multiplePasses)
    {
        strstr << "_multipass";
    }

    if (withDepthStencil)
    {
        strstr << "_ds";
    }

    return strstr.str();
}

class MultisampledRenderToTextureBenchmark
    : public ANGLERenderTest,
      public ::testing::WithParamInterface<MultisampledRenderToTextureParams>
{
  public:
    MultisampledRenderToTextureBenchmark();

    void initializeBenchmark() override;
    void destroyBenchmark() override;
    void drawBenchmark() override;

  protected:
    void initShaders();

    GLuint mFramebuffer              = 0;
    GLuint mProgram                  = 0;
    GLuint mColorTexture             = 0;
    GLuint mDepthStencilRenderbuffer = 0;

    std::vector<uint8_t> mTextureData;
};

MultisampledRenderToTextureBenchmark::MultisampledRenderToTextureBenchmark()
    : ANGLERenderTest("MultisampledRenderToTexture", GetParam())
{
    // Crashes on nvidia+d3d11. http://crbug.com/945415
    if (GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
    {
        mSkipTest = true;
    }

    // Fails on Windows7 NVIDIA Vulkan, presumably due to old drivers. http://crbug.com/1096510
    if (IsWindows7() && IsNVIDIA() &&
        GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE)
    {
        mSkipTest = true;
    }

    // Fails on Pixel 2 GLES: http://anglebug.com/5120
    if (IsPixel2() && GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
    {
        mSkipTest = true;
    }
}

void MultisampledRenderToTextureBenchmark::initializeBenchmark()
{
    if (!IsGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"))
    {
        mSkipTest = true;
        return;
    }

    const auto &params = GetParam();

    initShaders();
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());

    glGenFramebuffers(1, &mFramebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);

    glGenTextures(1, &mColorTexture);
    glBindTexture(GL_TEXTURE_2D, mColorTexture);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, params.textureWidth, params.textureHeight, 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, nullptr);
    glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                                         mColorTexture, 0, 4);

    if (params.withDepthStencil)
    {
        glGenRenderbuffers(1, &mDepthStencilRenderbuffer);
        glBindRenderbuffer(GL_RENDERBUFFER, mDepthStencilRenderbuffer);
        glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8,
                                            params.textureWidth, params.textureHeight);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                                  mDepthStencilRenderbuffer);
    }

    ASSERT_GL_NO_ERROR();
}

void MultisampledRenderToTextureBenchmark::initShaders()
{
    constexpr char kVS[] = R"(void main()
{
    gl_Position = vec4(0, 0, 0, 1);
})";

    constexpr char kFS[] = R"(precision mediump float;
void main()
{
    gl_FragColor = vec4(0);
})";

    mProgram = CompileProgram(kVS, kFS);
    ASSERT_NE(0u, mProgram);

    glUseProgram(mProgram);

    ASSERT_GL_NO_ERROR();
}

void MultisampledRenderToTextureBenchmark::destroyBenchmark()
{
    glDeleteFramebuffers(1, &mFramebuffer);
    glDeleteRenderbuffers(1, &mDepthStencilRenderbuffer);
    glDeleteTextures(1, &mColorTexture);
    glDeleteProgram(mProgram);
}

void MultisampledRenderToTextureBenchmark::drawBenchmark()
{
    const auto &params = GetParam();

    GLTexture mDummyTexture;
    glBindTexture(GL_TEXTURE_2D, mDummyTexture);

    startGpuTimer();

    // Initially clear the color attachment to avoid having to load from the resolved image.  The
    // depth/stencil attachment doesn't need this as it's contents are always undefined between
    // render passes.
    glClear(GL_COLOR_BUFFER_BIT);

    const uint32_t passCount = params.multiplePasses ? kMultipassPassCount : 1;
    for (uint32_t pass = 0; pass < passCount; ++pass)
    {
        // Perform a draw just to have something in the render pass.  With the position attributes
        // not set, a constant default value is used, resulting in a very cheap draw.
        glDrawArrays(GL_TRIANGLES, 0, 3);

        // Force the render pass to break by cheaply reading back from the color attachment.
        glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 1, 1, 0);
    }
    stopGpuTimer();

    ASSERT_GL_NO_ERROR();
}

MultisampledRenderToTextureParams D3D11Params(bool multiplePasses, bool withDepthStencil)
{
    MultisampledRenderToTextureParams params;
    params.eglParameters    = egl_platform::D3D11();
    params.majorVersion     = 3;
    params.minorVersion     = 0;
    params.multiplePasses   = multiplePasses;
    params.withDepthStencil = withDepthStencil;
    return params;
}

MultisampledRenderToTextureParams OpenGLOrGLESParams(bool multiplePasses, bool withDepthStencil)
{
    MultisampledRenderToTextureParams params;
    params.eglParameters    = egl_platform::OPENGL_OR_GLES();
    params.majorVersion     = 3;
    params.minorVersion     = 0;
    params.multiplePasses   = multiplePasses;
    params.withDepthStencil = withDepthStencil;
    return params;
}

MultisampledRenderToTextureParams VulkanParams(bool multiplePasses, bool withDepthStencil)
{
    MultisampledRenderToTextureParams params;
    params.eglParameters    = egl_platform::VULKAN();
    params.majorVersion     = 3;
    params.minorVersion     = 0;
    params.multiplePasses   = multiplePasses;
    params.withDepthStencil = withDepthStencil;
    return params;
}

}  // anonymous namespace

TEST_P(MultisampledRenderToTextureBenchmark, Run)
{
    run();
}

using namespace params;

ANGLE_INSTANTIATE_TEST(MultisampledRenderToTextureBenchmark,
                       D3D11Params(false, false),
                       D3D11Params(true, true),
                       OpenGLOrGLESParams(false, false),
                       OpenGLOrGLESParams(true, true),
                       VulkanParams(false, false),
                       VulkanParams(true, false),
                       VulkanParams(false, true),
                       VulkanParams(true, true));
<|endoftext|>


<commit_before>/*********************************************************************
 *
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2016,
 *  TU Dortmund - Institute of Control Theory and Systems Engineering.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of the institute nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * Author: Christoph Rösmann
 *********************************************************************/

#include <teb_local_planner/homotopy_class_planner.h>

namespace teb_local_planner
{

template<typename BidirIter, typename Fun>
std::complex<long double> HomotopyClassPlanner::calculateHSignature(BidirIter path_start, BidirIter path_end, Fun fun_cplx_point, const ObstContainer* obstacles, double prescaler)
{
    if (obstacles->empty())
      return std::complex<double>(0,0);

    ROS_ASSERT_MSG(prescaler>0.1 && prescaler<=1, "Only a prescaler on the interval (0.1,1] ist allowed.");

    // guess values for f0
    // paper proposes a+b=N-1 && |a-b|<=1, 1...N obstacles
    int m = (int)obstacles->size()-1;

    if (m>5)
      m = 5;  // hardcoded, but this was working in my test cases... TODO further tests requried

  //   m = round(double(m) * prescaler);

    int a = (int) std::ceil(double(m)/2.0);
    int b = m-a;

    std::advance(path_end, -1); // reduce path_end by 1 (since we check line segments between those path points

    typedef std::complex<long double> cplx;
    // guess map size (only a really really coarse guess is required
    // use distance from start to goal as distance to each direction
    // TODO: one could move the map determination outside this function, since it remains constant for the whole planning interval
    cplx start = fun_cplx_point(*path_start);
    cplx end = fun_cplx_point(*path_end); // path_end points to the last point now after calling std::advance before
    double dist = std::sqrt( std::norm(end - start) );
    if (dist < 3.0)
      dist = 3.0; // set minimum bound on distance (we do not want to have numerical instabilities) and 3.0 performs fine...
    cplx map_bottom_left(start.real(), start.imag()-dist);
    cplx map_top_right(start.real()+dist, start.imag()+dist);

    cplx H = 0;
    std::vector<double> imag_proposals(5);

    // iterate path
    while(path_start != path_end)
    {
      cplx z1 = fun_cplx_point(*path_start);
      cplx z2 = fun_cplx_point(*boost::next(path_start));

      for (std::size_t l=0; l<obstacles->size(); ++l) // iterate all obstacles
      {
        cplx obst_l = obstacles->at(l)->getCentroidCplx();
        cplx f0 = (long double) prescaler * std::pow(obst_l-map_bottom_left,a) * std::pow(obst_l-map_top_right,b);
        // denum contains product with all obstacles exepct j==l
        cplx Al = f0;
        for (std::size_t j=0; j<obstacles->size(); ++j)
        {
          if (j==l)
              continue;
          cplx obst_j = obstacles->at(j)->getCentroidCplx();
          cplx diff = obst_l - obst_j;
          if (diff.real()!=0 || diff.imag()!=0)
              Al /= diff;
          else
            continue;
        }
        // compute log value
        double diff2 = std::abs(z2-obst_l);
        double diff1 = std::abs(z1-obst_l);
        if (diff2 == 0 || diff1 == 0)
          continue;
        double log_real = std::log(diff2)-std::log(diff1);
        // complex ln has more than one solution -> choose minimum abs angle -> paper
        imag_proposals.at(0) = std::arg(z2-obst_l)-std::arg(z1-obst_l);
        imag_proposals.at(1) = std::arg(z2-obst_l)-std::arg(z1-obst_l)+2*M_PI;
        imag_proposals.at(2) = std::arg(z2-obst_l)-std::arg(z1-obst_l)-2*M_PI;
        imag_proposals.at(3) = std::arg(z2-obst_l)-std::arg(z1-obst_l)+4*M_PI;
        imag_proposals.at(4) = std::arg(z2-obst_l)-std::arg(z1-obst_l)-4*M_PI;
        double log_imag = *std::min_element(imag_proposals.begin(),imag_proposals.end(),smaller_than_abs);
        cplx log_value(log_real,log_imag);
        //cplx log_value = std::log(z2-obst_l)-std::log(z1-obst_l); // the principal solution doesn't seem to work
        H += Al*log_value;
      }
      ++path_start;
    }
    return H;
}

template<typename BidirIter, typename Fun>
void HomotopyClassPlanner::addAndInitNewTeb(BidirIter path_start, BidirIter path_end, Fun fun_position, double start_orientation, double goal_orientation, const geometry_msgs::Twist* start_velocity)
{
  tebs_.push_back( TebOptimalPlannerPtr( new TebOptimalPlanner(*cfg_, obstacles_, robot_model_) ) );
  tebs_.back()->teb().initTEBtoGoal(path_start, path_end, fun_position, cfg_->robot.max_vel_x, cfg_->robot.max_vel_theta,
                                    cfg_->robot.acc_lim_x, cfg_->robot.acc_lim_theta, start_orientation, goal_orientation, cfg_->trajectory.min_samples);
  if (start_velocity)
    tebs_.back()->setVelocityStart(*start_velocity);
}

} // namespace teb_local_planner

<commit_msg>Changed the f0 function for calculating the H-Signature. The new one seems to be more robust for a much larger number of obstacles after some testing.<commit_after>/*********************************************************************
 *
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2016,
 *  TU Dortmund - Institute of Control Theory and Systems Engineering.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of the institute nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * Author: Christoph Rösmann
 *********************************************************************/

#include <teb_local_planner/homotopy_class_planner.h>

namespace teb_local_planner
{

template<typename BidirIter, typename Fun>
std::complex<long double> HomotopyClassPlanner::calculateHSignature(BidirIter path_start, BidirIter path_end, Fun fun_cplx_point, const ObstContainer* obstacles, double prescaler)
{
    if (obstacles->empty())
      return std::complex<double>(0,0);

    ROS_ASSERT_MSG(prescaler>0.1 && prescaler<=1, "Only a prescaler on the interval (0.1,1] ist allowed.");

    // guess values for f0
    // paper proposes a+b=N-1 && |a-b|<=1, 1...N obstacles
    int m = (int)obstacles->size()-1;

    int a = (int) std::ceil(double(m)/2.0);
    int b = m-a;

    std::advance(path_end, -1); // reduce path_end by 1 (since we check line segments between those path points

    typedef std::complex<long double> cplx;
    // guess map size (only a really really coarse guess is required
    // use distance from start to goal as distance to each direction
    // TODO: one could move the map determination outside this function, since it remains constant for the whole planning interval
    cplx start = fun_cplx_point(*path_start);
    cplx end = fun_cplx_point(*path_end); // path_end points to the last point now after calling std::advance before
    cplx delta = end-start;
    cplx normal(-delta.imag(), delta.real());
    cplx map_bottom_left;
    cplx map_top_right;
    if (std::abs(delta) < 3.0)
    { // set minimum bound on distance (we do not want to have numerical instabilities) and 3.0 performs fine...
      map_bottom_left = start + cplx(0, -3);
      map_top_right = start + cplx(3, 3);
    }
    else
    {
      map_bottom_left = start - normal;
      map_top_right = start + delta + normal;
    }

    cplx H = 0;
    std::vector<double> imag_proposals(5);

    // iterate path
    while(path_start != path_end)
    {
      cplx z1 = fun_cplx_point(*path_start);
      cplx z2 = fun_cplx_point(*boost::next(path_start));

      for (std::size_t l=0; l<obstacles->size(); ++l) // iterate all obstacles
      {
        cplx obst_l = obstacles->at(l)->getCentroidCplx();
        //cplx f0 = (long double) prescaler * std::pow(obst_l-map_bottom_left,a) * std::pow(obst_l-map_top_right,b);
        cplx f0 = (long double) prescaler * (long double)a*(obst_l-map_bottom_left) * (long double)b*(obst_l-map_top_right);

        // denum contains product with all obstacles exepct j==l
        cplx Al = f0;
        for (std::size_t j=0; j<obstacles->size(); ++j)
        {
          if (j==l)
              continue;
          cplx obst_j = obstacles->at(j)->getCentroidCplx();
          cplx diff = obst_l - obst_j;
          //if (diff.real()!=0 || diff.imag()!=0)
          if (std::abs(diff)<0.05) // skip really close obstacles
              Al /= diff;
          else
            continue;
        }
        // compute log value
        double diff2 = std::abs(z2-obst_l);
        double diff1 = std::abs(z1-obst_l);
        if (diff2 == 0 || diff1 == 0)
          continue;
        double log_real = std::log(diff2)-std::log(diff1);
        // complex ln has more than one solution -> choose minimum abs angle -> paper
        double arg_diff = std::arg(z2-obst_l)-std::arg(z1-obst_l);
        imag_proposals.at(0) = arg_diff;
        imag_proposals.at(1) = arg_diff+2*M_PI;
        imag_proposals.at(2) = arg_diff-2*M_PI;
        imag_proposals.at(3) = arg_diff+4*M_PI;
        imag_proposals.at(4) = arg_diff-4*M_PI;
        double log_imag = *std::min_element(imag_proposals.begin(),imag_proposals.end(),smaller_than_abs);
        cplx log_value(log_real,log_imag);
        //cplx log_value = std::log(z2-obst_l)-std::log(z1-obst_l); // the principal solution doesn't seem to work
        H += Al*log_value;
      }
      ++path_start;
    }
    return H;
}

template<typename BidirIter, typename Fun>
void HomotopyClassPlanner::addAndInitNewTeb(BidirIter path_start, BidirIter path_end, Fun fun_position, double start_orientation, double goal_orientation, const geometry_msgs::Twist* start_velocity)
{
  tebs_.push_back( TebOptimalPlannerPtr( new TebOptimalPlanner(*cfg_, obstacles_, robot_model_) ) );
  tebs_.back()->teb().initTEBtoGoal(path_start, path_end, fun_position, cfg_->robot.max_vel_x, cfg_->robot.max_vel_theta,
                                    cfg_->robot.acc_lim_x, cfg_->robot.acc_lim_theta, start_orientation, goal_orientation, cfg_->trajectory.min_samples);
  if (start_velocity)
    tebs_.back()->setVelocityStart(*start_velocity);
}

} // namespace teb_local_planner

<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    MPIGroups.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm 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 notice for more information.

=========================================================================*/
#include "vtkMPIController.h"
#include "vtkSphereSource.h"
#include "vtkPolyDataNormals.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkCompositeRenderManager.h"
#include "vtkDebugLeaks.h"
#include "vtkParallelFactory.h"
#include "vtkRegressionTestImage.h"
#include "vtkMPIGroup.h"

static const int NUM_PROC_PER_GROUP = 2;

struct MPIGroupsArgs_tmp
{
  int* retVal;
  int argc;
  char** argv;
};

void proc1( vtkMultiProcessController *controller, void *arg );
void proc2( vtkMultiProcessController *controller, void *arg );

void MyMain( vtkMultiProcessController *controller, void *arg )
{

  MPIGroupsArgs_tmp* args =
    reinterpret_cast<MPIGroupsArgs_tmp*>(arg);

  int myId = controller->GetLocalProcessId();

  vtkMPICommunicator* localComm = vtkMPICommunicator::New();
  vtkMPIGroup* localGroup= vtkMPIGroup::New();
  vtkMPIController* localController = vtkMPIController::New();
  vtkMPICommunicator* worldComm = vtkMPICommunicator::GetWorldCommunicator();

  int currentGroup = myId / NUM_PROC_PER_GROUP;

  localGroup->Initialize( static_cast<vtkMPIController*>(controller) );
  for(int i=0; i<NUM_PROC_PER_GROUP; i++)
    {
    localGroup->AddProcessId(currentGroup*NUM_PROC_PER_GROUP + i);
    }
  localComm->Initialize(worldComm, localGroup);
  localGroup->UnRegister(0);

  // Create a local controller (for the sub-group)
  localController->SetCommunicator(localComm);
  localComm->UnRegister(0);

  int locRetVal;
  if ( currentGroup == 0 )
    {
    localController->SetSingleMethod(proc1, arg);
    localController->SingleMethodExecute();
    }
  else if ( currentGroup == 1 )
    {
    localController->SetSingleMethod(proc2, &locRetVal);
    localController->SingleMethodExecute();
    }
  localController->Delete();

  if ( myId == 0 )
    {
    controller->Receive(&locRetVal, 1, 3, 33);
    if (args->retVal && (!locRetVal))
      {
      *(args->retVal) = locRetVal;
      }
    }
  else if (myId == 3)
    {
    controller->Send(&locRetVal, 1, 0, 33);
    }
}

// This will be called by all processes
void proc1( vtkMultiProcessController *controller, void *arg )
{

  MPIGroupsArgs_tmp* args =
    reinterpret_cast<MPIGroupsArgs_tmp*>(arg);

  int myid, numProcs;

  // Obtain the id of the running process and the total
  // number of processes
  myid = controller->GetLocalProcessId();
  numProcs = controller->GetNumberOfProcesses();

  vtkSphereSource* sphere = vtkSphereSource::New();
  sphere->SetThetaResolution(16);
  sphere->SetPhiResolution(16);

  vtkPolyDataNormals* pdn = vtkPolyDataNormals::New();
  pdn->SetInput(sphere->GetOutput());
  sphere->UnRegister(0);

  vtkPolyDataMapper *mapper = vtkPolyDataMapper::New();
  mapper->SetInput(pdn->GetOutput());
  pdn->UnRegister(0);

  vtkActor *actor = vtkActor::New();
  actor->SetMapper(mapper);
  mapper->UnRegister(0);

  vtkRenderer *ren = vtkRenderer::New();
  ren->AddActor(actor);
  actor->UnRegister(0);

  vtkRenderWindow *renWin = vtkRenderWindow::New();
  renWin->AddRenderer(ren);
  ren->UnRegister(0);
  renWin->SetPosition(0, 360 * myid);

  vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
  iren->SetRenderWindow(renWin);

  // The only thing we have to do to get parallel execution.
  vtkCompositeRenderManager*  treeComp = vtkCompositeRenderManager::New();
  treeComp->SetController(controller);
  treeComp->SetRenderWindow(renWin);

  // Tell the mappers to only update a piece (based on process) of
  // their inputs.
  treeComp->InitializePieces();

  if (myid)
    {
    treeComp->InitializeRMIs();
    controller->ProcessRMIs();
    controller->Receive(args->retVal, 1, 0, 33);
    }
  else
    {
    renWin->Render();
    renWin->Render();
    *(args->retVal) =
      vtkRegressionTester::Test(args->argc, args->argv, renWin, 10);
    for (int i = 1; i < numProcs; i++)
      {
      controller->TriggerRMI(i, vtkMultiProcessController::BREAK_RMI_TAG);
      controller->Send(args->retVal, 1, i, 33);
      }
    }

  if (!myid)
    {
    }

  if ( *(args->retVal) == vtkRegressionTester::DO_INTERACTOR)
    {
    treeComp->StartInteractor();
    }

  iren->Delete();
  renWin->Delete();
  treeComp->Delete();
}

void proc2( vtkMultiProcessController *contr, void *arg )
{
  vtkMPIController* controller = static_cast<vtkMPIController*>(contr);

  if (controller->GetLocalProcessId() == 0)
    {
    int vali = 12;
    vtkMPICommunicator::Request req1;
    controller->NoBlockSend(&vali, 1, 1, 95, req1);
    int valul = 12;
    vtkMPICommunicator::Request req2;
    controller->NoBlockSend(&valul, 1, 1, 96, req2);
    int valc = 12;
    vtkMPICommunicator::Request req3;
    controller->NoBlockSend(&valc, 1, 1, 97, req3);
    int valf = 12;
    vtkMPICommunicator::Request req4;
    controller->NoBlockSend(&valf, 1, 1, 98, req4);
    }
  else if (controller->GetLocalProcessId() == 1)
    {
    int* retVal = static_cast<int*>(arg);
    *retVal = 1;

    int vali;
    vtkMPICommunicator::Request req1;
    controller->NoBlockReceive(&vali, 1, vtkMultiProcessController::ANY_SOURCE,
                               95, req1);
    req1.Wait();
    if (req1.Test() && (vali == 12))
      {
      cout << "Receive (int) succeeded." << endl;
      }
    else
      {
      cout << "Receive (int) failed:" << vali << endl;
      *retVal = 0;
      }
    int valul;
    vtkMPICommunicator::Request req2;
    controller->NoBlockReceive(&valul, 1, vtkMultiProcessController::ANY_SOURCE,
                               96, req2);
    req2.Wait();
    if (req2.Test() && (valul == 12))
      {
      cout << "Receive (unsigned long) succeeded." << endl;
      }
    else
      {
      cout << "Receive (unsigned long) failed:" << valul << endl;
      *retVal = 0;
      }
    int valc;
    vtkMPICommunicator::Request req3;
    controller->NoBlockReceive(&valc, 1, vtkMultiProcessController::ANY_SOURCE,
                               97, req3);
    req3.Wait();
    if (req3.Test() && (valc == 12))
      {
      cout << "Receive (char) succeeded." << endl;
      }
    else
      {
      cout << "Receive (char) failed:" << valc  << endl;
      *retVal = 0;
      }
    int valf;
    vtkMPICommunicator::Request req4;
    controller->NoBlockReceive(&valf, 1, vtkMultiProcessController::ANY_SOURCE,
                               98, req4);
    req4.Wait();
    if (req4.Test() && (valf == 12))
      {
      cout << "Receive (float) succeeded." << endl;
      }
    else
      {
      cout << "Receive (float) failed:" << valf  << endl;
      *retVal = 0;
      }
    }

  // Just for coverage
  controller->Barrier();

}

int main( int argc, char* argv[] )
{
  vtkMPIController *controller;

  // Note that this will create a vtkMPIController if MPI
  // is configured, vtkMPIController otherwise.
  controller = vtkMPIController::New();

  vtkDebugLeaks::PromptUserOff();
  controller->Initialize(&argc, &argv);
  vtkDebugLeaks::PromptUserOff();

  int numProcs = controller->GetNumberOfProcesses();
  int myId = controller->GetLocalProcessId();
  if (numProcs != 4)
    {
    if (!myId)
      {
      cerr << "This program requires 4 processes." << endl;
      }
    controller->Finalize();
    controller->Delete();
    return -1;
    }

  vtkParallelFactory* pf = vtkParallelFactory::New();
  vtkObjectFactory::RegisterFactory(pf);
  pf->Delete();

  // Added for regression test.
  // ----------------------------------------------
  int retVal;
  MPIGroupsArgs_tmp args;
  args.retVal = &retVal;
  args.argc = argc;
  args.argv = argv;
  // ----------------------------------------------

  controller->SetSingleMethod(MyMain, &args);
  controller->SingleMethodExecute();

  controller->Finalize();
  controller->Delete();

  return !retVal;
}

<commit_msg>ENH: converting vtkPolyDataNormals to use the new pipeline<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    MPIGroups.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm 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 notice for more information.

=========================================================================*/
#include "vtkMPIController.h"
#include "vtkSphereSource.h"
#include "vtkPolyDataNormals.h"
#include "vtkPolyDataMapper.h"
#include "vtkPolyData.h"
#include "vtkActor.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkCompositeRenderManager.h"
#include "vtkDebugLeaks.h"
#include "vtkParallelFactory.h"
#include "vtkRegressionTestImage.h"
#include "vtkMPIGroup.h"

static const int NUM_PROC_PER_GROUP = 2;

struct MPIGroupsArgs_tmp
{
  int* retVal;
  int argc;
  char** argv;
};

void proc1( vtkMultiProcessController *controller, void *arg );
void proc2( vtkMultiProcessController *controller, void *arg );

void MyMain( vtkMultiProcessController *controller, void *arg )
{

  MPIGroupsArgs_tmp* args =
    reinterpret_cast<MPIGroupsArgs_tmp*>(arg);

  int myId = controller->GetLocalProcessId();

  vtkMPICommunicator* localComm = vtkMPICommunicator::New();
  vtkMPIGroup* localGroup= vtkMPIGroup::New();
  vtkMPIController* localController = vtkMPIController::New();
  vtkMPICommunicator* worldComm = vtkMPICommunicator::GetWorldCommunicator();

  int currentGroup = myId / NUM_PROC_PER_GROUP;

  localGroup->Initialize( static_cast<vtkMPIController*>(controller) );
  for(int i=0; i<NUM_PROC_PER_GROUP; i++)
    {
    localGroup->AddProcessId(currentGroup*NUM_PROC_PER_GROUP + i);
    }
  localComm->Initialize(worldComm, localGroup);
  localGroup->UnRegister(0);

  // Create a local controller (for the sub-group)
  localController->SetCommunicator(localComm);
  localComm->UnRegister(0);

  int locRetVal;
  if ( currentGroup == 0 )
    {
    localController->SetSingleMethod(proc1, arg);
    localController->SingleMethodExecute();
    }
  else if ( currentGroup == 1 )
    {
    localController->SetSingleMethod(proc2, &locRetVal);
    localController->SingleMethodExecute();
    }
  localController->Delete();

  if ( myId == 0 )
    {
    controller->Receive(&locRetVal, 1, 3, 33);
    if (args->retVal && (!locRetVal))
      {
      *(args->retVal) = locRetVal;
      }
    }
  else if (myId == 3)
    {
    controller->Send(&locRetVal, 1, 0, 33);
    }
}

// This will be called by all processes
void proc1( vtkMultiProcessController *controller, void *arg )
{

  MPIGroupsArgs_tmp* args =
    reinterpret_cast<MPIGroupsArgs_tmp*>(arg);

  int myid, numProcs;

  // Obtain the id of the running process and the total
  // number of processes
  myid = controller->GetLocalProcessId();
  numProcs = controller->GetNumberOfProcesses();

  vtkSphereSource* sphere = vtkSphereSource::New();
  sphere->SetThetaResolution(16);
  sphere->SetPhiResolution(16);

  vtkPolyDataNormals* pdn = vtkPolyDataNormals::New();
  pdn->SetInput(sphere->GetOutput());
  sphere->UnRegister(0);

  vtkPolyDataMapper *mapper = vtkPolyDataMapper::New();
  mapper->SetInput(pdn->GetOutput());
  pdn->UnRegister(0);

  vtkActor *actor = vtkActor::New();
  actor->SetMapper(mapper);
  mapper->UnRegister(0);

  vtkRenderer *ren = vtkRenderer::New();
  ren->AddActor(actor);
  actor->UnRegister(0);

  vtkRenderWindow *renWin = vtkRenderWindow::New();
  renWin->AddRenderer(ren);
  ren->UnRegister(0);
  renWin->SetPosition(0, 360 * myid);

  vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
  iren->SetRenderWindow(renWin);

  // The only thing we have to do to get parallel execution.
  vtkCompositeRenderManager*  treeComp = vtkCompositeRenderManager::New();
  treeComp->SetController(controller);
  treeComp->SetRenderWindow(renWin);

  // Tell the mappers to only update a piece (based on process) of
  // their inputs.
  treeComp->InitializePieces();

  if (myid)
    {
    treeComp->InitializeRMIs();
    controller->ProcessRMIs();
    controller->Receive(args->retVal, 1, 0, 33);
    }
  else
    {
    renWin->Render();
    renWin->Render();
    *(args->retVal) =
      vtkRegressionTester::Test(args->argc, args->argv, renWin, 10);
    for (int i = 1; i < numProcs; i++)
      {
      controller->TriggerRMI(i, vtkMultiProcessController::BREAK_RMI_TAG);
      controller->Send(args->retVal, 1, i, 33);
      }
    }

  if (!myid)
    {
    }

  if ( *(args->retVal) == vtkRegressionTester::DO_INTERACTOR)
    {
    treeComp->StartInteractor();
    }

  iren->Delete();
  renWin->Delete();
  treeComp->Delete();
}

void proc2( vtkMultiProcessController *contr, void *arg )
{
  vtkMPIController* controller = static_cast<vtkMPIController*>(contr);

  if (controller->GetLocalProcessId() == 0)
    {
    int vali = 12;
    vtkMPICommunicator::Request req1;
    controller->NoBlockSend(&vali, 1, 1, 95, req1);
    int valul = 12;
    vtkMPICommunicator::Request req2;
    controller->NoBlockSend(&valul, 1, 1, 96, req2);
    int valc = 12;
    vtkMPICommunicator::Request req3;
    controller->NoBlockSend(&valc, 1, 1, 97, req3);
    int valf = 12;
    vtkMPICommunicator::Request req4;
    controller->NoBlockSend(&valf, 1, 1, 98, req4);
    }
  else if (controller->GetLocalProcessId() == 1)
    {
    int* retVal = static_cast<int*>(arg);
    *retVal = 1;

    int vali;
    vtkMPICommunicator::Request req1;
    controller->NoBlockReceive(&vali, 1, vtkMultiProcessController::ANY_SOURCE,
                               95, req1);
    req1.Wait();
    if (req1.Test() && (vali == 12))
      {
      cout << "Receive (int) succeeded." << endl;
      }
    else
      {
      cout << "Receive (int) failed:" << vali << endl;
      *retVal = 0;
      }
    int valul;
    vtkMPICommunicator::Request req2;
    controller->NoBlockReceive(&valul, 1, vtkMultiProcessController::ANY_SOURCE,
                               96, req2);
    req2.Wait();
    if (req2.Test() && (valul == 12))
      {
      cout << "Receive (unsigned long) succeeded." << endl;
      }
    else
      {
      cout << "Receive (unsigned long) failed:" << valul << endl;
      *retVal = 0;
      }
    int valc;
    vtkMPICommunicator::Request req3;
    controller->NoBlockReceive(&valc, 1, vtkMultiProcessController::ANY_SOURCE,
                               97, req3);
    req3.Wait();
    if (req3.Test() && (valc == 12))
      {
      cout << "Receive (char) succeeded." << endl;
      }
    else
      {
      cout << "Receive (char) failed:" << valc  << endl;
      *retVal = 0;
      }
    int valf;
    vtkMPICommunicator::Request req4;
    controller->NoBlockReceive(&valf, 1, vtkMultiProcessController::ANY_SOURCE,
                               98, req4);
    req4.Wait();
    if (req4.Test() && (valf == 12))
      {
      cout << "Receive (float) succeeded." << endl;
      }
    else
      {
      cout << "Receive (float) failed:" << valf  << endl;
      *retVal = 0;
      }
    }

  // Just for coverage
  controller->Barrier();

}

int main( int argc, char* argv[] )
{
  vtkMPIController *controller;

  // Note that this will create a vtkMPIController if MPI
  // is configured, vtkMPIController otherwise.
  controller = vtkMPIController::New();

  vtkDebugLeaks::PromptUserOff();
  controller->Initialize(&argc, &argv);
  vtkDebugLeaks::PromptUserOff();

  int numProcs = controller->GetNumberOfProcesses();
  int myId = controller->GetLocalProcessId();
  if (numProcs != 4)
    {
    if (!myId)
      {
      cerr << "This program requires 4 processes." << endl;
      }
    controller->Finalize();
    controller->Delete();
    return -1;
    }

  vtkParallelFactory* pf = vtkParallelFactory::New();
  vtkObjectFactory::RegisterFactory(pf);
  pf->Delete();

  // Added for regression test.
  // ----------------------------------------------
  int retVal;
  MPIGroupsArgs_tmp args;
  args.retVal = &retVal;
  args.argc = argc;
  args.argv = argv;
  // ----------------------------------------------

  controller->SetSingleMethod(MyMain, &args);
  controller->SingleMethodExecute();

  controller->Finalize();
  controller->Delete();

  return !retVal;
}

<|endoftext|>


<commit_before>/* RoboticsLab, Copyright 2008-2010 SimLab Co., Ltd. All rights reserved.
 *
 * This library is commercial and cannot be redistributed, and/or modified
 * WITHOUT ANY ALLOWANCE OR PERMISSION OF SimLab Co., LTD.
 */
#include "SequentialHybridAutomatonManager.h"
#include "SequentialHybridAutomatonManagerCmd.h"

SequentialHybridAutomatonManager::SequentialHybridAutomatonManager(rDC rdc)
#ifdef _USE_RCONTROLALGORITHM_EX_
:AbstractHybridAutomatonManager(rdc)
#else
:AbstractHybridAutomatonManager(rdc)
#endif
{
}

SequentialHybridAutomatonManager::~SequentialHybridAutomatonManager()
{
}

void SequentialHybridAutomatonManager::updateMotionBehaviour(const rTime& t)
{
	Milestone* childMs = (Milestone*)(_activeMotionBehaviour->getChild());

	if( !_deserialized_hybrid_automatons.empty() )
	{
		if (WaitForSingleObject(_deserialize_mutex, 0) != WAIT_FAILED && !_deserialized_hybrid_automatons.empty())
		{
			delete _hybrid_automaton;
			_hybrid_automaton = _deserialized_hybrid_automatons.front();
			_deserialized_hybrid_automatons.pop_front();

			std::cout << "New Hybrid Automaton" << std::endl;
			_activeMotionBehaviour->deactivate();
			_activeMotionBehaviour = (MotionBehaviour*) _hybrid_automaton->outgoingEdges(_hybrid_automaton->getStartNode())[0];
			_activeMotionBehaviour->activate();
			ReleaseMutex(_deserialize_mutex);
		}
	}
	else if (_hybrid_automaton && childMs->hasConverged(_sys))
	{
		std::cout << "[HybridAutomatonManager::_compute] INFO: Milestone " << childMs->getName() << " converged." << std::endl;
		std::vector<const Edge*> edges = _hybrid_automaton->outgoingEdges(childMs);
		if (!edges.empty())
		{
			_activeMotionBehaviour->deactivate();
			_activeMotionBehaviour = (MotionBehaviour*) edges[0];
			_activeMotionBehaviour->activate();
			std::cout << "[HybridAutomatonManager::_compute] INFO: Changed motion behavior. Next goal: " << ((Milestone*)(_activeMotionBehaviour->getChild()))->getName() << std::endl;
		}
	}
}

void SequentialHybridAutomatonManager::updateBlackboard()
{
	if(!_blackboard)
		return;

	if (_currentMotionBehavior && _currentMotionBehavior->getChild())
		_blackboard->setBool("idle", ((Milestone*)_currentMotionBehavior->getChild())->hasConverged(_sys));
	else
		_blackboard->setBool("idle", false);

	AbstractHybridAutomatonManager::updateBlackboard();
}

rControlAlgorithm* CreateControlAlgorithm(rDC& rdc)
{
	return new SequentialHybridAutomatonManager(rdc);
}
<commit_msg>bug fix<commit_after>/* RoboticsLab, Copyright 2008-2010 SimLab Co., Ltd. All rights reserved.
 *
 * This library is commercial and cannot be redistributed, and/or modified
 * WITHOUT ANY ALLOWANCE OR PERMISSION OF SimLab Co., LTD.
 */
#include "SequentialHybridAutomatonManager.h"
#include "SequentialHybridAutomatonManagerCmd.h"

SequentialHybridAutomatonManager::SequentialHybridAutomatonManager(rDC rdc)
#ifdef _USE_RCONTROLALGORITHM_EX_
:AbstractHybridAutomatonManager(rdc)
#else
:AbstractHybridAutomatonManager(rdc)
#endif
{
}

SequentialHybridAutomatonManager::~SequentialHybridAutomatonManager()
{
}

void SequentialHybridAutomatonManager::updateMotionBehaviour(const rTime& t)
{
	Milestone* childMs = (Milestone*)(_activeMotionBehaviour->getChild());

	if( !_deserialized_hybrid_automatons.empty() )
	{
		if (WaitForSingleObject(_deserialize_mutex, 0) != WAIT_FAILED && !_deserialized_hybrid_automatons.empty())
		{
			delete _hybrid_automaton;
			_hybrid_automaton = _deserialized_hybrid_automatons.front();
			_deserialized_hybrid_automatons.pop_front();

			std::cout << "New Hybrid Automaton" << std::endl;
			_activeMotionBehaviour->deactivate();
			_activeMotionBehaviour = (MotionBehaviour*) _hybrid_automaton->outgoingEdges(_hybrid_automaton->getStartNode())[0];
			_activeMotionBehaviour->activate();
			ReleaseMutex(_deserialize_mutex);
		}
	}
	else if (_hybrid_automaton && childMs->hasConverged(_sys))
	{
		std::cout << "[HybridAutomatonManager::_compute] INFO: Milestone " << childMs->getName() << " converged." << std::endl;
		std::vector<const Edge*> edges = _hybrid_automaton->outgoingEdges(childMs);
		if (!edges.empty())
		{
			_activeMotionBehaviour->deactivate();
			_activeMotionBehaviour = (MotionBehaviour*) edges[0];
			_activeMotionBehaviour->activate();
			std::cout << "[HybridAutomatonManager::_compute] INFO: Changed motion behavior. Next goal: " << ((Milestone*)(_activeMotionBehaviour->getChild()))->getName() << std::endl;
		}
	}
}

void SequentialHybridAutomatonManager::updateBlackboard()
{
	if(!_blackboard)
		return;

	if (_activeMotionBehaviour && _activeMotionBehaviour->getChild())
		_blackboard->setBool("idle", ((Milestone*)_activeMotionBehaviour->getChild())->hasConverged(_sys));
	else
		_blackboard->setBool("idle", false);

	AbstractHybridAutomatonManager::updateBlackboard();
}

rControlAlgorithm* CreateControlAlgorithm(rDC& rdc)
{
	return new SequentialHybridAutomatonManager(rdc);
}
<|endoftext|>


<commit_before>// Copyright (C) 2010 - 2015 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

// Copyright (C) 2008 - 2009 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., EML Research, gGmbH, University of Heidelberg,
// and The University of Manchester.
// All rights reserved.

#define COPASI_MAIN

#include <iostream>
#include <stdlib.h>

#include "copasi/copasi.h"
#include "copasi/CopasiDataModel/CCopasiDataModel.h"
#include "copasi/report/CCopasiRootContainer.h"
#include "copasi/model/CMetab.h"
#include "copasi/report/CCopasiObjectName.h"
#include "copasi/utilities/CCopasiVector.h"
#include "copasi/model/CModel.h"
#include "copasi/utilities/CCopasiException.h"
#include "copasi/commandline/COptionParser.h"
#include "copasi/commandline/COptions.h"

#include "copasi/trajectory/CTrajectoryTask.h"
#include "copasi/trajectory/CTrajectoryMethod.h"
#include "copasi/trajectory/CTrajectoryProblem.h"
#include "copasi/report/CReportDefinitionVector.h"
#include "copasi/report/CReportDefinition.h"

int main(int argc, char *argv[])
{
  // Parse the commandline options
  // first argument is the SBML filename
  // second argument is the endtime
  // third argument is the step number
  // fourth argument is the filename where the results are to be written
  // fifth argument is the tmp directory (this is not needed)
  // the rest of the arguments are species names for the result
  try
    {
      // Create the root container.
      CCopasiRootContainer::init(0, NULL, false);
    }

  catch (copasi::autoexcept &e)
    {}

  catch (copasi::option_error &e)
    {}

  if (argc < 5)
    {
      std::cout << "Usage: batch_wrapper SBMLFILENAME STARTTIME ENDTIME STEPNUMBER OUTFILENAME" << std::endl;
      exit(1);
    }

  char* pSBMLFilename = argv[1];
  const char * pStartTime = argv[2];
  const char * pEndTime = argv[3];
  const char * pStepNumber = argv[4];
  char* pOutputFilename = argv[5];
  CTrajectoryTask* pTrajectoryTask = NULL;

  std::string CWD = COptions::getPWD();
  double startTime = strToDouble(pStartTime, NULL);
  double endTime = strToDouble(pEndTime, NULL);
  double stepNumber = strToDouble(pStepNumber, NULL);

  if (startTime < 0.0)
    {
      std::cerr << "Invalid endtime " << pEndTime << std::endl;
      exit(1);
    }

  if (endTime <= 0.0)
    {
      std::cerr << "Invalid endtime " << pEndTime << std::endl;
      exit(1);
    }

  if (stepNumber <= 0.0)
    {
      std::cerr << "Invalid step number " << pStepNumber << std::endl;
      exit(1);
    }

  try
    {
      // Create the global data model.
      CCopasiDataModel* pDataModel = CCopasiRootContainer::addDatamodel();

      // Import the SBML File
      pDataModel->importSBML(pSBMLFilename);

      // create a report with the correct filename and all the species against
      // time.
      CReportDefinitionVector* pReports = pDataModel->getReportDefinitionList();
      CReportDefinition* pReport = pReports->createReportDefinition("Report", "Output for batch run");
      pReport->setTaskType(CTaskEnum::timeCourse);
      pReport->setIsTable(false);
      pReport->setSeparator(CCopasiReportSeparator(", "));

      std::vector<CRegisteredObjectName>* pHeader = pReport->getHeaderAddr();
      std::vector<CRegisteredObjectName>* pBody = pReport->getBodyAddr();
      pBody->push_back(CCopasiObjectName(pDataModel->getModel()->getCN() + ",Reference=Time"));
      pBody->push_back(CRegisteredObjectName(pReport->getSeparator().getCN()));
      pHeader->push_back(CCopasiStaticString("time").getCN());
      pHeader->push_back(pReport->getSeparator().getCN());
      const CCopasiVectorNS<CCompartment>& compartments = pDataModel->getModel()->getCompartments();
      unsigned int j, jMax = compartments.size();
      /*
      for (j = 0; j < jMax;++j)
      {
        if(compartments[j]->getStatus()!=CModelEntity::FIXED)
        {
          pBody->push_back(compartments[j]->getObject(CCopasiObjectName("Reference=Volume"))->getCN());
          pBody->push_back(pReport->getSeparator().getCN());
          pHeader->push_back(CCopasiStaticString(compartments[j]->getSBMLId()).getCN());
          pHeader->push_back(pReport->getSeparator().getCN());
        }
      }
      */
      const CCopasiVector<CMetab>& metabolites = pDataModel->getModel()->getMetabolites();
      jMax = metabolites.size();

      for (j = 0; j < jMax; ++j)
        {
          if (metabolites[j]->getStatus() != CModelEntity::FIXED)
            {
              pBody->push_back(metabolites[j]->getObject(CCopasiObjectName("Reference=Concentration"))->getCN());
              pBody->push_back(pReport->getSeparator().getCN());
              pHeader->push_back(CCopasiStaticString(metabolites[j]->getSBMLId()).getCN());
              pHeader->push_back(pReport->getSeparator().getCN());
            }
        }

      /*
      const CCopasiVectorN<CModelValue>& parameters = pDataModel->getModel()->getModelValues();
      jMax = parameters.size();
      for (j = 0; j < jMax;++j)
      {
        if(parameters[j]->getStatus()!=CModelEntity::FIXED)
        {
          pBody->push_back(parameters[j]->getObject(CCopasiObjectName("Reference=Value"))->getCN());
          pBody->push_back(pReport->getSeparator().getCN());
          pHeader->push_back(CCopasiStaticString(parameters[j]->getSBMLId()).getCN());
          pHeader->push_back(pReport->getSeparator().getCN());
        }
      }
      const CCopasiVectorNS<CReaction>& reactions = pDataModel->getModel()->getReactions();
      jMax = reactions.size();
      for (j = 0; j < jMax;++j)
      {
        pBody->push_back(reactions[j]->getObject(CCopasiObjectName("Reference=Flux"))->getCN());
        pBody->push_back(pReport->getSeparator().getCN());
        pHeader->push_back(CCopasiStaticString(reactions[j]->getSBMLId()).getCN());
        pHeader->push_back(pReport->getSeparator().getCN());
      }
      */

      // delete the last separator
      if ((*pBody->rbegin()) == pReport->getSeparator().getCN())
        {
          pBody->erase(--pBody->end());
        }

      if ((*pHeader->rbegin()) == pReport->getSeparator().getCN())
        {
          pHeader->erase(--pHeader->end());
        }

      // create a trajectory task
      pTrajectoryTask = new CTrajectoryTask(pDataModel->getTaskList());
      // use LSODAR from now on since we will have events pretty soon
      pTrajectoryTask->setMethodType(CTaskEnum::LSODAR);
      pTrajectoryTask->getProblem()->setMathContainer(&pDataModel->getModel()->getMathContainer());

      pTrajectoryTask->setScheduled(true);

      pTrajectoryTask->getReport().setReportDefinition(pReport);
      pTrajectoryTask->getReport().setTarget(CWD + "/" + pOutputFilename);
      pTrajectoryTask->getReport().setAppend(false);

      CTrajectoryProblem* pProblem = dynamic_cast<CTrajectoryProblem*>(pTrajectoryTask->getProblem());

      pProblem->setStepNumber((const unsigned C_INT32)stepNumber);
      pDataModel->getModel()->setInitialTime((const C_FLOAT64)startTime);
      pProblem->setDuration((const C_FLOAT64)endTime - startTime);
      pProblem->setTimeSeriesRequested(true);

      CTrajectoryMethod* pMethod = dynamic_cast<CTrajectoryMethod*>(pTrajectoryTask->getMethod());

      pMethod->getParameter("Absolute Tolerance")->setValue(1.0e-12);

      CCopasiVectorN< CCopasiTask > & TaskList = * pDataModel->getTaskList();

      TaskList.remove("Time-Course");
      TaskList.add(pTrajectoryTask, true);

      // save the file for control purposes
      //std::string saveFilename = pSBMLFilename;
      //saveFilename = saveFilename.substr(0, saveFilename.length() - 4) + ".cps";
      //pDataModel->saveModel(saveFilename, NULL, true);

      // Run the trajectory task

      //pTrajectoryTask->initialize(CCopasiTask::OUTPUT_UI, NULL,NULL);
      //pTrajectoryTask->process(true);
      //pTrajectoryTask->restore();

      // create another report that will write to the directory where the input file came from
      // this can be used for debugging
      // create a trajectory task
      pTrajectoryTask->getReport().setTarget(pOutputFilename);

      pTrajectoryTask->initialize(CCopasiTask::OUTPUT_UI, pDataModel, NULL);
      pTrajectoryTask->process(true);
      pTrajectoryTask->restore();
    }
  catch (CCopasiException Exception)
    {
      std::cerr << Exception.getMessage().getText() << std::endl;
    }

  std::string Text = "";

  while (CCopasiMessage::size() > 0)
    {
      const CCopasiMessage& message = CCopasiMessage::getLastMessage();

      if (message.getType() < CCopasiMessage::RAW_FILTERED)
        {
          if (Text != "") Text += "\n";

          Text += message.getText();
        }
    }

  if (Text != "") std::cerr << Text << std::endl;

  CCopasiRootContainer::destroy();

  return 0;
}
<commit_msg>- more compile errors<commit_after>// Copyright (C) 2010 - 2016 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

// Copyright (C) 2008 - 2009 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., EML Research, gGmbH, University of Heidelberg,
// and The University of Manchester.
// All rights reserved.

#define COPASI_MAIN

#include <iostream>
#include <stdlib.h>

#include "copasi/copasi.h"
#include "copasi/CopasiDataModel/CCopasiDataModel.h"
#include "copasi/report/CCopasiRootContainer.h"
#include "copasi/model/CMetab.h"
#include "copasi/report/CCopasiObjectName.h"
#include "copasi/utilities/CCopasiVector.h"
#include "copasi/model/CModel.h"
#include "copasi/utilities/CCopasiException.h"
#include "copasi/commandline/COptionParser.h"
#include "copasi/commandline/COptions.h"

#include "copasi/trajectory/CTrajectoryTask.h"
#include "copasi/trajectory/CTrajectoryMethod.h"
#include "copasi/trajectory/CTrajectoryProblem.h"
#include "copasi/report/CReportDefinitionVector.h"
#include "copasi/report/CReportDefinition.h"

int main(int argc, char *argv[])
{
  // Parse the commandline options
  // first argument is the SBML filename
  // second argument is the endtime
  // third argument is the step number
  // fourth argument is the filename where the results are to be written
  // fifth argument is the tmp directory (this is not needed)
  // the rest of the arguments are species names for the result
  try
    {
      // Create the root container.
      CCopasiRootContainer::init(0, NULL, false);
    }

  catch (copasi::autoexcept &e)
    {}

  catch (copasi::option_error &e)
    {}

  if (argc < 5)
    {
      std::cout << "Usage: batch_wrapper SBMLFILENAME STARTTIME ENDTIME STEPNUMBER OUTFILENAME" << std::endl;
      exit(1);
    }

  char* pSBMLFilename = argv[1];
  const char * pStartTime = argv[2];
  const char * pEndTime = argv[3];
  const char * pStepNumber = argv[4];
  char* pOutputFilename = argv[5];
  CTrajectoryTask* pTrajectoryTask = NULL;

  std::string CWD = COptions::getPWD();
  double startTime = strToDouble(pStartTime, NULL);
  double endTime = strToDouble(pEndTime, NULL);
  double stepNumber = strToDouble(pStepNumber, NULL);

  if (startTime < 0.0)
    {
      std::cerr << "Invalid endtime " << pEndTime << std::endl;
      exit(1);
    }

  if (endTime <= 0.0)
    {
      std::cerr << "Invalid endtime " << pEndTime << std::endl;
      exit(1);
    }

  if (stepNumber <= 0.0)
    {
      std::cerr << "Invalid step number " << pStepNumber << std::endl;
      exit(1);
    }

  try
    {
      // Create the global data model.
      CCopasiDataModel* pDataModel = CCopasiRootContainer::addDatamodel();

      // Import the SBML File
      pDataModel->importSBML(pSBMLFilename);

      // create a report with the correct filename and all the species against
      // time.
      CReportDefinitionVector* pReports = pDataModel->getReportDefinitionList();
      CReportDefinition* pReport = pReports->createReportDefinition("Report", "Output for batch run");
      pReport->setTaskType(CTaskEnum::timeCourse);
      pReport->setIsTable(false);
      pReport->setSeparator(CCopasiReportSeparator(", "));

      std::vector<CRegisteredObjectName>* pHeader = pReport->getHeaderAddr();
      std::vector<CRegisteredObjectName>* pBody = pReport->getBodyAddr();
      pBody->push_back(CCopasiObjectName(pDataModel->getModel()->getCN() + ",Reference=Time"));
      pBody->push_back(CRegisteredObjectName(pReport->getSeparator().getCN()));
      pHeader->push_back(CCopasiStaticString("time").getCN());
      pHeader->push_back(pReport->getSeparator().getCN());
      const CCopasiVectorNS<CCompartment>& compartments = pDataModel->getModel()->getCompartments();
      unsigned int j, jMax = compartments.size();
      /*
      for (j = 0; j < jMax;++j)
      {
        if(compartments[j]->getStatus()!=CModelEntity::FIXED)
        {
          pBody->push_back(compartments[j]->getObject(CCopasiObjectName("Reference=Volume"))->getCN());
          pBody->push_back(pReport->getSeparator().getCN());
          pHeader->push_back(CCopasiStaticString(compartments[j]->getSBMLId()).getCN());
          pHeader->push_back(pReport->getSeparator().getCN());
        }
      }
      */
      const CCopasiVector<CMetab>& metabolites = pDataModel->getModel()->getMetabolites();
      jMax = metabolites.size();

      for (j = 0; j < jMax; ++j)
        {
          if (metabolites[j].getStatus() != CModelEntity::FIXED)
            {
              pBody->push_back(metabolites[j].getObject(CCopasiObjectName("Reference=Concentration"))->getCN());
              pBody->push_back(pReport->getSeparator().getCN());
              pHeader->push_back(CCopasiStaticString(metabolites[j].getSBMLId()).getCN());
              pHeader->push_back(pReport->getSeparator().getCN());
            }
        }

      /*
      const CCopasiVectorN<CModelValue>& parameters = pDataModel->getModel()->getModelValues();
      jMax = parameters.size();
      for (j = 0; j < jMax;++j)
      {
        if(parameters[j]->getStatus()!=CModelEntity::FIXED)
        {
          pBody->push_back(parameters[j]->getObject(CCopasiObjectName("Reference=Value"))->getCN());
          pBody->push_back(pReport->getSeparator().getCN());
          pHeader->push_back(CCopasiStaticString(parameters[j]->getSBMLId()).getCN());
          pHeader->push_back(pReport->getSeparator().getCN());
        }
      }
      const CCopasiVectorNS<CReaction>& reactions = pDataModel->getModel()->getReactions();
      jMax = reactions.size();
      for (j = 0; j < jMax;++j)
      {
        pBody->push_back(reactions[j]->getObject(CCopasiObjectName("Reference=Flux"))->getCN());
        pBody->push_back(pReport->getSeparator().getCN());
        pHeader->push_back(CCopasiStaticString(reactions[j]->getSBMLId()).getCN());
        pHeader->push_back(pReport->getSeparator().getCN());
      }
      */

      // delete the last separator
      if ((*pBody->rbegin()) == pReport->getSeparator().getCN())
        {
          pBody->erase(--pBody->end());
        }

      if ((*pHeader->rbegin()) == pReport->getSeparator().getCN())
        {
          pHeader->erase(--pHeader->end());
        }

      // create a trajectory task
      pTrajectoryTask = new CTrajectoryTask(pDataModel->getTaskList());
      // use LSODAR from now on since we will have events pretty soon
      pTrajectoryTask->setMethodType(CTaskEnum::LSODAR);
      pTrajectoryTask->getProblem()->setMathContainer(&pDataModel->getModel()->getMathContainer());

      pTrajectoryTask->setScheduled(true);

      pTrajectoryTask->getReport().setReportDefinition(pReport);
      pTrajectoryTask->getReport().setTarget(CWD + "/" + pOutputFilename);
      pTrajectoryTask->getReport().setAppend(false);

      CTrajectoryProblem* pProblem = dynamic_cast<CTrajectoryProblem*>(pTrajectoryTask->getProblem());

      pProblem->setStepNumber((const unsigned C_INT32)stepNumber);
      pDataModel->getModel()->setInitialTime((const C_FLOAT64)startTime);
      pProblem->setDuration((const C_FLOAT64)endTime - startTime);
      pProblem->setTimeSeriesRequested(true);

      CTrajectoryMethod* pMethod = dynamic_cast<CTrajectoryMethod*>(pTrajectoryTask->getMethod());

      pMethod->getParameter("Absolute Tolerance")->setValue(1.0e-12);

      CCopasiVectorN< CCopasiTask > & TaskList = * pDataModel->getTaskList();

      TaskList.remove("Time-Course");
      TaskList.add(pTrajectoryTask, true);

      // save the file for control purposes
      //std::string saveFilename = pSBMLFilename;
      //saveFilename = saveFilename.substr(0, saveFilename.length() - 4) + ".cps";
      //pDataModel->saveModel(saveFilename, NULL, true);

      // Run the trajectory task

      //pTrajectoryTask->initialize(CCopasiTask::OUTPUT_UI, NULL,NULL);
      //pTrajectoryTask->process(true);
      //pTrajectoryTask->restore();

      // create another report that will write to the directory where the input file came from
      // this can be used for debugging
      // create a trajectory task
      pTrajectoryTask->getReport().setTarget(pOutputFilename);

      pTrajectoryTask->initialize(CCopasiTask::OUTPUT_UI, pDataModel, NULL);
      pTrajectoryTask->process(true);
      pTrajectoryTask->restore();
    }
  catch (CCopasiException Exception)
    {
      std::cerr << Exception.getMessage().getText() << std::endl;
    }

  std::string Text = "";

  while (CCopasiMessage::size() > 0)
    {
      const CCopasiMessage& message = CCopasiMessage::getLastMessage();

      if (message.getType() < CCopasiMessage::RAW_FILTERED)
        {
          if (Text != "") Text += "\n";

          Text += message.getText();
        }
    }

  if (Text != "") std::cerr << Text << std::endl;

  CCopasiRootContainer::destroy();

  return 0;
}
<|endoftext|>