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

  Program:   Visualization Toolkit
  Module:    vtkScalarsToColors.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-2001 Ken Martin, Will Schroeder, Bill Lorensen
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 name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

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 AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/
#include <math.h>
#include "vtkScalarsToColors.h"
#include "vtkScalars.h"

// do not use SetMacro() because we do not the table to rebuild.
void vtkScalarsToColors::SetAlpha(float alpha)
{
  this->Alpha = (alpha < 0.0 ? 0.0 : (alpha > 1.0 ? 1.0 : alpha));
}

vtkUnsignedCharArray *vtkScalarsToColors::MapScalars(vtkDataArray *scalars,
                                                     int colorMode, int comp)
{
  vtkUnsignedCharArray *newColors;
  vtkUnsignedCharArray *colors;

  // map scalars through lookup table only if needed
  if ( colorMode == VTK_COLOR_MODE_DEFAULT &&
       (colors=vtkUnsignedCharArray::SafeDownCast(scalars)) != NULL )
    {
    newColors = this->
      ConvertUnsignedCharToRGBA(colors, colors->GetNumberOfComponents(),
                                scalars->GetNumberOfTuples());
    }
  else
    {
    newColors = vtkUnsignedCharArray::New();
    newColors->SetNumberOfComponents(4);
    newColors->SetNumberOfTuples(scalars->GetNumberOfTuples());
    newColors->Register(this);
    this->
      MapScalarsThroughTable2(scalars->GetVoidPointer(comp),
                              newColors->GetPointer(0),
                              scalars->GetDataType(),
                              scalars->GetNumberOfTuples(),
                              scalars->GetNumberOfComponents(),
                              VTK_RGBA);
    }//need to map

  return newColors;
}

// Map a set of scalar values through the table
void vtkScalarsToColors::MapScalarsThroughTable(vtkScalars *scalars,
                                                unsigned char *output,
						int outputFormat)
{
  switch (outputFormat)
    {
    case VTK_RGBA:
    case VTK_RGB:
    case VTK_LUMINANCE_ALPHA:
    case VTK_LUMINANCE:
      break;
    default:
      vtkErrorMacro(<< "MapScalarsThroughTable: unrecognized color format");
      break;
    }

  this->MapScalarsThroughTable2(scalars->GetVoidPointer(0),
				output,
				scalars->GetDataType(),
				scalars->GetNumberOfScalars(),
				scalars->GetNumberOfComponents(),
				outputFormat);
}

vtkUnsignedCharArray *vtkScalarsToColors::ConvertUnsignedCharToRGBA(
  vtkUnsignedCharArray *colors, int numComp, int numTuples)
{
  unsigned char *cptr = colors->GetPointer(0);
  vtkUnsignedCharArray *newColors = vtkUnsignedCharArray::New();

  if ( numComp == 4 && this->Alpha >= 1.0 )
    {
    newColors->SetArray(cptr, numTuples, 0);
    return newColors;
    }

  newColors->SetNumberOfComponents(4);
  newColors->SetNumberOfTuples(numTuples);
  unsigned char *nptr = newColors->GetPointer(0);
  int i;

  if ( this->Alpha >= 1.0 )
    {
    switch (numComp)
      {
      case 1:
        for (i=0; i<numTuples; i++)
          {
          *nptr++ = *cptr;
          *nptr++ = *cptr;
          *nptr++ = *cptr++;
          *nptr++ = 255;
          }
        break;

      case 2:
        for (i=0; i<numTuples; i++)
          {
          *nptr++ = *cptr;
          *nptr++ = *cptr;
          *nptr++ = *cptr++;
          *nptr++ = *cptr++;
          }
        break;

      case 3:
        for (i=0; i<numTuples; i++)
          {
          *nptr++ = *cptr++;
          *nptr++ = *cptr++;
          *nptr++ = *cptr++;
          *nptr++ = 255;
          }
        break;

      default:
        vtkErrorMacro(<<"Cannot convert colors");
        return NULL;
      }
    }
  else //blending required
    {
    unsigned char alpha;
    switch (numComp)
      {
      case 1:
        alpha = this->Alpha*255;
        for (i=0; i<numTuples; i++)
          {
          *nptr++ = *cptr;
          *nptr++ = *cptr;
          *nptr++ = *cptr++;
          *nptr++ = alpha;
          }
        break;

      case 2:
        for (i=0; i<numTuples; i++)
          {
          *nptr++ = *cptr;
          *nptr++ = *cptr;
          *nptr++ = *cptr++;
          *nptr++ = (*cptr)*this->Alpha; cptr++;
          }
        break;

      case 3:
        alpha = this->Alpha*255;
        for (i=0; i<numTuples; i++)
          {
          *nptr++ = *cptr++;
          *nptr++ = *cptr++;
          *nptr++ = *cptr++;
          *nptr++ = alpha;
          }
        break;

      case 4:
        for (i=0; i<numTuples; i++)
          {
          *nptr++ = *cptr++;
          *nptr++ = *cptr++;
          *nptr++ = *cptr++;
          *nptr++ = (*cptr)*this->Alpha; cptr++;
          }
        break;

      default:
        vtkErrorMacro(<<"Cannot convert colors");
        return NULL;
      }
    }

  return newColors;
}

<commit_msg>ERR:Fixed memory leak<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkScalarsToColors.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-2001 Ken Martin, Will Schroeder, Bill Lorensen
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 name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

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 AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/
#include <math.h>
#include "vtkScalarsToColors.h"
#include "vtkScalars.h"

// do not use SetMacro() because we do not the table to rebuild.
void vtkScalarsToColors::SetAlpha(float alpha)
{
  this->Alpha = (alpha < 0.0 ? 0.0 : (alpha > 1.0 ? 1.0 : alpha));
}

vtkUnsignedCharArray *vtkScalarsToColors::MapScalars(vtkDataArray *scalars,
                                                     int colorMode, int comp)
{
  vtkUnsignedCharArray *newColors;
  vtkUnsignedCharArray *colors;

  // map scalars through lookup table only if needed
  if ( colorMode == VTK_COLOR_MODE_DEFAULT &&
       (colors=vtkUnsignedCharArray::SafeDownCast(scalars)) != NULL )
    {
    newColors = this->
      ConvertUnsignedCharToRGBA(colors, colors->GetNumberOfComponents(),
                                scalars->GetNumberOfTuples());
    }
  else
    {
    newColors = vtkUnsignedCharArray::New();
    newColors->SetNumberOfComponents(4);
    newColors->SetNumberOfTuples(scalars->GetNumberOfTuples());
    this->
      MapScalarsThroughTable2(scalars->GetVoidPointer(comp),
                              newColors->GetPointer(0),
                              scalars->GetDataType(),
                              scalars->GetNumberOfTuples(),
                              scalars->GetNumberOfComponents(),
                              VTK_RGBA);
    }//need to map

  return newColors;
}

// Map a set of scalar values through the table
void vtkScalarsToColors::MapScalarsThroughTable(vtkScalars *scalars,
                                                unsigned char *output,
						int outputFormat)
{
  switch (outputFormat)
    {
    case VTK_RGBA:
    case VTK_RGB:
    case VTK_LUMINANCE_ALPHA:
    case VTK_LUMINANCE:
      break;
    default:
      vtkErrorMacro(<< "MapScalarsThroughTable: unrecognized color format");
      break;
    }

  this->MapScalarsThroughTable2(scalars->GetVoidPointer(0),
				output,
				scalars->GetDataType(),
				scalars->GetNumberOfScalars(),
				scalars->GetNumberOfComponents(),
				outputFormat);
}

vtkUnsignedCharArray *vtkScalarsToColors::ConvertUnsignedCharToRGBA(
  vtkUnsignedCharArray *colors, int numComp, int numTuples)
{
  unsigned char *cptr = colors->GetPointer(0);
  vtkUnsignedCharArray *newColors = vtkUnsignedCharArray::New();

  if ( numComp == 4 && this->Alpha >= 1.0 )
    {
    newColors->SetArray(cptr, numTuples, 0);
    return newColors;
    }

  newColors->SetNumberOfComponents(4);
  newColors->SetNumberOfTuples(numTuples);
  unsigned char *nptr = newColors->GetPointer(0);
  int i;

  if ( this->Alpha >= 1.0 )
    {
    switch (numComp)
      {
      case 1:
        for (i=0; i<numTuples; i++)
          {
          *nptr++ = *cptr;
          *nptr++ = *cptr;
          *nptr++ = *cptr++;
          *nptr++ = 255;
          }
        break;

      case 2:
        for (i=0; i<numTuples; i++)
          {
          *nptr++ = *cptr;
          *nptr++ = *cptr;
          *nptr++ = *cptr++;
          *nptr++ = *cptr++;
          }
        break;

      case 3:
        for (i=0; i<numTuples; i++)
          {
          *nptr++ = *cptr++;
          *nptr++ = *cptr++;
          *nptr++ = *cptr++;
          *nptr++ = 255;
          }
        break;

      default:
        vtkErrorMacro(<<"Cannot convert colors");
        return NULL;
      }
    }
  else //blending required
    {
    unsigned char alpha;
    switch (numComp)
      {
      case 1:
        alpha = this->Alpha*255;
        for (i=0; i<numTuples; i++)
          {
          *nptr++ = *cptr;
          *nptr++ = *cptr;
          *nptr++ = *cptr++;
          *nptr++ = alpha;
          }
        break;

      case 2:
        for (i=0; i<numTuples; i++)
          {
          *nptr++ = *cptr;
          *nptr++ = *cptr;
          *nptr++ = *cptr++;
          *nptr++ = (*cptr)*this->Alpha; cptr++;
          }
        break;

      case 3:
        alpha = this->Alpha*255;
        for (i=0; i<numTuples; i++)
          {
          *nptr++ = *cptr++;
          *nptr++ = *cptr++;
          *nptr++ = *cptr++;
          *nptr++ = alpha;
          }
        break;

      case 4:
        for (i=0; i<numTuples; i++)
          {
          *nptr++ = *cptr++;
          *nptr++ = *cptr++;
          *nptr++ = *cptr++;
          *nptr++ = (*cptr)*this->Alpha; cptr++;
          }
        break;

      default:
        vtkErrorMacro(<<"Cannot convert colors");
        return NULL;
      }
    }

  return newColors;
}

<|endoftext|>


<commit_before>/**
 * @file HOGDescriptor_.cpp
 * @brief mex interface for HOGDescriptor
 * @author Kota Yamaguchi
 * @date 2012
 */
#include "mexopencv.hpp"
using namespace std;
using namespace cv;

namespace {
/// Last object id to allocate
int last_id = 0;
/// Object container
map<int,HOGDescriptor> obj_;

/** HistogramNormType map
 */
const ConstMap<std::string,int> HistogramNormType = ConstMap<std::string,int>
    ("L2Hys",HOGDescriptor::L2Hys);
/** HistogramNormType inverse map
 */
const ConstMap<int,std::string> InvHistogramNormType = ConstMap<int,std::string>
    (HOGDescriptor::L2Hys,"L2Hys");

/// Alias for argument number check
inline void nargchk(bool cond)
{
    if (!cond)
        mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");
}

}

/**
 * Main entry called from Matlab
 * @param nlhs number of left-hand-side arguments
 * @param plhs pointers to mxArrays in the left-hand-side
 * @param nrhs number of right-hand-side arguments
 * @param prhs pointers to mxArrays in the right-hand-side
 */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{
    nargchk(nrhs>=2 && nlhs<=2);
    vector<MxArray> rhs(prhs,prhs+nrhs);
    int id = rhs[0].toInt();
    string method(rhs[1].toString());

    // Constructor call
    if (method == "new") {
        nargchk(nlhs<=1);
        if (nrhs==3 && rhs[2].isChar())
            obj_[++last_id] = HOGDescriptor(rhs[2].toString());
        else {
            nargchk((nrhs%2)==0);
            obj_[++last_id] = HOGDescriptor();
            HOGDescriptor& obj = obj_[last_id];
            for (int i=2; i<nrhs; i+=2) {
                string key(rhs[i].toString());
                if (key == "WinSize")
                    obj.winSize = rhs[i+1].toSize();
                else if (key == "BlockSize")
                    obj.blockSize = rhs[i+1].toSize();
                else if (key == "BlockStride")
                    obj.blockStride = rhs[i+1].toSize();
                else if (key == "CellSize")
                    obj.cellSize = rhs[i+1].toSize();
                else if (key == "NBins")
                    obj.nbins = rhs[i+1].toInt();
                else if (key == "DerivAperture")
                    obj.derivAperture = rhs[i+1].toInt();
                else if (key == "WinSigma")
                    obj.winSigma = rhs[i+1].toDouble();
                else if (key == "HistogramNormType")
                    obj.histogramNormType = HistogramNormType[rhs[i+1].toString()];
                else if (key == "L2HysThreshold")
                    obj.L2HysThreshold = rhs[i+1].toDouble();
                else if (key == "GammaCorrection")
                    obj.gammaCorrection = rhs[i+1].toBool();
                else if (key == "NLevels")
                    obj.nlevels = rhs[i+1].toInt();
                else
                    mexErrMsgIdAndTxt("mexopencv:error","Unknown option %s",key.c_str());
            }
        }
        plhs[0] = MxArray(last_id);
        return;
    }

    // Big operation switch
    HOGDescriptor& obj = obj_[id];
    if (method == "delete") {
        nargchk(nrhs==2 && nlhs==0);
        obj_.erase(id);
    }
    else if (method == "getDescriptorSize") {
        nargchk(nrhs==2 && nlhs<=1);
        plhs[0] = MxArray(static_cast<int>(obj.getDescriptorSize()));
    }
    else if (method == "checkDetectorSize") {
        nargchk(nrhs==2 && nlhs<=1);
        plhs[0] = MxArray(obj.checkDetectorSize());
    }
    else if (method == "getWinSigma") {
        nargchk(nrhs==2 && nlhs<=1);
        plhs[0] = MxArray(obj.getWinSigma());
    }
    else if (method == "setSVMDetector") {
        nargchk(nrhs==3 && nlhs==0);
        if (rhs[2].isChar()) {
            string key(rhs[2].toString());
            if (key=="Default")
                obj.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
            else if (key=="Daimler")
                obj.setSVMDetector(HOGDescriptor::getDaimlerPeopleDetector());
            else
                mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option %s", key.c_str());
        }
        else
            obj.setSVMDetector(rhs[2].toVector<float>());
    }
    else if (method == "load") {
        nargchk(nrhs==3 && nlhs<=1);
        plhs[0] = MxArray(obj.load(rhs[2].toString()));
    }
    else if (method == "save") {
        nargchk(nrhs==3 && nlhs==0);
        obj.save(rhs[2].toString());
    }
    else if (method == "compute") {
        nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=1);

        Mat img(rhs[2].isUint8() ? rhs[2].toMat() : rhs[2].toMat(CV_32F));
        Size winStride;
        Size padding;
        vector<Point> locations;
        for (int i=3; i<nrhs; i+=2) {
            string key = rhs[i].toString();
            if (key=="WinStride")
                winStride = rhs[i+1].toSize();
            else if (key=="Padding")
                padding = rhs[i+1].toSize();
            else if (key=="Locations")
                locations = rhs[i+1].toVector<Point>();
            else
                mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option %s", key.c_str());
        }

        // Run
        vector<float> descriptors;
        obj.compute(img,descriptors,winStride,padding,locations);
        Mat m(descriptors);
        plhs[0] = MxArray(m.reshape(0,m.total()/obj.getDescriptorSize()));
    }
    else if (method == "detect") {
        nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=2);

        Mat img(rhs[2].isUint8() ? rhs[2].toMat() : rhs[2].toMat(CV_32F));
        double hitThreshold=0;
        Size winStride;
        Size padding;
        vector<Point> searchLocations;
        for (int i=3; i<nrhs; i+=2) {
            string key = rhs[i].toString();
            if (key=="HitThreshold")
                hitThreshold = rhs[i+1].toDouble();
            else if (key=="WinStride")
                winStride = rhs[i+1].toSize();
            else if (key=="Padding")
                padding = rhs[i+1].toSize();
            else if (key=="Locations")
                searchLocations = rhs[i+1].toVector<Point>();
            else
                mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option %s", key.c_str());
        }

        // Run
        vector<Point> foundLocations;
        vector<double> weights;
        obj.detect(img, foundLocations, hitThreshold, winStride,
            padding, searchLocations);
        plhs[0] = MxArray(foundLocations);
        if (nlhs>1)
            plhs[1] = MxArray(Mat(weights));
    }
    else if (method == "detectMultiScale") {
        nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=2);

        Mat img(rhs[2].isUint8() ? rhs[2].toMat() : rhs[2].toMat(CV_32F));
        double hitThreshold=0;
        Size winStride;
        Size padding;
        double scale=1.05;
        double finalThreshold=2.0;
        bool useMeanshiftGrouping = false;
        for (int i=3; i<nrhs; i+=2) {
            string key = rhs[i].toString();
            if (key=="HitThreshold")
                hitThreshold = rhs[i+1].toDouble();
            else if (key=="WinStride")
                winStride = rhs[i+1].toSize();
            else if (key=="Padding")
                padding = rhs[i+1].toSize();
            else if (key=="Scale")
                scale = rhs[i+1].toDouble();
            else if (key=="FinalThreshold")
                finalThreshold = rhs[i+1].toDouble();
            else if (key=="UseMeanshiftGrouping")
                useMeanshiftGrouping = rhs[i+1].toBool();
            else
                mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option %s", key.c_str());
        }

        // Run
        vector<Rect> foundLocations;
        vector<double> weights;
        obj.detectMultiScale(img, foundLocations, weights, hitThreshold, winStride,
            padding, scale, finalThreshold, useMeanshiftGrouping);
        plhs[0] = MxArray(foundLocations);
        if (nlhs>1)
            plhs[1] = MxArray(Mat(weights));
    }
    else if (method == "computeGradient") {
        nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=2);

        Mat img(rhs[2].isUint8() ? rhs[2].toMat() : rhs[2].toMat(CV_32F));
        Size paddingTL;
        Size paddingBR;
        for (int i=3; i<nrhs; i+=2) {
            string key = rhs[i].toString();
            if (key=="PaddingTR")
                paddingTL = rhs[i+1].toSize();
            else if (key=="PaddingBR")
                paddingBR = rhs[i+1].toSize();
            else
                mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option %s", key.c_str());
        }

        // Run
        Mat grad, angleOfs;
        obj.computeGradient(img,grad,angleOfs,paddingTL,paddingBR);
        plhs[0] = MxArray(grad);
        if (nlhs>1)
            plhs[1] = MxArray(angleOfs);
    }
    else if (method == "winSize") {
        if (nlhs==1 && nrhs==2)
            plhs[0] = MxArray(obj.winSize);
        else if (nlhs==0 && nrhs==3)
            obj.winSize = rhs[2].toSize();
        else
            nargchk(false);
    }
    else if (method == "blockSize") {
        if (nlhs==1 && nrhs==2)
            plhs[0] = MxArray(obj.blockSize);
        else if (nlhs==0 && nrhs==3)
            obj.blockSize = rhs[2].toSize();
        else
            nargchk(false);
    }
    else if (method == "blockStride") {
        if (nlhs==1 && nrhs==2)
            plhs[0] = MxArray(obj.blockStride);
        else if (nlhs==0 && nrhs==3)
            obj.blockStride = rhs[2].toSize();
        else
            nargchk(false);
    }
    else if (method == "cellSize") {
        if (nlhs==1 && nrhs==2)
            plhs[0] = MxArray(obj.cellSize);
        else if (nlhs==0 && nrhs==3)
            obj.cellSize = rhs[2].toSize();
        else
            nargchk(false);
    }
    else if (method == "nbins") {
        if (nlhs==1 && nrhs==2)
            plhs[0] = MxArray(obj.nbins);
        else if (nlhs==0 && nrhs==3)
            obj.nbins = rhs[2].toInt();
        else
            nargchk(false);
    }
    else if (method == "derivAperture") {
        if (nlhs==1 && nrhs==2)
            plhs[0] = MxArray(obj.derivAperture);
        else if (nlhs==0 && nrhs==3)
            obj.derivAperture = rhs[2].toInt();
        else
            nargchk(false);
    }
    else if (method == "winSigma") {
        if (nlhs==1 && nrhs==2)
            plhs[0] = MxArray(obj.winSigma);
        else if (nlhs==0 && nrhs==3)
            obj.winSigma = rhs[2].toDouble();
        else
            nargchk(false);
    }
    else if (method == "histogramNormType") {
        if (nlhs==1 && nrhs==2)
            plhs[0] = MxArray(InvHistogramNormType[obj.histogramNormType]);
        else if (nlhs==0 && nrhs==3)
            obj.histogramNormType = HistogramNormType[rhs[2].toString()];
        else
            nargchk(false);
    }
    else if (method == "L2HysThreshold") {
        if (nlhs==1 && nrhs==2)
            plhs[0] = MxArray(obj.L2HysThreshold);
        else if (nlhs==0 && nrhs==3)
            obj.L2HysThreshold = rhs[2].toDouble();
        else
            nargchk(false);
    }
    else if (method == "gammaCorrection") {
        if (nlhs==1 && nrhs==2)
            plhs[0] = MxArray(obj.gammaCorrection);
        else if (nlhs==0 && nrhs==3)
            obj.gammaCorrection = rhs[2].toBool();
        else
            nargchk(false);
    }
    else if (method == "nlevels") {
        if (nlhs==1 && nrhs==2)
            plhs[0] = MxArray(obj.nlevels);
        else if (nlhs==0 && nrhs==3)
            obj.nlevels = rhs[2].toInt();
        else
            nargchk(false);
    }
    else
        mexErrMsgIdAndTxt("mexopencv:error","Unrecognized operation %s", method.c_str());
}
<commit_msg>missing weights argument in detect function<commit_after>/**
 * @file HOGDescriptor_.cpp
 * @brief mex interface for HOGDescriptor
 * @author Kota Yamaguchi
 * @date 2012
 */
#include "mexopencv.hpp"
using namespace std;
using namespace cv;

namespace {
/// Last object id to allocate
int last_id = 0;
/// Object container
map<int,HOGDescriptor> obj_;

/** HistogramNormType map
 */
const ConstMap<std::string,int> HistogramNormType = ConstMap<std::string,int>
    ("L2Hys",HOGDescriptor::L2Hys);
/** HistogramNormType inverse map
 */
const ConstMap<int,std::string> InvHistogramNormType = ConstMap<int,std::string>
    (HOGDescriptor::L2Hys,"L2Hys");

/// Alias for argument number check
inline void nargchk(bool cond)
{
    if (!cond)
        mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");
}

}

/**
 * Main entry called from Matlab
 * @param nlhs number of left-hand-side arguments
 * @param plhs pointers to mxArrays in the left-hand-side
 * @param nrhs number of right-hand-side arguments
 * @param prhs pointers to mxArrays in the right-hand-side
 */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{
    nargchk(nrhs>=2 && nlhs<=2);
    vector<MxArray> rhs(prhs,prhs+nrhs);
    int id = rhs[0].toInt();
    string method(rhs[1].toString());

    // Constructor call
    if (method == "new") {
        nargchk(nlhs<=1);
        if (nrhs==3 && rhs[2].isChar())
            obj_[++last_id] = HOGDescriptor(rhs[2].toString());
        else {
            nargchk((nrhs%2)==0);
            obj_[++last_id] = HOGDescriptor();
            HOGDescriptor& obj = obj_[last_id];
            for (int i=2; i<nrhs; i+=2) {
                string key(rhs[i].toString());
                if (key == "WinSize")
                    obj.winSize = rhs[i+1].toSize();
                else if (key == "BlockSize")
                    obj.blockSize = rhs[i+1].toSize();
                else if (key == "BlockStride")
                    obj.blockStride = rhs[i+1].toSize();
                else if (key == "CellSize")
                    obj.cellSize = rhs[i+1].toSize();
                else if (key == "NBins")
                    obj.nbins = rhs[i+1].toInt();
                else if (key == "DerivAperture")
                    obj.derivAperture = rhs[i+1].toInt();
                else if (key == "WinSigma")
                    obj.winSigma = rhs[i+1].toDouble();
                else if (key == "HistogramNormType")
                    obj.histogramNormType = HistogramNormType[rhs[i+1].toString()];
                else if (key == "L2HysThreshold")
                    obj.L2HysThreshold = rhs[i+1].toDouble();
                else if (key == "GammaCorrection")
                    obj.gammaCorrection = rhs[i+1].toBool();
                else if (key == "NLevels")
                    obj.nlevels = rhs[i+1].toInt();
                else
                    mexErrMsgIdAndTxt("mexopencv:error","Unknown option %s",key.c_str());
            }
        }
        plhs[0] = MxArray(last_id);
        return;
    }

    // Big operation switch
    HOGDescriptor& obj = obj_[id];
    if (method == "delete") {
        nargchk(nrhs==2 && nlhs==0);
        obj_.erase(id);
    }
    else if (method == "getDescriptorSize") {
        nargchk(nrhs==2 && nlhs<=1);
        plhs[0] = MxArray(static_cast<int>(obj.getDescriptorSize()));
    }
    else if (method == "checkDetectorSize") {
        nargchk(nrhs==2 && nlhs<=1);
        plhs[0] = MxArray(obj.checkDetectorSize());
    }
    else if (method == "getWinSigma") {
        nargchk(nrhs==2 && nlhs<=1);
        plhs[0] = MxArray(obj.getWinSigma());
    }
    else if (method == "setSVMDetector") {
        nargchk(nrhs==3 && nlhs==0);
        if (rhs[2].isChar()) {
            string key(rhs[2].toString());
            if (key=="Default")
                obj.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
            else if (key=="Daimler")
                obj.setSVMDetector(HOGDescriptor::getDaimlerPeopleDetector());
            else
                mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option %s", key.c_str());
        }
        else
            obj.setSVMDetector(rhs[2].toVector<float>());
    }
    else if (method == "load") {
        nargchk(nrhs==3 && nlhs<=1);
        plhs[0] = MxArray(obj.load(rhs[2].toString()));
    }
    else if (method == "save") {
        nargchk(nrhs==3 && nlhs==0);
        obj.save(rhs[2].toString());
    }
    else if (method == "compute") {
        nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=1);

        Mat img(rhs[2].isUint8() ? rhs[2].toMat() : rhs[2].toMat(CV_32F));
        Size winStride;
        Size padding;
        vector<Point> locations;
        for (int i=3; i<nrhs; i+=2) {
            string key = rhs[i].toString();
            if (key=="WinStride")
                winStride = rhs[i+1].toSize();
            else if (key=="Padding")
                padding = rhs[i+1].toSize();
            else if (key=="Locations")
                locations = rhs[i+1].toVector<Point>();
            else
                mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option %s", key.c_str());
        }

        // Run
        vector<float> descriptors;
        obj.compute(img,descriptors,winStride,padding,locations);
        Mat m(descriptors);
        plhs[0] = MxArray(m.reshape(0,m.total()/obj.getDescriptorSize()));
    }
    else if (method == "detect") {
        nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=2);

        Mat img(rhs[2].isUint8() ? rhs[2].toMat() : rhs[2].toMat(CV_32F));
        double hitThreshold=0;
        Size winStride;
        Size padding;
        vector<Point> searchLocations;
        for (int i=3; i<nrhs; i+=2) {
            string key = rhs[i].toString();
            if (key=="HitThreshold")
                hitThreshold = rhs[i+1].toDouble();
            else if (key=="WinStride")
                winStride = rhs[i+1].toSize();
            else if (key=="Padding")
                padding = rhs[i+1].toSize();
            else if (key=="Locations")
                searchLocations = rhs[i+1].toVector<Point>();
            else
                mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option %s", key.c_str());
        }

        // Run
        vector<Point> foundLocations;
        vector<double> weights;
        obj.detect(img, foundLocations, weights, hitThreshold, winStride,
            padding, searchLocations);
        plhs[0] = MxArray(foundLocations);
        if (nlhs>1)
            plhs[1] = MxArray(Mat(weights));
    }
    else if (method == "detectMultiScale") {
        nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=2);

        Mat img(rhs[2].isUint8() ? rhs[2].toMat() : rhs[2].toMat(CV_32F));
        double hitThreshold=0;
        Size winStride;
        Size padding;
        double scale=1.05;
        double finalThreshold=2.0;
        bool useMeanshiftGrouping = false;
        for (int i=3; i<nrhs; i+=2) {
            string key = rhs[i].toString();
            if (key=="HitThreshold")
                hitThreshold = rhs[i+1].toDouble();
            else if (key=="WinStride")
                winStride = rhs[i+1].toSize();
            else if (key=="Padding")
                padding = rhs[i+1].toSize();
            else if (key=="Scale")
                scale = rhs[i+1].toDouble();
            else if (key=="FinalThreshold")
                finalThreshold = rhs[i+1].toDouble();
            else if (key=="UseMeanshiftGrouping")
                useMeanshiftGrouping = rhs[i+1].toBool();
            else
                mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option %s", key.c_str());
        }

        // Run
        vector<Rect> foundLocations;
        vector<double> weights;
        obj.detectMultiScale(img, foundLocations, weights, hitThreshold, winStride,
            padding, scale, finalThreshold, useMeanshiftGrouping);
        plhs[0] = MxArray(foundLocations);
        if (nlhs>1)
            plhs[1] = MxArray(Mat(weights));
    }
    else if (method == "computeGradient") {
        nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=2);

        Mat img(rhs[2].isUint8() ? rhs[2].toMat() : rhs[2].toMat(CV_32F));
        Size paddingTL;
        Size paddingBR;
        for (int i=3; i<nrhs; i+=2) {
            string key = rhs[i].toString();
            if (key=="PaddingTR")
                paddingTL = rhs[i+1].toSize();
            else if (key=="PaddingBR")
                paddingBR = rhs[i+1].toSize();
            else
                mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option %s", key.c_str());
        }

        // Run
        Mat grad, angleOfs;
        obj.computeGradient(img,grad,angleOfs,paddingTL,paddingBR);
        plhs[0] = MxArray(grad);
        if (nlhs>1)
            plhs[1] = MxArray(angleOfs);
    }
    else if (method == "winSize") {
        if (nlhs==1 && nrhs==2)
            plhs[0] = MxArray(obj.winSize);
        else if (nlhs==0 && nrhs==3)
            obj.winSize = rhs[2].toSize();
        else
            nargchk(false);
    }
    else if (method == "blockSize") {
        if (nlhs==1 && nrhs==2)
            plhs[0] = MxArray(obj.blockSize);
        else if (nlhs==0 && nrhs==3)
            obj.blockSize = rhs[2].toSize();
        else
            nargchk(false);
    }
    else if (method == "blockStride") {
        if (nlhs==1 && nrhs==2)
            plhs[0] = MxArray(obj.blockStride);
        else if (nlhs==0 && nrhs==3)
            obj.blockStride = rhs[2].toSize();
        else
            nargchk(false);
    }
    else if (method == "cellSize") {
        if (nlhs==1 && nrhs==2)
            plhs[0] = MxArray(obj.cellSize);
        else if (nlhs==0 && nrhs==3)
            obj.cellSize = rhs[2].toSize();
        else
            nargchk(false);
    }
    else if (method == "nbins") {
        if (nlhs==1 && nrhs==2)
            plhs[0] = MxArray(obj.nbins);
        else if (nlhs==0 && nrhs==3)
            obj.nbins = rhs[2].toInt();
        else
            nargchk(false);
    }
    else if (method == "derivAperture") {
        if (nlhs==1 && nrhs==2)
            plhs[0] = MxArray(obj.derivAperture);
        else if (nlhs==0 && nrhs==3)
            obj.derivAperture = rhs[2].toInt();
        else
            nargchk(false);
    }
    else if (method == "winSigma") {
        if (nlhs==1 && nrhs==2)
            plhs[0] = MxArray(obj.winSigma);
        else if (nlhs==0 && nrhs==3)
            obj.winSigma = rhs[2].toDouble();
        else
            nargchk(false);
    }
    else if (method == "histogramNormType") {
        if (nlhs==1 && nrhs==2)
            plhs[0] = MxArray(InvHistogramNormType[obj.histogramNormType]);
        else if (nlhs==0 && nrhs==3)
            obj.histogramNormType = HistogramNormType[rhs[2].toString()];
        else
            nargchk(false);
    }
    else if (method == "L2HysThreshold") {
        if (nlhs==1 && nrhs==2)
            plhs[0] = MxArray(obj.L2HysThreshold);
        else if (nlhs==0 && nrhs==3)
            obj.L2HysThreshold = rhs[2].toDouble();
        else
            nargchk(false);
    }
    else if (method == "gammaCorrection") {
        if (nlhs==1 && nrhs==2)
            plhs[0] = MxArray(obj.gammaCorrection);
        else if (nlhs==0 && nrhs==3)
            obj.gammaCorrection = rhs[2].toBool();
        else
            nargchk(false);
    }
    else if (method == "nlevels") {
        if (nlhs==1 && nrhs==2)
            plhs[0] = MxArray(obj.nlevels);
        else if (nlhs==0 && nrhs==3)
            obj.nlevels = rhs[2].toInt();
        else
            nargchk(false);
    }
    else
        mexErrMsgIdAndTxt("mexopencv:error","Unrecognized operation %s", method.c_str());
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: NeonHeadRequest.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: kz $ $Date: 2006-07-19 09:34:54 $
 *
 *  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 _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYSTATE_HPP_
#include <com/sun/star/beans/PropertyState.hpp>
#endif

#ifndef _NEONHEADREQUEST_HXX_
#include "NeonHeadRequest.hxx"
#endif

using namespace webdav_ucp;
using namespace com::sun::star;

#if NEON_VERSION >= 0250
static void process_headers(ne_request *req,
                            DAVResource &rResource,
                            const std::vector< ::rtl::OUString > &rHeaderNames)
{
    void *cursor = NULL;
    const char *name, *value;

    while ((cursor = ne_response_header_iterate(req, cursor,
                                                &name, &value)) != NULL) {
        rtl::OUString aHeaderName( rtl::OUString::createFromAscii( name ) );
        rtl::OUString aHeaderValue( rtl::OUString::createFromAscii( value ) );

        // Note: Empty vector means that all headers are requested.
        bool bIncludeIt = ( rHeaderNames.size() == 0 );

        if ( !bIncludeIt )
        {
            // Check whether this header was requested.
            std::vector< ::rtl::OUString >::const_iterator it(
                rHeaderNames.begin() );
            const std::vector< ::rtl::OUString >::const_iterator end(
                rHeaderNames.end() );

            while ( it != end )
            {
                if ( (*it) == aHeaderName )
                    break;

                ++it;
            }

            if ( it != end )
                bIncludeIt = true;
        }

        if ( bIncludeIt )
        {
            // Create & set the PropertyValue
            beans::PropertyValue thePropertyValue;
            thePropertyValue.Handle = -1;
            thePropertyValue.Name   = aHeaderName;
            thePropertyValue.State  = beans::PropertyState_DIRECT_VALUE;

            thePropertyValue.Value  <<= aHeaderValue;

            // Add the newly created PropertyValue
            rResource.properties.push_back( thePropertyValue );
        }
    }
}
#else
struct NeonHeadRequestContext
{
    DAVResource * pResource;
    const std::vector< ::rtl::OUString > * pHeaderNames;

    NeonHeadRequestContext( DAVResource * p,
                            const std::vector< ::rtl::OUString > * pHeaders )
    : pResource( p ), pHeaderNames( pHeaders ) {}
};

extern "C" void NHR_ResponseHeaderCatcher( void * userdata,
                                           const char * value )
{
    rtl::OUString aHeader( rtl::OUString::createFromAscii( value ) );
    sal_Int32 nPos = aHeader.indexOf( ':' );

    if ( nPos != -1 )
    {
        rtl::OUString aHeaderName( aHeader.copy( 0, nPos ) );

        NeonHeadRequestContext * pCtx
            = static_cast< NeonHeadRequestContext * >( userdata );

        // Note: Empty vector means that all headers are requested.
        bool bIncludeIt = ( pCtx->pHeaderNames->size() == 0 );

        if ( !bIncludeIt )
        {
            // Check whether this header was requested.
            std::vector< ::rtl::OUString >::const_iterator it(
                pCtx->pHeaderNames->begin() );
            const std::vector< ::rtl::OUString >::const_iterator end(
                pCtx->pHeaderNames->end() );

            while ( it != end )
            {
                if ( (*it) == aHeaderName )
                    break;

                ++it;
            }

            if ( it != end )
                bIncludeIt = true;
        }

        if ( bIncludeIt )
        {
            // Create & set the PropertyValue
            beans::PropertyValue thePropertyValue;
            thePropertyValue.Handle = -1;
            thePropertyValue.Name   = aHeaderName;
            thePropertyValue.State  = beans::PropertyState_DIRECT_VALUE;

            if ( nPos < aHeader.getLength() )
                thePropertyValue.Value <<= aHeader.copy( nPos + 1 ).trim();

            // Add the newly created PropertyValue
            pCtx->pResource->properties.push_back( thePropertyValue );
        }
    }
}
#endif

// -------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------

NeonHeadRequest::NeonHeadRequest( HttpSession* inSession,
                                  const rtl::OUString & inPath,
                                  const std::vector< ::rtl::OUString > &
                                    inHeaderNames,
                                  DAVResource & ioResource,
                                  int & nError )
{
    ioResource.uri = inPath;
    ioResource.properties.clear();

    // Create and dispatch HEAD request. Install catcher for all response
    // header fields.
    ne_request * req = ne_request_create( inSession,
                                          "HEAD",
                                          rtl::OUStringToOString(
                                            inPath,
                                            RTL_TEXTENCODING_UTF8 ) );

#if NEON_VERSION < 0250
    NeonHeadRequestContext aCtx( &ioResource, &inHeaderNames );
    ne_add_response_header_catcher( req, NHR_ResponseHeaderCatcher, &aCtx );
#endif

    nError = ne_request_dispatch( req );

#if NEON_VERSION >= 0250
    process_headers(req, ioResource, inHeaderNames);
#endif

    if ( nError == NE_OK && ne_get_status( req )->klass != 2 )
        nError = NE_ERROR;

    ne_request_destroy( req );
}

// -------------------------------------------------------------------
// Destructor
// -------------------------------------------------------------------
NeonHeadRequest::~NeonHeadRequest()
{
}

<commit_msg>INTEGRATION: CWS pchfix02 (1.5.16); FILE MERGED 2006/09/01 17:55:54 kaib 1.5.16.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: NeonHeadRequest.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 14:06:12 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_ucb.hxx"

#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYSTATE_HPP_
#include <com/sun/star/beans/PropertyState.hpp>
#endif

#ifndef _NEONHEADREQUEST_HXX_
#include "NeonHeadRequest.hxx"
#endif

using namespace webdav_ucp;
using namespace com::sun::star;

#if NEON_VERSION >= 0250
static void process_headers(ne_request *req,
                            DAVResource &rResource,
                            const std::vector< ::rtl::OUString > &rHeaderNames)
{
    void *cursor = NULL;
    const char *name, *value;

    while ((cursor = ne_response_header_iterate(req, cursor,
                                                &name, &value)) != NULL) {
        rtl::OUString aHeaderName( rtl::OUString::createFromAscii( name ) );
        rtl::OUString aHeaderValue( rtl::OUString::createFromAscii( value ) );

        // Note: Empty vector means that all headers are requested.
        bool bIncludeIt = ( rHeaderNames.size() == 0 );

        if ( !bIncludeIt )
        {
            // Check whether this header was requested.
            std::vector< ::rtl::OUString >::const_iterator it(
                rHeaderNames.begin() );
            const std::vector< ::rtl::OUString >::const_iterator end(
                rHeaderNames.end() );

            while ( it != end )
            {
                if ( (*it) == aHeaderName )
                    break;

                ++it;
            }

            if ( it != end )
                bIncludeIt = true;
        }

        if ( bIncludeIt )
        {
            // Create & set the PropertyValue
            beans::PropertyValue thePropertyValue;
            thePropertyValue.Handle = -1;
            thePropertyValue.Name   = aHeaderName;
            thePropertyValue.State  = beans::PropertyState_DIRECT_VALUE;

            thePropertyValue.Value  <<= aHeaderValue;

            // Add the newly created PropertyValue
            rResource.properties.push_back( thePropertyValue );
        }
    }
}
#else
struct NeonHeadRequestContext
{
    DAVResource * pResource;
    const std::vector< ::rtl::OUString > * pHeaderNames;

    NeonHeadRequestContext( DAVResource * p,
                            const std::vector< ::rtl::OUString > * pHeaders )
    : pResource( p ), pHeaderNames( pHeaders ) {}
};

extern "C" void NHR_ResponseHeaderCatcher( void * userdata,
                                           const char * value )
{
    rtl::OUString aHeader( rtl::OUString::createFromAscii( value ) );
    sal_Int32 nPos = aHeader.indexOf( ':' );

    if ( nPos != -1 )
    {
        rtl::OUString aHeaderName( aHeader.copy( 0, nPos ) );

        NeonHeadRequestContext * pCtx
            = static_cast< NeonHeadRequestContext * >( userdata );

        // Note: Empty vector means that all headers are requested.
        bool bIncludeIt = ( pCtx->pHeaderNames->size() == 0 );

        if ( !bIncludeIt )
        {
            // Check whether this header was requested.
            std::vector< ::rtl::OUString >::const_iterator it(
                pCtx->pHeaderNames->begin() );
            const std::vector< ::rtl::OUString >::const_iterator end(
                pCtx->pHeaderNames->end() );

            while ( it != end )
            {
                if ( (*it) == aHeaderName )
                    break;

                ++it;
            }

            if ( it != end )
                bIncludeIt = true;
        }

        if ( bIncludeIt )
        {
            // Create & set the PropertyValue
            beans::PropertyValue thePropertyValue;
            thePropertyValue.Handle = -1;
            thePropertyValue.Name   = aHeaderName;
            thePropertyValue.State  = beans::PropertyState_DIRECT_VALUE;

            if ( nPos < aHeader.getLength() )
                thePropertyValue.Value <<= aHeader.copy( nPos + 1 ).trim();

            // Add the newly created PropertyValue
            pCtx->pResource->properties.push_back( thePropertyValue );
        }
    }
}
#endif

// -------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------

NeonHeadRequest::NeonHeadRequest( HttpSession* inSession,
                                  const rtl::OUString & inPath,
                                  const std::vector< ::rtl::OUString > &
                                    inHeaderNames,
                                  DAVResource & ioResource,
                                  int & nError )
{
    ioResource.uri = inPath;
    ioResource.properties.clear();

    // Create and dispatch HEAD request. Install catcher for all response
    // header fields.
    ne_request * req = ne_request_create( inSession,
                                          "HEAD",
                                          rtl::OUStringToOString(
                                            inPath,
                                            RTL_TEXTENCODING_UTF8 ) );

#if NEON_VERSION < 0250
    NeonHeadRequestContext aCtx( &ioResource, &inHeaderNames );
    ne_add_response_header_catcher( req, NHR_ResponseHeaderCatcher, &aCtx );
#endif

    nError = ne_request_dispatch( req );

#if NEON_VERSION >= 0250
    process_headers(req, ioResource, inHeaderNames);
#endif

    if ( nError == NE_OK && ne_get_status( req )->klass != 2 )
        nError = NE_ERROR;

    ne_request_destroy( req );
}

// -------------------------------------------------------------------
// Destructor
// -------------------------------------------------------------------
NeonHeadRequest::~NeonHeadRequest()
{
}

<|endoftext|>


<commit_before>//
// RemotePhotoTool - remote camera control software
// Copyright (C) 2008-2016 Michael Fink
//
/// \file GPhoto2Common.cpp gPhoto2 - Common functions
//

// includes
#include "stdafx.h"
#include "GPhoto2Common.hpp"
#include "GPhoto2SourceInfoImpl.hpp"
#include "GPhoto2Include.hpp"

void GPhoto2::CheckError(const CString& cszFunction, int err, LPCSTR pszFile, UINT uiLine)
{
   if (err >= GP_OK)
      return;

   const char* errorText = gp_result_as_string(err);

   LOG_TRACE(_T("gPhoto2: error in function %s: %hs, return code %i\n"), cszFunction.GetString(), errorText, err);

   throw CameraException(cszFunction, CString(errorText), static_cast<unsigned int>(err), pszFile, uiLine);
}

/// context error handler function
static void ctx_error_func(GPContext* context, const char* str, void* /*data*/)
{
   LOG_TRACE(_T("gPhoto2 error: ctx=%p, text=%hs\n"), context, str);
}

/// context status handler function
static void ctx_status_func(GPContext* context, const char* str, void* /*data*/)
{
   LOG_TRACE(_T("gPhoto2 status: ctx=%p, text=%hs\n"), context, str);
}

/// context message handler function
static void ctx_message_func(GPContext* context, const char* str, void* /*data*/)
{
   LOG_TRACE(_T("gPhoto2 message: ctx=%p, text=%hs\n"), context, str);
}

GPhoto2::Ref::Ref()
{
   GPContext* context = gp_context_new();
   m_spContext.reset(context, gp_context_unref);

   gp_context_set_error_func(context, ctx_error_func, nullptr);
   gp_context_set_status_func(context, ctx_status_func, nullptr);
   gp_context_set_message_func(context, ctx_message_func, nullptr);
}

GPhoto2::Ref::~Ref() throw()
{
}

void GPhoto2::Ref::AddVersionText(CString& cszVersionText) const
{
   const char** ppVersion = gp_library_version(GP_VERSION_SHORT);

   cszVersionText.AppendFormat(_T("gPhoto2 %hs\n"), ppVersion[0]);
}

void GPhoto2::Ref::EnumerateDevices(std::vector<std::shared_ptr<SourceInfo>>& vecSourceDevices) const
{
   CameraList* cameraList = nullptr;

   int ret = gp_list_new(&cameraList);
   if (ret < GP_OK)
      return;

   std::shared_ptr<CameraList> spAutoFreeCameraList(cameraList, gp_list_free);

   ret = gp_camera_autodetect(cameraList, m_spContext.get());
   if (ret < GP_OK)
   {
      const char* errorText = gp_result_as_string(ret);

      LOG_TRACE(_T("gPhoto2: no camera auto detected: %hs\n"), errorText);
      return;
   }

   for (int index = 0, max = ret; index < max; index++)
   {
      const char* name = nullptr;
      const char* port = nullptr;

      gp_list_get_name(cameraList, index, &name);
      gp_list_get_value(cameraList, index, &port);

      LOG_TRACE(_T("gPhoto2 camera #%i: %hs (%hs)\n"), index, name, port);

      vecSourceDevices.push_back(std::make_shared<GPhoto2::SourceInfoImpl>(m_spContext, name, port));
   }
}
<commit_msg>added another newline after gPhoto version<commit_after>//
// RemotePhotoTool - remote camera control software
// Copyright (C) 2008-2016 Michael Fink
//
/// \file GPhoto2Common.cpp gPhoto2 - Common functions
//

// includes
#include "stdafx.h"
#include "GPhoto2Common.hpp"
#include "GPhoto2SourceInfoImpl.hpp"
#include "GPhoto2Include.hpp"

void GPhoto2::CheckError(const CString& cszFunction, int err, LPCSTR pszFile, UINT uiLine)
{
   if (err >= GP_OK)
      return;

   const char* errorText = gp_result_as_string(err);

   LOG_TRACE(_T("gPhoto2: error in function %s: %hs, return code %i\n"), cszFunction.GetString(), errorText, err);

   throw CameraException(cszFunction, CString(errorText), static_cast<unsigned int>(err), pszFile, uiLine);
}

/// context error handler function
static void ctx_error_func(GPContext* context, const char* str, void* /*data*/)
{
   LOG_TRACE(_T("gPhoto2 error: ctx=%p, text=%hs\n"), context, str);
}

/// context status handler function
static void ctx_status_func(GPContext* context, const char* str, void* /*data*/)
{
   LOG_TRACE(_T("gPhoto2 status: ctx=%p, text=%hs\n"), context, str);
}

/// context message handler function
static void ctx_message_func(GPContext* context, const char* str, void* /*data*/)
{
   LOG_TRACE(_T("gPhoto2 message: ctx=%p, text=%hs\n"), context, str);
}

GPhoto2::Ref::Ref()
{
   GPContext* context = gp_context_new();
   m_spContext.reset(context, gp_context_unref);

   gp_context_set_error_func(context, ctx_error_func, nullptr);
   gp_context_set_status_func(context, ctx_status_func, nullptr);
   gp_context_set_message_func(context, ctx_message_func, nullptr);
}

GPhoto2::Ref::~Ref() throw()
{
}

void GPhoto2::Ref::AddVersionText(CString& cszVersionText) const
{
   const char** ppVersion = gp_library_version(GP_VERSION_SHORT);

   cszVersionText.AppendFormat(_T("gPhoto2 %hs\n\n"), ppVersion[0]);
}

void GPhoto2::Ref::EnumerateDevices(std::vector<std::shared_ptr<SourceInfo>>& vecSourceDevices) const
{
   CameraList* cameraList = nullptr;

   int ret = gp_list_new(&cameraList);
   if (ret < GP_OK)
      return;

   std::shared_ptr<CameraList> spAutoFreeCameraList(cameraList, gp_list_free);

   ret = gp_camera_autodetect(cameraList, m_spContext.get());
   if (ret < GP_OK)
   {
      const char* errorText = gp_result_as_string(ret);

      LOG_TRACE(_T("gPhoto2: no camera auto detected: %hs\n"), errorText);
      return;
   }

   for (int index = 0, max = ret; index < max; index++)
   {
      const char* name = nullptr;
      const char* port = nullptr;

      gp_list_get_name(cameraList, index, &name);
      gp_list_get_value(cameraList, index, &port);

      LOG_TRACE(_T("gPhoto2 camera #%i: %hs (%hs)\n"), index, name, port);

      vecSourceDevices.push_back(std::make_shared<GPhoto2::SourceInfoImpl>(m_spContext, name, port));
   }
}
<|endoftext|>


<commit_before>/***********************************************************************************
** MIT License                                                                    **
**                                                                                **
** Copyright (c) 2017 Victor DENIS (victordenis01@gmail.com)                      **
**                                                                                **
** Permission is hereby granted, free of charge, to any person obtaining a copy   **
** of this software and associated documentation files (the "Software"), to deal  **
** in the Software without restriction, including without limitation the rights   **
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell      **
** copies of the Software, and to permit persons to whom the Software is          **
** furnished to do so, subject to the following conditions:                       **
**                                                                                **
** The above copyright notice and this permission notice shall be included in all **
** copies or substantial portions of the Software.                                **
**                                                                                **
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR     **
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,       **
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE    **
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER         **
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,  **
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE  **
** SOFTWARE.                                                                      **
***********************************************************************************/

#include "Utils/Updater.hpp"

#include <QTimer>

#include <QMessageBox>

#include <QFile>
#include <QStandardPaths>
#include <QDesktopServices>

#include <QMessageBox>

#include <QNetworkRequest>
#include <QNetworkReply>

#include "Network/NetworkManager.hpp"

#include "BrowserWindow.hpp"

#include "Application.hpp"

namespace Sn {

Updater::Updater(BrowserWindow* window, QObject* parent) :
	QObject(parent),
	m_window(window)
{
	QTimer::singleShot(10 * 1000, this, &Updater::start);
}

void Updater::downloadUpdateInfoCompleted()
{
	if (!m_versionReply)
		return;

	QByteArray updateInfo = m_versionReply->readAll();
	QTextStream in{&updateInfo};
	QString newVersion{};
	bool readLastVersion{true};

	while (!in.atEnd()) {
		QString line{in.readLine()};
		QStringList versionInfo{line.split(QLatin1Char(','))};

		if (newVersion.isEmpty())
			newVersion = versionInfo[0];

		if (versionInfo[0] == Application::currentVersion)
			break;

		std::string debug = line.toStdString();

		for (int i{1}; i < versionInfo.count(); ++i) {
			if (versionInfo[i] == "fullUpdate")
				m_fullUpdate = true;
			if (versionInfo[i] == "themeUpdate")
				m_themeUpdate = true;
		}
	}

	if (newVersion != Application::currentVersion) {
#if defined(Q_OS_WIN)
		QMessageBox::information(m_window, tr("Update"), tr("A new version of Sielo will be download in background!"));
		QString updaterName{};

		if (m_fullUpdate)
			updaterName = "sielo_full_update_setup.exe";
		else if (m_themeUpdate)
			updaterName = "sielo_theme_update_setup.exe";
		else
			updaterName = "sielo_update_setup.exe";

		QUrl updaterUrl{QUrl("http://www.feldrise.com/Sielo/" + updaterName)};
		startDownloadNewVersion(updaterUrl);
#elif defined(Q_OS_LINUX)
		QMessageBox::information(m_window,
								 tr("Update"),
								 tr("A new version of Sielo is available (%1)! We advise you to download it.")
									 .arg(newVersion));
#endif
	}

	m_versionReply->deleteLater();

}

void Updater::downloadCompleted()
{
	QString updaterLocation{QStandardPaths::writableLocation(QStandardPaths::TempLocation)};
	QFile updater{updaterLocation + QLatin1String("/SieloUpdater.exe")};

	if (!updater.open(QIODevice::WriteOnly)) {
		QMessageBox::critical(m_window, tr("Update fail"), tr("Impossible to update Sielo... Please retry later"));
		return;
	}

	updater.write(m_updaterReply->readAll());
	updater.close();

	QDesktopServices::openUrl(QUrl(updaterLocation + QLatin1String("/SieloUpdater.exe")));

	m_updaterReply->deleteLater();
	m_window->close();
}

void Updater::start()
{
	QUrl newVersionUrl{QUrl("http://www.feldrise.com/Sielo/versions.txt")};

	startDownloadingUpdateInfo(newVersionUrl);
}

void Updater::startDownloadNewVersion(const QUrl& url)
{
	m_updaterReply = Application::instance()->networkManager()->get(QNetworkRequest(url));

	connect(m_updaterReply, &QNetworkReply::finished, this, &Updater::downloadCompleted);
}

void Updater::startDownloadingUpdateInfo(const QUrl& url)
{
	m_versionReply = Application::instance()->networkManager()->get(QNetworkRequest(url));

	connect(m_versionReply, &QNetworkReply::finished, this, &Updater::downloadUpdateInfoCompleted);
}

}
<commit_msg>[Remove] useless variable<commit_after>/***********************************************************************************
** MIT License                                                                    **
**                                                                                **
** Copyright (c) 2017 Victor DENIS (victordenis01@gmail.com)                      **
**                                                                                **
** Permission is hereby granted, free of charge, to any person obtaining a copy   **
** of this software and associated documentation files (the "Software"), to deal  **
** in the Software without restriction, including without limitation the rights   **
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell      **
** copies of the Software, and to permit persons to whom the Software is          **
** furnished to do so, subject to the following conditions:                       **
**                                                                                **
** The above copyright notice and this permission notice shall be included in all **
** copies or substantial portions of the Software.                                **
**                                                                                **
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR     **
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,       **
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE    **
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER         **
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,  **
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE  **
** SOFTWARE.                                                                      **
***********************************************************************************/

#include "Utils/Updater.hpp"

#include <QTimer>

#include <QMessageBox>

#include <QFile>
#include <QStandardPaths>
#include <QDesktopServices>

#include <QMessageBox>

#include <QNetworkRequest>
#include <QNetworkReply>

#include "Network/NetworkManager.hpp"

#include "BrowserWindow.hpp"

#include "Application.hpp"

namespace Sn {

Updater::Updater(BrowserWindow* window, QObject* parent) :
	QObject(parent),
	m_window(window)
{
	QTimer::singleShot(10 * 1000, this, &Updater::start);
}

void Updater::downloadUpdateInfoCompleted()
{
	if (!m_versionReply)
		return;

	QByteArray updateInfo = m_versionReply->readAll();
	QTextStream in{&updateInfo};
	QString newVersion{};

	while (!in.atEnd()) {
		QString line{in.readLine()};
		QStringList versionInfo{line.split(QLatin1Char(','))};

		if (newVersion.isEmpty())
			newVersion = versionInfo[0];

		if (versionInfo[0] == Application::currentVersion)
			break;

		for (int i{1}; i < versionInfo.count(); ++i) {
			if (versionInfo[i] == "fullUpdate")
				m_fullUpdate = true;
			if (versionInfo[i] == "themeUpdate")
				m_themeUpdate = true;
		}
	}

	if (newVersion != Application::currentVersion) {
#if defined(Q_OS_WIN)
		QMessageBox::information(m_window, tr("Update"), tr("A new version of Sielo will be download in background!"));
		QString updaterName{};

		if (m_fullUpdate)
			updaterName = "sielo_full_update_setup.exe";
		else if (m_themeUpdate)
			updaterName = "sielo_theme_update_setup.exe";
		else
			updaterName = "sielo_update_setup.exe";

		QUrl updaterUrl{QUrl("http://www.feldrise.com/Sielo/" + updaterName)};
		startDownloadNewVersion(updaterUrl);
#elif defined(Q_OS_LINUX)
		QMessageBox::information(m_window,
								 tr("Update"),
								 tr("A new version of Sielo is available (%1)! We advise you to download it.")
									 .arg(newVersion));
#endif
	}

	m_versionReply->deleteLater();

}

void Updater::downloadCompleted()
{
	QString updaterLocation{QStandardPaths::writableLocation(QStandardPaths::TempLocation)};
	QFile updater{updaterLocation + QLatin1String("/SieloUpdater.exe")};

	if (!updater.open(QIODevice::WriteOnly)) {
		QMessageBox::critical(m_window, tr("Update fail"), tr("Impossible to update Sielo... Please retry later"));
		return;
	}

	updater.write(m_updaterReply->readAll());
	updater.close();

	QDesktopServices::openUrl(QUrl(updaterLocation + QLatin1String("/SieloUpdater.exe")));

	m_updaterReply->deleteLater();
	m_window->close();
}

void Updater::start()
{
	QUrl newVersionUrl{QUrl("http://www.feldrise.com/Sielo/versions.txt")};

	startDownloadingUpdateInfo(newVersionUrl);
}

void Updater::startDownloadNewVersion(const QUrl& url)
{
	m_updaterReply = Application::instance()->networkManager()->get(QNetworkRequest(url));

	connect(m_updaterReply, &QNetworkReply::finished, this, &Updater::downloadCompleted);
}

void Updater::startDownloadingUpdateInfo(const QUrl& url)
{
	m_versionReply = Application::instance()->networkManager()->get(QNetworkRequest(url));

	connect(m_versionReply, &QNetworkReply::finished, this, &Updater::downloadUpdateInfoCompleted);
}

}
<|endoftext|>


<commit_before>#include <QList>

#include "Connection.hpp"
#include "ForwardingSender.hpp"
#include "RelayEdge.hpp"
#include "RelayForwarder.hpp"

namespace Dissent {
namespace Connections {
  RelayForwarder::RelayForwarder(const Id &local_id, const ConnectionTable &ct,
      RpcHandler &rpc) :
    _local_id(local_id),
    _base_been(local_id.ToString()),
    _ct(ct),
    _rpc(rpc),
    _incoming_data(this, &RelayForwarder::IncomingData)
  {
    _rpc.Register(&_incoming_data, "RF::Data");
  }

  RelayForwarder::~RelayForwarder()
  {
    _rpc.Unregister("RF::Data");
  }

  RelayForwarder::ISender *RelayForwarder::GetSender(const Id &to)
  {
    return new ForwardingSender(this, to);
  }

  void RelayForwarder::Send(const QByteArray &data, const Id &to)
  {
    if(to == _local_id) {
      _rpc.HandleData(data, new ForwardingSender(this, _local_id));
      return;
    }

    Forward(data, to, _base_been);
  }

  void RelayForwarder::IncomingData(RpcRequest &notification)
  {
    const QVariantMap &msg = notification.GetMessage();

    Id destination = Id(msg["to"].toString());
    if(destination == Id::Zero()) {
      qWarning() << "Received a forwarded message without a destination.";
      return;
    }

    QStringList been = msg["been"].toStringList();
    if(destination == _local_id) {
      if(been.size() == 0) {
        qWarning() << "Received a forwarded message without any history.";
        return;
      }

      Id source = Id(been[0]);
      if(source == Id::Zero()) {
        qWarning() << "Received a forwarded message without a valid source.";
      }

      _rpc.HandleData(msg["data"].toByteArray(), new ForwardingSender(this, source));
      return;
    }

    Forward(msg["data"].toByteArray(), destination, (been + _base_been));
  }

  void RelayForwarder::Forward(const QByteArray &data, const Id &to,
      const QStringList &been)
  {
    QHash<int, bool> tested;

    Connection *con = _ct.GetConnection(to);
    if(con == 0 || (dynamic_cast<RelayEdge *>(con->GetEdge().data()) != 0)) {
      const QList<Connection *> cons = _ct.GetConnections();

      Dissent::Utils::Random &rand = Dissent::Utils::Random::GetInstance();
      int idx = rand.GetInt(0, cons.size());
      con = cons[idx];
      tested[idx] = true;
      RelayEdge *redge = dynamic_cast<RelayEdge *>(con->GetEdge().data());
      while(been.contains(con->GetRemoteId().ToString()) || (redge != 0)) {
        if(tested.size() == cons.size()) {
          qWarning() << "Packet has been to all of our connections.";
          return;
        }

        idx = rand.GetInt(0, cons.size());
        con = cons[idx];
        redge = dynamic_cast<RelayEdge *>(con->GetEdge().data());
        tested[idx] = true;
      }
    }

    qWarning() << _local_id.ToString() << con->GetRemoteId().ToString() << con->GetEdge()->ToString();

    QVariantMap notification;
    notification["method"] = "RF::Data";
    notification["data"] = data;
    notification["to"] = to.ToString();
    notification["been"] = been + _base_been;

    _rpc.SendNotification(notification, con);
  }
}
}
<commit_msg>[Connections] debug cleanup<commit_after>#include <QList>

#include "Connection.hpp"
#include "ForwardingSender.hpp"
#include "RelayEdge.hpp"
#include "RelayForwarder.hpp"

namespace Dissent {
namespace Connections {
  RelayForwarder::RelayForwarder(const Id &local_id, const ConnectionTable &ct,
      RpcHandler &rpc) :
    _local_id(local_id),
    _base_been(local_id.ToString()),
    _ct(ct),
    _rpc(rpc),
    _incoming_data(this, &RelayForwarder::IncomingData)
  {
    _rpc.Register(&_incoming_data, "RF::Data");
  }

  RelayForwarder::~RelayForwarder()
  {
    _rpc.Unregister("RF::Data");
  }

  RelayForwarder::ISender *RelayForwarder::GetSender(const Id &to)
  {
    return new ForwardingSender(this, to);
  }

  void RelayForwarder::Send(const QByteArray &data, const Id &to)
  {
    if(to == _local_id) {
      _rpc.HandleData(data, new ForwardingSender(this, _local_id));
      return;
    }

    Forward(data, to, _base_been);
  }

  void RelayForwarder::IncomingData(RpcRequest &notification)
  {
    const QVariantMap &msg = notification.GetMessage();

    Id destination = Id(msg["to"].toString());
    if(destination == Id::Zero()) {
      qWarning() << "Received a forwarded message without a destination.";
      return;
    }

    QStringList been = msg["been"].toStringList();
    if(destination == _local_id) {
      if(been.size() == 0) {
        qWarning() << "Received a forwarded message without any history.";
        return;
      }

      Id source = Id(been[0]);
      if(source == Id::Zero()) {
        qWarning() << "Received a forwarded message without a valid source.";
      }

      _rpc.HandleData(msg["data"].toByteArray(), new ForwardingSender(this, source));
      return;
    }

    Forward(msg["data"].toByteArray(), destination, (been + _base_been));
  }

  void RelayForwarder::Forward(const QByteArray &data, const Id &to,
      const QStringList &been)
  {
    QHash<int, bool> tested;

    Connection *con = _ct.GetConnection(to);
    if(con == 0 || (dynamic_cast<RelayEdge *>(con->GetEdge().data()) != 0)) {
      const QList<Connection *> cons = _ct.GetConnections();

      Dissent::Utils::Random &rand = Dissent::Utils::Random::GetInstance();
      int idx = rand.GetInt(0, cons.size());
      con = cons[idx];
      tested[idx] = true;
      RelayEdge *redge = dynamic_cast<RelayEdge *>(con->GetEdge().data());
      while(been.contains(con->GetRemoteId().ToString()) || (redge != 0)) {
        if(tested.size() == cons.size()) {
          qWarning() << "Packet has been to all of our connections.";
          return;
        }

        idx = rand.GetInt(0, cons.size());
        con = cons[idx];
        redge = dynamic_cast<RelayEdge *>(con->GetEdge().data());
        tested[idx] = true;
      }
    }

    QVariantMap notification;
    notification["method"] = "RF::Data";
    notification["data"] = data;
    notification["to"] = to.ToString();
    notification["been"] = been + _base_been;

    _rpc.SendNotification(notification, con);
  }
}
}
<|endoftext|>


<commit_before>#include "TriangleMesh.hpp"
#include <Core/Geometry/TriangleOperation.hpp> // triangleArea

namespace Ra {
namespace Core {
namespace Geometry {

inline AttribArrayGeometry ::AttribArrayGeometry( const AttribArrayGeometry& other ) :
    AbstractGeometry( other ) {
    m_vertexAttribs.copyAllAttributes( other.m_vertexAttribs );
    m_verticesHandle = other.m_verticesHandle;
    m_normalsHandle  = other.m_normalsHandle;
}

inline AttribArrayGeometry::AttribArrayGeometry( AttribArrayGeometry&& other ) :
    m_vertexAttribs( std::move( other.m_vertexAttribs ) ),
    m_verticesHandle( std::move( other.m_verticesHandle ) ),
    m_normalsHandle( std::move( other.m_normalsHandle ) ) {}

inline AttribArrayGeometry& AttribArrayGeometry::operator=( const AttribArrayGeometry& other ) {
    if ( this != &other )
    {
        m_vertexAttribs.clear();
        m_vertexAttribs.copyAllAttributes( other.m_vertexAttribs );
        m_verticesHandle = other.m_verticesHandle;
        m_normalsHandle  = other.m_normalsHandle;
    }
    return *this;
}

inline AttribArrayGeometry& AttribArrayGeometry::operator=( AttribArrayGeometry&& other ) {
    if ( this != &other )
    {
        m_vertexAttribs  = std::move( other.m_vertexAttribs );
        m_verticesHandle = std::move( other.m_verticesHandle );
        m_normalsHandle  = std::move( other.m_normalsHandle );
    }
    return *this;
}

inline void AttribArrayGeometry::clear() {
    m_vertexAttribs.clear();
    // restore the default attribs (empty though)
    initDefaultAttribs();
}

inline void AttribArrayGeometry::copyBaseGeometry( const AttribArrayGeometry& other ) {
    clear();
    m_vertexAttribs.copyAttributes(
        other.m_vertexAttribs, other.m_verticesHandle, other.m_normalsHandle );
}

template <typename... Handles>
inline bool AttribArrayGeometry::copyAttributes( const AttribArrayGeometry& input,
                                                 Handles... attribs ) {
    if ( vertices().size() != input.vertices().size() ) return false;
    // copy attribs
    m_vertexAttribs.copyAttributes( input.m_vertexAttribs, attribs... );
    return true;
}

inline bool AttribArrayGeometry::copyAllAttributes( const AttribArrayGeometry& input ) {
    if ( vertices().size() != input.vertices().size() ) return false;
    // copy attribs
    m_vertexAttribs.copyAllAttributes( input.m_vertexAttribs );
    return true;
}

inline Aabb AttribArrayGeometry::computeAabb() const {
    Aabb aabb;
    for ( const auto& v : vertices() )
    {
        aabb.extend( v );
    }
    return aabb;
}

inline void AttribArrayGeometry::setVertices( PointAttribHandle::Container&& vertices ) {
    m_vertexAttribs.setAttrib( m_verticesHandle, std::move( vertices ) );
}

inline void AttribArrayGeometry::setVertices( const PointAttribHandle::Container& vertices ) {
    m_vertexAttribs.setAttrib<PointAttribHandle::value_type>( m_verticesHandle, vertices );
}

inline const AttribArrayGeometry::PointAttribHandle::Container&
AttribArrayGeometry::vertices() const {
    return m_vertexAttribs.getAttrib( m_verticesHandle ).data();
}

inline void AttribArrayGeometry::setNormals( PointAttribHandle::Container&& normals ) {
    m_vertexAttribs.setAttrib( m_normalsHandle, std::move( normals ) );
}
inline void AttribArrayGeometry::setNormals( const PointAttribHandle::Container& normals ) {
    m_vertexAttribs.setAttrib( m_normalsHandle, normals );
}

inline const AttribArrayGeometry::NormalAttribHandle::Container&
AttribArrayGeometry::normals() const {
    return m_vertexAttribs.getAttrib( m_normalsHandle ).data();
}

template <typename T>
inline Utils::AttribHandle<T>
AttribArrayGeometry::getAttribHandle( const std::string& name ) const {
    return m_vertexAttribs.findAttrib<T>( name );
}

template <typename T>
inline bool AttribArrayGeometry::isValid( const Utils::AttribHandle<T>& h ) const {
    return m_vertexAttribs.isValid( h );
}

template <typename T>
inline Utils::Attrib<T>& AttribArrayGeometry::getAttrib( const Utils::AttribHandle<T>& h ) {
    return m_vertexAttribs.getAttrib( h );
}

template <typename T>
const Utils::Attrib<T>& AttribArrayGeometry::getAttrib( const Utils::AttribHandle<T>& h ) const {
    return m_vertexAttribs.getAttrib( h );
}

inline Utils::AttribBase* AttribArrayGeometry::getAttribBase( const std::string& name ) {
    return m_vertexAttribs.getAttribBase( name );
}

inline bool AttribArrayGeometry::hasAttrib( const std::string& name ) {
    return m_vertexAttribs.contains( name );
}

template <typename T>
inline Utils::AttribHandle<T> AttribArrayGeometry::addAttrib( const std::string& name ) {
    return m_vertexAttribs.addAttrib<T>( name );
}

template <typename T>
inline Utils::AttribHandle<T>
AttribArrayGeometry::addAttrib( const std::string& name,
                                const typename Core::VectorArray<T>& data ) {
    auto handle = addAttrib<T>( name );
    getAttrib( handle ).setData( data );
    return handle;
}

template <typename T>
inline Utils::AttribHandle<T>
AttribArrayGeometry::addAttrib( const std::string& name,
                                const typename Utils::Attrib<T>::Container&& data ) {
    auto handle = addAttrib<T>( name );
    getAttrib( handle ).setData( std::move( data ) );
    return handle;
}

template <typename T>
inline void AttribArrayGeometry::removeAttrib( Utils::AttribHandle<T>& h ) {
    m_vertexAttribs.removeAttrib( h );
}

inline Utils::AttribManager& AttribArrayGeometry::vertexAttribs() {
    return m_vertexAttribs;
}

inline const Utils::AttribManager& AttribArrayGeometry::vertexAttribs() const {
    return m_vertexAttribs;
}

inline AttribArrayGeometry::PointAttribHandle::Container& AttribArrayGeometry::verticesWithLock() {
    return m_vertexAttribs.getAttrib( m_verticesHandle ).getDataWithLock();
}

inline void AttribArrayGeometry::verticesUnlock() {
    return m_vertexAttribs.getAttrib( m_verticesHandle ).unlock();
}

inline AttribArrayGeometry::NormalAttribHandle::Container& AttribArrayGeometry::normalsWithLock() {
    return m_vertexAttribs.getAttrib( m_normalsHandle ).getDataWithLock();
}

inline void AttribArrayGeometry::normalsUnlock() {
    return m_vertexAttribs.getAttrib( m_normalsHandle ).unlock();
}

inline void AttribArrayGeometry::initDefaultAttribs() {
    m_verticesHandle = m_vertexAttribs.addAttrib<PointAttribHandle::value_type>( "in_position" );
    m_normalsHandle  = m_vertexAttribs.addAttrib<NormalAttribHandle::value_type>( "in_normal" );
}

template <typename T>
inline void AttribArrayGeometry::append_attrib( Utils::AttribBase* attr ) {
    auto h         = m_vertexAttribs.findAttrib<T>( attr->getName() );
    auto& v0       = m_vertexAttribs.getAttrib( h ).getDataWithLock();
    const auto& v1 = attr->cast<T>().data();
    v0.insert( v0.end(), v1.cbegin(), v1.cend() );
    m_vertexAttribs.getAttrib( h ).unlock();
}

/*** IndexedGeometry ***/
template <typename T>
inline IndexedGeometry<T>::IndexedGeometry( const IndexedGeometry<IndexType>& other ) :
    AttribArrayGeometry( other ), m_indices( other.m_indices ) {}

template <typename T>
inline IndexedGeometry<T>::IndexedGeometry( IndexedGeometry<IndexType>&& other ) :
    AttribArrayGeometry( std::move( other ) ), m_indices( std::move( other.m_indices ) ) {}

template <typename T>
inline IndexedGeometry<T>&
IndexedGeometry<T>::operator=( const IndexedGeometry<IndexType>& other ) {
    AttribArrayGeometry::operator=( other );
    m_indices                    = other.m_indices;
    notify();
    return *this;
}

template <typename T>
inline IndexedGeometry<T>& IndexedGeometry<T>::operator=( IndexedGeometry<IndexType>&& other ) {
    AttribArrayGeometry::operator=( std::move( other ) );
    m_indices                    = std::move( other.m_indices );
    notify();
    return *this;
}

template <typename T>
inline void IndexedGeometry<T>::clear() {
    m_indices.clear();
    AttribArrayGeometry::clear();
    notify();
}

template <typename T>
inline void IndexedGeometry<T>::copy( const IndexedGeometry<IndexType>& other ) {
    AttribArrayGeometry::copyBaseGeometry( other );
    m_indices = other.m_indices;
    notify();
}

template <typename T>
inline void IndexedGeometry<T>::checkConsistency() const {
#ifdef CORE_DEBUG
    const auto nbVertices = vertices().size();
    std::vector<bool> visited( nbVertices, false );
    for ( uint t = 0; t < m_indices.size(); ++t )
    {
        const IndexType& face = m_indices[t];
        for ( uint i = 0; i < IndexType::RowsAtCompileTime; ++i )
        {
            CORE_ASSERT( uint( face[i] ) < nbVertices,
                         "Vertex " << face[i] << " is out of bound, in face " << t << " (#" << i
                                   << ")" );
            visited[face[i]] = true;
        }
        CORE_WARN_IF( IndexType::RowsAtCompileTime == 3 &&
                          !( Geometry::triangleArea( vertices()[face[0]],
                                                     vertices()[face[1]],
                                                     vertices()[face[2]] ) > 0.f ),
                      "triangle " << t << " is degenerate" );
    }

    for ( uint v = 0; v < nbVertices; ++v )
    {
        CORE_ASSERT( visited[v], "Vertex " << v << " does not belong to any triangle" );
    }

    // Always have the same number of vertex data and vertices
    CORE_ASSERT( vertices().size() == normals().size(), "Inconsistent number of normals" );
#endif
}

template <typename T>
inline bool IndexedGeometry<T>::append( const IndexedGeometry<IndexType>& other ) {
    const std::size_t verticesBefore  = vertices().size();
    const std::size_t trianglesBefore = m_indices.size();

    // check same attributes through names
    if ( !AttribArrayGeometry::append( other ) ) return false;

    // now we can proceed topology
    m_indices.insert( m_indices.end(), other.m_indices.cbegin(), other.m_indices.cend() );

    // Offset the vertex indices in the triangles and faces
    for ( size_t t = trianglesBefore; t < m_indices.size(); ++t )
    {
        for ( uint i = 0; i < IndexType::RowsAtCompileTime; ++i )
        {
            m_indices[t][i] += verticesBefore;
        }
    }
    notify();
    return true;
}

template <typename T>
const typename IndexedGeometry<T>::IndexContainerType& IndexedGeometry<T>::getIndices() const {
    return m_indices;
}

template <typename T>
typename IndexedGeometry<T>::IndexContainerType& IndexedGeometry<T>::getIndicesWithLock() {
    CORE_ASSERT( !m_isIndicesLocked, "try to get already locked indices" );
    m_isIndicesLocked = true;
    return m_indices;
}

template <typename T>
void IndexedGeometry<T>::indicesUnlock() {
    CORE_ASSERT( !m_isIndicesLocked, "try unlock not locked indices" );
    m_isIndicesLocked = false;
    notify();
}

template <typename T>
void IndexedGeometry<T>::setIndices( IndexContainerType&& indices ) {
    CORE_ASSERT( !m_isIndicesLocked, "try set already locked indices" );
    m_indices = std::move( indices );
    notify();
}

} // namespace Geometry
} // namespace Core
} // namespace Ra
<commit_msg>[Core] TriangleMesh: typo in assert.<commit_after>#include "TriangleMesh.hpp"
#include <Core/Geometry/TriangleOperation.hpp> // triangleArea

namespace Ra {
namespace Core {
namespace Geometry {

inline AttribArrayGeometry ::AttribArrayGeometry( const AttribArrayGeometry& other ) :
    AbstractGeometry( other ) {
    m_vertexAttribs.copyAllAttributes( other.m_vertexAttribs );
    m_verticesHandle = other.m_verticesHandle;
    m_normalsHandle  = other.m_normalsHandle;
}

inline AttribArrayGeometry::AttribArrayGeometry( AttribArrayGeometry&& other ) :
    m_vertexAttribs( std::move( other.m_vertexAttribs ) ),
    m_verticesHandle( std::move( other.m_verticesHandle ) ),
    m_normalsHandle( std::move( other.m_normalsHandle ) ) {}

inline AttribArrayGeometry& AttribArrayGeometry::operator=( const AttribArrayGeometry& other ) {
    if ( this != &other )
    {
        m_vertexAttribs.clear();
        m_vertexAttribs.copyAllAttributes( other.m_vertexAttribs );
        m_verticesHandle = other.m_verticesHandle;
        m_normalsHandle  = other.m_normalsHandle;
    }
    return *this;
}

inline AttribArrayGeometry& AttribArrayGeometry::operator=( AttribArrayGeometry&& other ) {
    if ( this != &other )
    {
        m_vertexAttribs  = std::move( other.m_vertexAttribs );
        m_verticesHandle = std::move( other.m_verticesHandle );
        m_normalsHandle  = std::move( other.m_normalsHandle );
    }
    return *this;
}

inline void AttribArrayGeometry::clear() {
    m_vertexAttribs.clear();
    // restore the default attribs (empty though)
    initDefaultAttribs();
}

inline void AttribArrayGeometry::copyBaseGeometry( const AttribArrayGeometry& other ) {
    clear();
    m_vertexAttribs.copyAttributes(
        other.m_vertexAttribs, other.m_verticesHandle, other.m_normalsHandle );
}

template <typename... Handles>
inline bool AttribArrayGeometry::copyAttributes( const AttribArrayGeometry& input,
                                                 Handles... attribs ) {
    if ( vertices().size() != input.vertices().size() ) return false;
    // copy attribs
    m_vertexAttribs.copyAttributes( input.m_vertexAttribs, attribs... );
    return true;
}

inline bool AttribArrayGeometry::copyAllAttributes( const AttribArrayGeometry& input ) {
    if ( vertices().size() != input.vertices().size() ) return false;
    // copy attribs
    m_vertexAttribs.copyAllAttributes( input.m_vertexAttribs );
    return true;
}

inline Aabb AttribArrayGeometry::computeAabb() const {
    Aabb aabb;
    for ( const auto& v : vertices() )
    {
        aabb.extend( v );
    }
    return aabb;
}

inline void AttribArrayGeometry::setVertices( PointAttribHandle::Container&& vertices ) {
    m_vertexAttribs.setAttrib( m_verticesHandle, std::move( vertices ) );
}

inline void AttribArrayGeometry::setVertices( const PointAttribHandle::Container& vertices ) {
    m_vertexAttribs.setAttrib<PointAttribHandle::value_type>( m_verticesHandle, vertices );
}

inline const AttribArrayGeometry::PointAttribHandle::Container&
AttribArrayGeometry::vertices() const {
    return m_vertexAttribs.getAttrib( m_verticesHandle ).data();
}

inline void AttribArrayGeometry::setNormals( PointAttribHandle::Container&& normals ) {
    m_vertexAttribs.setAttrib( m_normalsHandle, std::move( normals ) );
}
inline void AttribArrayGeometry::setNormals( const PointAttribHandle::Container& normals ) {
    m_vertexAttribs.setAttrib( m_normalsHandle, normals );
}

inline const AttribArrayGeometry::NormalAttribHandle::Container&
AttribArrayGeometry::normals() const {
    return m_vertexAttribs.getAttrib( m_normalsHandle ).data();
}

template <typename T>
inline Utils::AttribHandle<T>
AttribArrayGeometry::getAttribHandle( const std::string& name ) const {
    return m_vertexAttribs.findAttrib<T>( name );
}

template <typename T>
inline bool AttribArrayGeometry::isValid( const Utils::AttribHandle<T>& h ) const {
    return m_vertexAttribs.isValid( h );
}

template <typename T>
inline Utils::Attrib<T>& AttribArrayGeometry::getAttrib( const Utils::AttribHandle<T>& h ) {
    return m_vertexAttribs.getAttrib( h );
}

template <typename T>
const Utils::Attrib<T>& AttribArrayGeometry::getAttrib( const Utils::AttribHandle<T>& h ) const {
    return m_vertexAttribs.getAttrib( h );
}

inline Utils::AttribBase* AttribArrayGeometry::getAttribBase( const std::string& name ) {
    return m_vertexAttribs.getAttribBase( name );
}

inline bool AttribArrayGeometry::hasAttrib( const std::string& name ) {
    return m_vertexAttribs.contains( name );
}

template <typename T>
inline Utils::AttribHandle<T> AttribArrayGeometry::addAttrib( const std::string& name ) {
    return m_vertexAttribs.addAttrib<T>( name );
}

template <typename T>
inline Utils::AttribHandle<T>
AttribArrayGeometry::addAttrib( const std::string& name,
                                const typename Core::VectorArray<T>& data ) {
    auto handle = addAttrib<T>( name );
    getAttrib( handle ).setData( data );
    return handle;
}

template <typename T>
inline Utils::AttribHandle<T>
AttribArrayGeometry::addAttrib( const std::string& name,
                                const typename Utils::Attrib<T>::Container&& data ) {
    auto handle = addAttrib<T>( name );
    getAttrib( handle ).setData( std::move( data ) );
    return handle;
}

template <typename T>
inline void AttribArrayGeometry::removeAttrib( Utils::AttribHandle<T>& h ) {
    m_vertexAttribs.removeAttrib( h );
}

inline Utils::AttribManager& AttribArrayGeometry::vertexAttribs() {
    return m_vertexAttribs;
}

inline const Utils::AttribManager& AttribArrayGeometry::vertexAttribs() const {
    return m_vertexAttribs;
}

inline AttribArrayGeometry::PointAttribHandle::Container& AttribArrayGeometry::verticesWithLock() {
    return m_vertexAttribs.getAttrib( m_verticesHandle ).getDataWithLock();
}

inline void AttribArrayGeometry::verticesUnlock() {
    return m_vertexAttribs.getAttrib( m_verticesHandle ).unlock();
}

inline AttribArrayGeometry::NormalAttribHandle::Container& AttribArrayGeometry::normalsWithLock() {
    return m_vertexAttribs.getAttrib( m_normalsHandle ).getDataWithLock();
}

inline void AttribArrayGeometry::normalsUnlock() {
    return m_vertexAttribs.getAttrib( m_normalsHandle ).unlock();
}

inline void AttribArrayGeometry::initDefaultAttribs() {
    m_verticesHandle = m_vertexAttribs.addAttrib<PointAttribHandle::value_type>( "in_position" );
    m_normalsHandle  = m_vertexAttribs.addAttrib<NormalAttribHandle::value_type>( "in_normal" );
}

template <typename T>
inline void AttribArrayGeometry::append_attrib( Utils::AttribBase* attr ) {
    auto h         = m_vertexAttribs.findAttrib<T>( attr->getName() );
    auto& v0       = m_vertexAttribs.getAttrib( h ).getDataWithLock();
    const auto& v1 = attr->cast<T>().data();
    v0.insert( v0.end(), v1.cbegin(), v1.cend() );
    m_vertexAttribs.getAttrib( h ).unlock();
}

/*** IndexedGeometry ***/
template <typename T>
inline IndexedGeometry<T>::IndexedGeometry( const IndexedGeometry<IndexType>& other ) :
    AttribArrayGeometry( other ), m_indices( other.m_indices ) {}

template <typename T>
inline IndexedGeometry<T>::IndexedGeometry( IndexedGeometry<IndexType>&& other ) :
    AttribArrayGeometry( std::move( other ) ), m_indices( std::move( other.m_indices ) ) {}

template <typename T>
inline IndexedGeometry<T>&
IndexedGeometry<T>::operator=( const IndexedGeometry<IndexType>& other ) {
    AttribArrayGeometry::operator=( other );
    m_indices                    = other.m_indices;
    notify();
    return *this;
}

template <typename T>
inline IndexedGeometry<T>& IndexedGeometry<T>::operator=( IndexedGeometry<IndexType>&& other ) {
    AttribArrayGeometry::operator=( std::move( other ) );
    m_indices                    = std::move( other.m_indices );
    notify();
    return *this;
}

template <typename T>
inline void IndexedGeometry<T>::clear() {
    m_indices.clear();
    AttribArrayGeometry::clear();
    notify();
}

template <typename T>
inline void IndexedGeometry<T>::copy( const IndexedGeometry<IndexType>& other ) {
    AttribArrayGeometry::copyBaseGeometry( other );
    m_indices = other.m_indices;
    notify();
}

template <typename T>
inline void IndexedGeometry<T>::checkConsistency() const {
#ifdef CORE_DEBUG
    const auto nbVertices = vertices().size();
    std::vector<bool> visited( nbVertices, false );
    for ( uint t = 0; t < m_indices.size(); ++t )
    {
        const IndexType& face = m_indices[t];
        for ( uint i = 0; i < IndexType::RowsAtCompileTime; ++i )
        {
            CORE_ASSERT( uint( face[i] ) < nbVertices,
                         "Vertex " << face[i] << " is out of bound, in face " << t << " (#" << i
                                   << ")" );
            visited[face[i]] = true;
        }
        CORE_WARN_IF( IndexType::RowsAtCompileTime == 3 &&
                          !( Geometry::triangleArea( vertices()[face[0]],
                                                     vertices()[face[1]],
                                                     vertices()[face[2]] ) > 0.f ),
                      "triangle " << t << " is degenerate" );
    }

    for ( uint v = 0; v < nbVertices; ++v )
    {
        CORE_ASSERT( visited[v], "Vertex " << v << " does not belong to any triangle" );
    }

    // Always have the same number of vertex data and vertices
    CORE_ASSERT( vertices().size() == normals().size(), "Inconsistent number of normals" );
#endif
}

template <typename T>
inline bool IndexedGeometry<T>::append( const IndexedGeometry<IndexType>& other ) {
    const std::size_t verticesBefore  = vertices().size();
    const std::size_t trianglesBefore = m_indices.size();

    // check same attributes through names
    if ( !AttribArrayGeometry::append( other ) ) return false;

    // now we can proceed topology
    m_indices.insert( m_indices.end(), other.m_indices.cbegin(), other.m_indices.cend() );

    // Offset the vertex indices in the triangles and faces
    for ( size_t t = trianglesBefore; t < m_indices.size(); ++t )
    {
        for ( uint i = 0; i < IndexType::RowsAtCompileTime; ++i )
        {
            m_indices[t][i] += verticesBefore;
        }
    }
    notify();
    return true;
}

template <typename T>
const typename IndexedGeometry<T>::IndexContainerType& IndexedGeometry<T>::getIndices() const {
    return m_indices;
}

template <typename T>
typename IndexedGeometry<T>::IndexContainerType& IndexedGeometry<T>::getIndicesWithLock() {
    CORE_ASSERT( !m_isIndicesLocked, "try to get already locked indices" );
    m_isIndicesLocked = true;
    return m_indices;
}

template <typename T>
void IndexedGeometry<T>::indicesUnlock() {
    CORE_ASSERT( m_isIndicesLocked, "try unlock not locked indices" );
    m_isIndicesLocked = false;
    notify();
}

template <typename T>
void IndexedGeometry<T>::setIndices( IndexContainerType&& indices ) {
    CORE_ASSERT( !m_isIndicesLocked, "try set already locked indices" );
    m_indices = std::move( indices );
    notify();
}

} // namespace Geometry
} // namespace Core
} // namespace Ra
<|endoftext|>