<commit_before>#include "ArmatureData.h"
#include "UserData.h"
#include "DragonBonesData.h"
#include "ConstraintData.h"
#include "DisplayData.h"
#include "AnimationData.h"

DRAGONBONES_NAMESPACE_BEGIN

void ArmatureData::_onClear()
{
    for (const auto action : defaultActions)
    {
        action->returnToPool();
    }

    for (const auto action : actions)
    {
        action->returnToPool();
    }

    for (const auto& pair : bones)
    {
        pair.second->returnToPool();
    }

    for (const auto& pair : slots)
    {
        pair.second->returnToPool();
    }

    for (const auto& pair : skins)
    {
        pair.second->returnToPool();
    }

    for (const auto& pair : animations)
    {
        pair.second->returnToPool();
    }

    if (userData != nullptr)
    {
        userData->returnToPool();
    }

    type = ArmatureType::Armature;
    frameRate = 0;
    cacheFrameRate = 0;
    scale = 1.0f;
    name = "";
    aabb.clear();
    defaultActions.clear();
    actions.clear();
    bones.clear();
    slots.clear();
    skins.clear();
    animations.clear();
    parent = nullptr;
    defaultSkin = nullptr;
    defaultAnimation = nullptr;
    userData = nullptr;
    // TODO canvas
}

void ArmatureData::sortBones()
{
    const auto total = sortedBones.size();
    if (total <= 0)
    {
        return;
    }

    const auto sortHelper = sortedBones; // Copy.
    unsigned index = 0;
    unsigned count = 0;
    sortedBones.clear();
    while (count < total)
    {
        const auto bone = sortHelper[index++];
        if (index >= total)
        {
            index = 0;
        }

        if (std::find(sortedBones.cbegin(), sortedBones.cend(), bone) != sortedBones.cend())
        {
            continue;
        }

        if(!bone->constraints.empty())
        {
            auto flag = false;
            for(const auto constrait : bone->constraints)
            {
                if(std::find(sortedBones.cbegin(), sortedBones.cend(), constrait->target) == sortedBones.cend())
                {
                    flag = true;
                     break;
                }
            }

            if(flag)
            {
                continue;
            }
        }

        if (bone->parent != nullptr && std::find(sortedBones.cbegin(), sortedBones.cend(), bone->parent) == sortedBones.cend())
        {
            continue;
        }

        sortedBones.push_back(bone);
        count++;
    }
}

void ArmatureData::cacheFrames(unsigned value)
{
    if (cacheFrameRate > value) // TODO clear cache.
    {
        return;
    }

    cacheFrameRate = value;
    for (const auto& pair : animations)
    {
        pair.second->cacheFrames(cacheFrameRate);
    }
}

int ArmatureData::setCacheFrame(const Matrix& globalTransformMatrix, const Transform& transform)
{
    auto& dataArray = *&parent->cachedFrames;
    auto arrayOffset = dataArray.size();

    dataArray.resize(arrayOffset + 10);
    dataArray[arrayOffset] = globalTransformMatrix.a;
    dataArray[arrayOffset + 1] = globalTransformMatrix.b;
    dataArray[arrayOffset + 2] = globalTransformMatrix.c;
    dataArray[arrayOffset + 3] = globalTransformMatrix.d;
    dataArray[arrayOffset + 4] = globalTransformMatrix.tx;
    dataArray[arrayOffset + 5] = globalTransformMatrix.ty;
    dataArray[arrayOffset + 6] = transform.rotation;
    dataArray[arrayOffset + 7] = transform.skew;
    dataArray[arrayOffset + 8] = transform.scaleX;
    dataArray[arrayOffset + 9] = transform.scaleY;

    return arrayOffset;
}

void ArmatureData::getCacheFrame(Matrix& globalTransformMatrix, Transform& transform, unsigned arrayOffset)
{
    auto& dataArray = *&parent->cachedFrames;
    globalTransformMatrix.a = dataArray[arrayOffset];
    globalTransformMatrix.b = dataArray[arrayOffset + 1];
    globalTransformMatrix.c = dataArray[arrayOffset + 2];
    globalTransformMatrix.d = dataArray[arrayOffset + 3];
    globalTransformMatrix.tx = dataArray[arrayOffset + 4];
    globalTransformMatrix.ty = dataArray[arrayOffset + 5];
    transform.rotation = dataArray[arrayOffset + 6];
    transform.skew = dataArray[arrayOffset + 7];
    transform.scaleX = dataArray[arrayOffset + 8];
    transform.scaleY = dataArray[arrayOffset + 9];
    transform.x = globalTransformMatrix.tx;
    transform.y = globalTransformMatrix.ty;
}

void ArmatureData::addBone(BoneData* value)
{
    if (bones.find(value->name) != bones.cend())
    {
        DRAGONBONES_ASSERT(false, "Replace bone: " + value->name);
        bones[value->name]->returnToPool();
    }

    bones[value->name] = value;
    sortedBones.push_back(value);
}

void ArmatureData::addSlot(SlotData* value)
{
    if (slots.find(value->name) != slots.cend())
    {
        DRAGONBONES_ASSERT(false, "Replace slot: " + value->name);
        slots[value->name]->returnToPool();
    }

    slots[value->name] = value;
    sortedSlots.push_back(value);
}

void ArmatureData::addSkin(SkinData* value)
{
    if (skins.find(value->name) != skins.cend())
    {
        DRAGONBONES_ASSERT(false, "Replace skin: " + value->name);
        skins[value->name]->returnToPool();
    }

    skins[value->name] = value;
    if (defaultSkin == nullptr)
    {
        defaultSkin = value;
    }
}

void ArmatureData::addAnimation(AnimationData* value)
{
    if (animations.find(value->name) != animations.cend())
    {
        DRAGONBONES_ASSERT(false, "Replace animation: " + value->name);
        animations[value->name]->returnToPool();
    }

    value->parent = this;
    animations[value->name] = value;
    animationNames.push_back(value->name);
    if (defaultAnimation == nullptr)
    {
        defaultAnimation = value;
    }
}

void BoneData::_onClear()
{
    for (const auto constraint : constraints)
    {
        constraint->returnToPool();
    }

    if (userData != nullptr)
    {
        userData->returnToPool();
    }

    inheritTranslation = false;
    inheritRotation = false;
    inheritScale = false;
    inheritReflection = false;
    length = 0.0f;
    name = "";
    transform.identity();
    constraints.clear();
    parent = nullptr;
    userData = nullptr;
}

ColorTransform SlotData::DEFAULT_COLOR;
ColorTransform* SlotData::createColor()
{
    return new ColorTransform();
}

void SlotData::_onClear()
{
    if (userData != nullptr)
    {
        userData->returnToPool();
    }

    if (color != nullptr && color != &DEFAULT_COLOR)
    {
        delete color;
    }

    blendMode = BlendMode::Normal;
    displayIndex = 0;
    zOrder = 0;
    name = "";
    parent = nullptr;
    color = nullptr;
    userData = nullptr;
}

void SkinData::_onClear()
{
    for (const auto& pair : displays)
    {
        for (const auto display : pair.second)
        {
            if (display != nullptr)
            {
                display->returnToPool();
            }
        }
    }

    name = "";
    displays.clear();
    skinSlotNames.clear();
}

void SkinData::addDisplay(const std::string& slotName, DisplayData* value)
{
    skinSlotNames.push_back(slotName);
    displays[slotName].push_back(value); // TODO clear prev
}

DisplayData* SkinData::getDisplay(const std::string& slotName, const std::string& displayName)
{
    const auto slotDisplays = getDisplays(slotName);
    if (slotDisplays != nullptr)
    {
        for (const auto display : *slotDisplays)
        {
            if (display != nullptr && display->name == displayName)
            {
                return display;
            }
        }
    }

    return nullptr;
}

DRAGONBONES_NAMESPACE_END
<commit_msg>fixed ArmatureData clean bug<commit_after>#include "ArmatureData.h"
#include "UserData.h"
#include "DragonBonesData.h"
#include "ConstraintData.h"
#include "DisplayData.h"
#include "AnimationData.h"

DRAGONBONES_NAMESPACE_BEGIN

void ArmatureData::_onClear()
{
    for (const auto action : defaultActions)
    {
        action->returnToPool();
    }

    for (const auto action : actions)
    {
        action->returnToPool();
    }

    for (const auto& pair : bones)
    {
        pair.second->returnToPool();
    }

    for (const auto& pair : slots)
    {
        pair.second->returnToPool();
    }

    for (const auto& pair : skins)
    {
        pair.second->returnToPool();
    }

    for (const auto& pair : animations)
    {
        pair.second->returnToPool();
    }

    if (userData != nullptr)
    {
        userData->returnToPool();
    }

    type = ArmatureType::Armature;
    frameRate = 0;
    cacheFrameRate = 0;
    scale = 1.0f;
    name = "";
    aabb.clear();
    animationNames.clear();
    sortedBones.clear();
    sortedSlots.clear();
    defaultActions.clear();
    actions.clear();
    bones.clear();
    slots.clear();
    skins.clear();
    animations.clear();
    parent = nullptr;
    defaultSkin = nullptr;
    defaultAnimation = nullptr;
    userData = nullptr;
    // TODO canvas
}

void ArmatureData::sortBones()
{
    const auto total = sortedBones.size();
    if (total <= 0)
    {
        return;
    }

    const auto sortHelper = sortedBones; // Copy.
    unsigned index = 0;
    unsigned count = 0;
    sortedBones.clear();
    while (count < total)
    {
        const auto bone = sortHelper[index++];
        if (index >= total)
        {
            index = 0;
        }

        if (std::find(sortedBones.cbegin(), sortedBones.cend(), bone) != sortedBones.cend())
        {
            continue;
        }

        if(!bone->constraints.empty())
        {
            auto flag = false;
            for(const auto constrait : bone->constraints)
            {
                if(std::find(sortedBones.cbegin(), sortedBones.cend(), constrait->target) == sortedBones.cend())
                {
                    flag = true;
                     break;
                }
            }

            if(flag)
            {
                continue;
            }
        }

        if (bone->parent != nullptr && std::find(sortedBones.cbegin(), sortedBones.cend(), bone->parent) == sortedBones.cend())
        {
            continue;
        }

        sortedBones.push_back(bone);
        count++;
    }
}

void ArmatureData::cacheFrames(unsigned value)
{
    if (cacheFrameRate > value) // TODO clear cache.
    {
        return;
    }

    cacheFrameRate = value;
    for (const auto& pair : animations)
    {
        pair.second->cacheFrames(cacheFrameRate);
    }
}

int ArmatureData::setCacheFrame(const Matrix& globalTransformMatrix, const Transform& transform)
{
    auto& dataArray = *&parent->cachedFrames;
    auto arrayOffset = dataArray.size();

    dataArray.resize(arrayOffset + 10);
    dataArray[arrayOffset] = globalTransformMatrix.a;
    dataArray[arrayOffset + 1] = globalTransformMatrix.b;
    dataArray[arrayOffset + 2] = globalTransformMatrix.c;
    dataArray[arrayOffset + 3] = globalTransformMatrix.d;
    dataArray[arrayOffset + 4] = globalTransformMatrix.tx;
    dataArray[arrayOffset + 5] = globalTransformMatrix.ty;
    dataArray[arrayOffset + 6] = transform.rotation;
    dataArray[arrayOffset + 7] = transform.skew;
    dataArray[arrayOffset + 8] = transform.scaleX;
    dataArray[arrayOffset + 9] = transform.scaleY;

    return arrayOffset;
}

void ArmatureData::getCacheFrame(Matrix& globalTransformMatrix, Transform& transform, unsigned arrayOffset)
{
    auto& dataArray = *&parent->cachedFrames;
    globalTransformMatrix.a = dataArray[arrayOffset];
    globalTransformMatrix.b = dataArray[arrayOffset + 1];
    globalTransformMatrix.c = dataArray[arrayOffset + 2];
    globalTransformMatrix.d = dataArray[arrayOffset + 3];
    globalTransformMatrix.tx = dataArray[arrayOffset + 4];
    globalTransformMatrix.ty = dataArray[arrayOffset + 5];
    transform.rotation = dataArray[arrayOffset + 6];
    transform.skew = dataArray[arrayOffset + 7];
    transform.scaleX = dataArray[arrayOffset + 8];
    transform.scaleY = dataArray[arrayOffset + 9];
    transform.x = globalTransformMatrix.tx;
    transform.y = globalTransformMatrix.ty;
}

void ArmatureData::addBone(BoneData* value)
{
    if (bones.find(value->name) != bones.cend())
    {
        DRAGONBONES_ASSERT(false, "Replace bone: " + value->name);
        bones[value->name]->returnToPool();
    }

    bones[value->name] = value;
    sortedBones.push_back(value);
}

void ArmatureData::addSlot(SlotData* value)
{
    if (slots.find(value->name) != slots.cend())
    {
        DRAGONBONES_ASSERT(false, "Replace slot: " + value->name);
        slots[value->name]->returnToPool();
    }

    slots[value->name] = value;
    sortedSlots.push_back(value);
}

void ArmatureData::addSkin(SkinData* value)
{
    if (skins.find(value->name) != skins.cend())
    {
        DRAGONBONES_ASSERT(false, "Replace skin: " + value->name);
        skins[value->name]->returnToPool();
    }

    skins[value->name] = value;
    if (defaultSkin == nullptr)
    {
        defaultSkin = value;
    }
}

void ArmatureData::addAnimation(AnimationData* value)
{
    if (animations.find(value->name) != animations.cend())
    {
        DRAGONBONES_ASSERT(false, "Replace animation: " + value->name);
        animations[value->name]->returnToPool();
    }

    value->parent = this;
    animations[value->name] = value;
    animationNames.push_back(value->name);
    if (defaultAnimation == nullptr)
    {
        defaultAnimation = value;
    }
}

void BoneData::_onClear()
{
    for (const auto constraint : constraints)
    {
        constraint->returnToPool();
    }

    if (userData != nullptr)
    {
        userData->returnToPool();
    }

    inheritTranslation = false;
    inheritRotation = false;
    inheritScale = false;
    inheritReflection = false;
    length = 0.0f;
    name = "";
    transform.identity();
    constraints.clear();
    parent = nullptr;
    userData = nullptr;
}

ColorTransform SlotData::DEFAULT_COLOR;
ColorTransform* SlotData::createColor()
{
    return new ColorTransform();
}

void SlotData::_onClear()
{
    if (userData != nullptr)
    {
        userData->returnToPool();
    }

    if (color != nullptr && color != &DEFAULT_COLOR)
    {
        delete color;
    }

    blendMode = BlendMode::Normal;
    displayIndex = 0;
    zOrder = 0;
    name = "";
    parent = nullptr;
    color = nullptr;
    userData = nullptr;
}

void SkinData::_onClear()
{
    for (const auto& pair : displays)
    {
        for (const auto display : pair.second)
        {
            if (display != nullptr)
            {
                display->returnToPool();
            }
        }
    }

    name = "";
    displays.clear();
    skinSlotNames.clear();
}

void SkinData::addDisplay(const std::string& slotName, DisplayData* value)
{
    skinSlotNames.push_back(slotName);
    displays[slotName].push_back(value); // TODO clear prev
}

DisplayData* SkinData::getDisplay(const std::string& slotName, const std::string& displayName)
{
    const auto slotDisplays = getDisplays(slotName);
    if (slotDisplays != nullptr)
    {
        for (const auto display : *slotDisplays)
        {
            if (display != nullptr && display->name == displayName)
            {
                return display;
            }
        }
    }

    return nullptr;
}

DRAGONBONES_NAMESPACE_END
<|endoftext|>


<commit_before>//
// gsl-lite is based on GSL: Guidelines Support Library,
// https://github.com/microsoft/gsl
//
// Copyright (c) 2015 Martin Moene
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
//
// This code is licensed under the MIT License (MIT).
//
// 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 "gsl-lite.t.h"

namespace {

CASE( "at(): Allows access to existing C-array elements" )
{
    int a[] = { 1, 2, 3, 4 };

    for ( int i = 0; i < 4; ++i )
    {
        EXPECT( at(a, i) ==  i + 1 );
    }
}

CASE( "at(): Terminates access to non-existing C-array elements" )
{
    int a[] = { 1, 2, 3, 4 };

    EXPECT_THROWS( at(a, 4) );
}

CASE( "at(): Allows access to existing std::array elements" )
{
#if gsl_HAVE_ARRAY
    std::array<int, 4> a = { 1, 2, 3, 4 };

    for ( int i = 0; i < 4; ++i )
    {
        EXPECT( at(a, i) == i + 1 );
    }
#else
    EXPECT( !!"std::array<T> is not available (no C++11)" );
#endif
}

CASE( "at(): Terminates access to non-existing std::array elements" )
{
#if gsl_HAVE_ARRAY
    std::array<int, 4> a = { 1, 2, 3, 4 };

    EXPECT_THROWS( at(a, 4) );
#else
    EXPECT( !!"std::array<T> is not available (no C++11)" );
#endif
}

} // anonymous namespace

#include <vector>

#if gsl_COMPILER_MSVC_VERSION == 6
    gsl_MK_AT( std::vector )
#endif

namespace {

CASE( "at(): Allows access to existing std::vector elements" )
{
    std::vector<int> a; // = { 1, 2, 3, 4 };

    for ( int i = 0; i < 4; ++i )
    {
        a.push_back( i + 1 );
        EXPECT( at(a, i) == i + 1 );
    }
}

CASE( "at(): Terminates access to non-existing std::vector elements" )
{
    std::vector<int> a; // = { 1, 2, 3, 4 };

    for ( int i = 0; i < 4; ++i )
    {
        a.push_back( i + 1 );
    }

    EXPECT_THROWS( at(a, 4) );
}

}

// end of file
<commit_msg>Prevent warning for missing braces<commit_after>//
// gsl-lite is based on GSL: Guidelines Support Library,
// https://github.com/microsoft/gsl
//
// Copyright (c) 2015 Martin Moene
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
//
// This code is licensed under the MIT License (MIT).
//
// 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 "gsl-lite.t.h"

namespace {

CASE( "at(): Allows access to existing C-array elements" )
{
    int a[] = { 1, 2, 3, 4 };

    for ( int i = 0; i < 4; ++i )
    {
        EXPECT( at(a, i) ==  i + 1 );
    }
}

CASE( "at(): Terminates access to non-existing C-array elements" )
{
    int a[] = { 1, 2, 3, 4 };

    EXPECT_THROWS( at(a, 4) );
}

CASE( "at(): Allows access to existing std::array elements" )
{
#if gsl_HAVE_ARRAY
    std::array<int, 4> a = {{ 1, 2, 3, 4 }};

    for ( int i = 0; i < 4; ++i )
    {
        EXPECT( at(a, i) == i + 1 );
    }
#else
    EXPECT( !!"std::array<T> is not available (no C++11)" );
#endif
}

CASE( "at(): Terminates access to non-existing std::array elements" )
{
#if gsl_HAVE_ARRAY
    std::array<int, 4> a = {{ 1, 2, 3, 4 }};

    EXPECT_THROWS( at(a, 4) );
#else
    EXPECT( !!"std::array<T> is not available (no C++11)" );
#endif
}

} // anonymous namespace

#include <vector>

#if gsl_COMPILER_MSVC_VERSION == 6
    gsl_MK_AT( std::vector )
#endif

namespace {

CASE( "at(): Allows access to existing std::vector elements" )
{
    std::vector<int> a; // = { 1, 2, 3, 4 };

    for ( int i = 0; i < 4; ++i )
    {
        a.push_back( i + 1 );
        EXPECT( at(a, i) == i + 1 );
    }
}

CASE( "at(): Terminates access to non-existing std::vector elements" )
{
    std::vector<int> a; // = { 1, 2, 3, 4 };

    for ( int i = 0; i < 4; ++i )
    {
        a.push_back( i + 1 );
    }

    EXPECT_THROWS( at(a, 4) );
}

}

// end of file
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2008-2018 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, you can obtain one at http://mozilla.org/MPL/2.0/
 *
 * MRtrix3 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.
 *
 * For more details, see http://www.mrtrix.org/
 */

#include <mutex>

#include "command.h"
#include "image.h"
#include "progressbar.h"
#include "thread_queue.h"
#include "types.h"

#include "algo/loop.h"
#include "adapter/subset.h"

#include "connectome/connectome.h"

#include "surface/mesh.h"
#include "surface/mesh_multi.h"
#include "surface/algo/image2mesh.h"

using namespace MR;
using namespace App;
using namespace MR::Surface;

void usage ()
{

  AUTHOR = "Robert E. Smith (robert.smith@florey.edu.au)";

  SYNOPSIS = "Generate meshes from a label image";

  ARGUMENTS
  + Argument ("nodes_in", "the input node parcellation image").type_image_in()
  + Argument ("mesh_out", "the output mesh file").type_file_out();

  OPTIONS
  + Option ("blocky", "generate 'blocky' meshes with precise delineation of voxel edges, "
                      "rather than the default Marching Cubes approach");

}

void run ()
{

  Header labels_header = Header::open (argument[0]);
  Connectome::check (labels_header);
  check_3D_nonunity (labels_header);
  auto labels = labels_header.get_image<uint32_t>();

  using voxel_corner_t = Eigen::Array<int, 3, 1>;

  vector<voxel_corner_t> lower_corners, upper_corners;

  {
    for (auto i = Loop ("Importing label image", labels) (labels); i; ++i) {
      const uint32_t index = labels.value();
      if (index) {

        if (index >= lower_corners.size()) {
          lower_corners.resize (index+1, voxel_corner_t (labels.size(0), labels.size(1), labels.size(2)));
          upper_corners.resize (index+1, voxel_corner_t (-1, -1, -1));
        }

        for (size_t axis = 0; axis != 3; ++axis) {
          lower_corners[index][axis] = std::min (lower_corners[index][axis], int(labels.index (axis)));
          upper_corners[index][axis] = std::max (upper_corners[index][axis], int(labels.index (axis)));
        }

      }
    }
  }

  MeshMulti meshes (lower_corners.size(), MR::Surface::Mesh());
  meshes[0].set_name ("none");
  const bool blocky = get_options ("blocky").size();

  {
    std::mutex mutex;
    ProgressBar progress ("Generating meshes from labels", lower_corners.size() - 1);
    auto loader = [&] (size_t& out) { static size_t i = 1; out = i++; return (out != lower_corners.size()); };

    auto worker = [&] (const size_t& in)
    {
      vector<int> from, dimensions;
      for (size_t axis = 0; axis != 3; ++axis) {
        from.push_back (lower_corners[in][axis]);
        dimensions.push_back (upper_corners[in][axis] - lower_corners[in][axis] + 1);
      }
      Adapter::Subset<Image<uint32_t>> subset (labels, from, dimensions);

      auto scratch = Image<bool>::scratch (subset, "Node " + str(in) + " mask");
      for (auto i = Loop (subset) (subset, scratch); i; ++i)
        scratch.value() = (subset.value() == in);

      if (blocky)
        MR::Surface::Algo::image2mesh_blocky (scratch, meshes[in]);
      else
        MR::Surface::Algo::image2mesh_mc (scratch, meshes[in], 0.5);
      meshes[in].set_name (str(in));
      std::lock_guard<std::mutex> lock (mutex);
      ++progress;
      return true;
    };

    Thread::run_queue (loader, size_t(), Thread::multi (worker));
  }

  meshes.save (argument[1]);
}

<commit_msg>label2mesh: Skip absent parcels<commit_after>/*
 * Copyright (c) 2008-2018 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, you can obtain one at http://mozilla.org/MPL/2.0/
 *
 * MRtrix3 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.
 *
 * For more details, see http://www.mrtrix.org/
 */

#include <mutex>

#include "command.h"
#include "image.h"
#include "progressbar.h"
#include "thread_queue.h"
#include "types.h"

#include "algo/loop.h"
#include "adapter/subset.h"

#include "connectome/connectome.h"

#include "surface/mesh.h"
#include "surface/mesh_multi.h"
#include "surface/algo/image2mesh.h"

using namespace MR;
using namespace App;
using namespace MR::Surface;

void usage ()
{

  AUTHOR = "Robert E. Smith (robert.smith@florey.edu.au)";

  SYNOPSIS = "Generate meshes from a label image";

  ARGUMENTS
  + Argument ("nodes_in", "the input node parcellation image").type_image_in()
  + Argument ("mesh_out", "the output mesh file").type_file_out();

  OPTIONS
  + Option ("blocky", "generate 'blocky' meshes with precise delineation of voxel edges, "
                      "rather than the default Marching Cubes approach");

}

void run ()
{

  Header labels_header = Header::open (argument[0]);
  Connectome::check (labels_header);
  check_3D_nonunity (labels_header);
  auto labels = labels_header.get_image<uint32_t>();

  using voxel_corner_t = Eigen::Array<int, 3, 1>;

  vector<voxel_corner_t> lower_corners, upper_corners;
  {
    for (auto i = Loop ("Importing label image", labels) (labels); i; ++i) {
      const uint32_t index = labels.value();
      if (index) {

        if (index >= lower_corners.size()) {
          lower_corners.resize (index+1, voxel_corner_t (labels.size(0), labels.size(1), labels.size(2)));
          upper_corners.resize (index+1, voxel_corner_t (-1, -1, -1));
        }

        for (size_t axis = 0; axis != 3; ++axis) {
          lower_corners[index][axis] = std::min (lower_corners[index][axis], int(labels.index (axis)));
          upper_corners[index][axis] = std::max (upper_corners[index][axis], int(labels.index (axis)));
        }

      }
    }
  }

  MeshMulti meshes (lower_corners.size(), MR::Surface::Mesh());
  meshes[0].set_name ("none");
  const bool blocky = get_options ("blocky").size();

  {
    std::mutex mutex;
    ProgressBar progress ("Generating meshes from labels", lower_corners.size() - 1);
    auto loader = [&] (size_t& out) { static size_t i = 1; out = i++; return (out != lower_corners.size()); };

    auto worker = [&] (const size_t& in)
    {
      meshes[in].set_name (str(in));
      vector<int> from, dimensions;
      for (size_t axis = 0; axis != 3; ++axis) {
        from.push_back (lower_corners[in][axis]);
        dimensions.push_back (upper_corners[in][axis] - lower_corners[in][axis] + 1);
        if (dimensions.back() < 1) {
          std::lock_guard<std::mutex> lock (mutex);
          WARN ("Index " + str(in) + " absent from label image; mesh data will be empty");
          return true;
        }
      }

      Adapter::Subset<Image<uint32_t>> subset (labels, from, dimensions);

      auto scratch = Image<bool>::scratch (subset, "Node " + str(in) + " mask");
      for (auto i = Loop (subset) (subset, scratch); i; ++i)
        scratch.value() = (subset.value() == in);

      if (blocky)
        MR::Surface::Algo::image2mesh_blocky (scratch, meshes[in]);
      else
        MR::Surface::Algo::image2mesh_mc (scratch, meshes[in], 0.5);
      std::lock_guard<std::mutex> lock (mutex);
      ++progress;
      return true;
    };

    Thread::run_queue (loader, size_t(), Thread::multi (worker));
  }

  meshes.save (argument[1]);
}

<|endoftext|>


<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2009 Torus Knot Software Ltd

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 "OgreStableHeaders.h"
#include "OgreMatrix4.h"

#include "OgreVector3.h"
#include "OgreMatrix3.h"

namespace Ogre
{

    const Matrix4 Matrix4::ZERO(
        0, 0, 0, 0,
        0, 0, 0, 0,
        0, 0, 0, 0,
        0, 0, 0, 0 );

    const Matrix4 Matrix4::IDENTITY(
        1, 0, 0, 0,
        0, 1, 0, 0,
        0, 0, 1, 0,
        0, 0, 0, 1 );

    const Matrix4 Matrix4::CLIPSPACE2DTOIMAGESPACE(
        0.5,    0,  0, 0.5,
          0, -0.5,  0, 0.5,
          0,    0,  1,   0,
          0,    0,  0,   1);

    //-----------------------------------------------------------------------
    inline static Real
        MINOR(const Matrix4& m, const size_t r0, const size_t r1, const size_t r2,
								const size_t c0, const size_t c1, const size_t c2)
    {
        return m[r0][c0] * (m[r1][c1] * m[r2][c2] - m[r2][c1] * m[r1][c2]) -
            m[r0][c1] * (m[r1][c0] * m[r2][c2] - m[r2][c0] * m[r1][c2]) +
            m[r0][c2] * (m[r1][c0] * m[r2][c1] - m[r2][c0] * m[r1][c1]);
    }
    //-----------------------------------------------------------------------
    Matrix4 Matrix4::adjoint() const
    {
        return Matrix4( MINOR(*this, 1, 2, 3, 1, 2, 3),
            -MINOR(*this, 0, 2, 3, 1, 2, 3),
            MINOR(*this, 0, 1, 3, 1, 2, 3),
            -MINOR(*this, 0, 1, 2, 1, 2, 3),

            -MINOR(*this, 1, 2, 3, 0, 2, 3),
            MINOR(*this, 0, 2, 3, 0, 2, 3),
            -MINOR(*this, 0, 1, 3, 0, 2, 3),
            MINOR(*this, 0, 1, 2, 0, 2, 3),

            MINOR(*this, 1, 2, 3, 0, 1, 3),
            -MINOR(*this, 0, 2, 3, 0, 1, 3),
            MINOR(*this, 0, 1, 3, 0, 1, 3),
            -MINOR(*this, 0, 1, 2, 0, 1, 3),

            -MINOR(*this, 1, 2, 3, 0, 1, 2),
            MINOR(*this, 0, 2, 3, 0, 1, 2),
            -MINOR(*this, 0, 1, 3, 0, 1, 2),
            MINOR(*this, 0, 1, 2, 0, 1, 2));
    }
    //-----------------------------------------------------------------------
    Real Matrix4::determinant() const
    {
        return m[0][0] * MINOR(*this, 1, 2, 3, 1, 2, 3) -
            m[0][1] * MINOR(*this, 1, 2, 3, 0, 2, 3) +
            m[0][2] * MINOR(*this, 1, 2, 3, 0, 1, 3) -
            m[0][3] * MINOR(*this, 1, 2, 3, 0, 1, 2);
    }
    //-----------------------------------------------------------------------
    Matrix4 Matrix4::inverse() const
    {
        Real m00 = m[0][0], m01 = m[0][1], m02 = m[0][2], m03 = m[0][3];
        Real m10 = m[1][0], m11 = m[1][1], m12 = m[1][2], m13 = m[1][3];
        Real m20 = m[2][0], m21 = m[2][1], m22 = m[2][2], m23 = m[2][3];
        Real m30 = m[3][0], m31 = m[3][1], m32 = m[3][2], m33 = m[3][3];

        Real v0 = m20 * m31 - m21 * m30;
        Real v1 = m20 * m32 - m22 * m30;
        Real v2 = m20 * m33 - m23 * m30;
        Real v3 = m21 * m32 - m22 * m31;
        Real v4 = m21 * m33 - m23 * m31;
        Real v5 = m22 * m33 - m23 * m32;

        Real t00 = + (v5 * m11 - v4 * m12 + v3 * m13);
        Real t10 = - (v5 * m10 - v2 * m12 + v1 * m13);
        Real t20 = + (v4 * m10 - v2 * m11 + v0 * m13);
        Real t30 = - (v3 * m10 - v1 * m11 + v0 * m12);

        Real invDet = 1 / (t00 * m00 + t10 * m01 + t20 * m02 + t30 * m03);

        Real d00 = t00 * invDet;
        Real d10 = t10 * invDet;
        Real d20 = t20 * invDet;
        Real d30 = t30 * invDet;

        Real d01 = - (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
        Real d11 = + (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
        Real d21 = - (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
        Real d31 = + (v3 * m00 - v1 * m01 + v0 * m02) * invDet;

        v0 = m10 * m31 - m11 * m30;
        v1 = m10 * m32 - m12 * m30;
        v2 = m10 * m33 - m13 * m30;
        v3 = m11 * m32 - m12 * m31;
        v4 = m11 * m33 - m13 * m31;
        v5 = m12 * m33 - m13 * m32;

        Real d02 = + (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
        Real d12 = - (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
        Real d22 = + (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
        Real d32 = - (v3 * m00 - v1 * m01 + v0 * m02) * invDet;

        v0 = m21 * m10 - m20 * m11;
        v1 = m22 * m10 - m20 * m12;
        v2 = m23 * m10 - m20 * m13;
        v3 = m22 * m11 - m21 * m12;
        v4 = m23 * m11 - m21 * m13;
        v5 = m23 * m12 - m22 * m13;

        Real d03 = - (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
        Real d13 = + (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
        Real d23 = - (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
        Real d33 = + (v3 * m00 - v1 * m01 + v0 * m02) * invDet;

        return Matrix4(
            d00, d01, d02, d03,
            d10, d11, d12, d13,
            d20, d21, d22, d23,
            d30, d31, d32, d33);
    }
    //-----------------------------------------------------------------------
    Matrix4 Matrix4::inverseAffine(void) const
    {
        assert(isAffine());

        Real m10 = m[1][0], m11 = m[1][1], m12 = m[1][2];
        Real m20 = m[2][0], m21 = m[2][1], m22 = m[2][2];

        Real t00 = m22 * m11 - m21 * m12;
        Real t10 = m20 * m12 - m22 * m10;
        Real t20 = m21 * m10 - m20 * m11;

        Real m00 = m[0][0], m01 = m[0][1], m02 = m[0][2];

        Real invDet = 1 / (m00 * t00 + m01 * t10 + m02 * t20);

        t00 *= invDet; t10 *= invDet; t20 *= invDet;

        m00 *= invDet; m01 *= invDet; m02 *= invDet;

        Real r00 = t00;
        Real r01 = m02 * m21 - m01 * m22;
        Real r02 = m01 * m12 - m02 * m11;

        Real r10 = t10;
        Real r11 = m00 * m22 - m02 * m20;
        Real r12 = m02 * m10 - m00 * m12;

        Real r20 = t20;
        Real r21 = m01 * m20 - m00 * m21;
        Real r22 = m00 * m11 - m01 * m10;

        Real m03 = m[0][3], m13 = m[1][3], m23 = m[2][3];

        Real r03 = - (r00 * m03 + r01 * m13 + r02 * m23);
        Real r13 = - (r10 * m03 + r11 * m13 + r12 * m23);
        Real r23 = - (r20 * m03 + r21 * m13 + r22 * m23);

        return Matrix4(
            r00, r01, r02, r03,
            r10, r11, r12, r13,
            r20, r21, r22, r23,
              0,   0,   0,   1);
    }
    //-----------------------------------------------------------------------
    void Matrix4::makeTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation)
    {
        // Ordering:
        //    1. Scale
        //    2. Rotate
        //    3. Translate

        Matrix3 rot3x3;
        orientation.ToRotationMatrix(rot3x3);

        // Set up final matrix with scale, rotation and translation
        m[0][0] = scale.x * rot3x3[0][0]; m[0][1] = scale.y * rot3x3[0][1]; m[0][2] = scale.z * rot3x3[0][2]; m[0][3] = position.x;
        m[1][0] = scale.x * rot3x3[1][0]; m[1][1] = scale.y * rot3x3[1][1]; m[1][2] = scale.z * rot3x3[1][2]; m[1][3] = position.y;
        m[2][0] = scale.x * rot3x3[2][0]; m[2][1] = scale.y * rot3x3[2][1]; m[2][2] = scale.z * rot3x3[2][2]; m[2][3] = position.z;

        // No projection term
        m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
    }
    //-----------------------------------------------------------------------
    void Matrix4::makeInverseTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation)
    {
        // Invert the parameters
        Vector3 invTranslate = -position;
        Vector3 invScale(1 / scale.x, 1 / scale.y, 1 / scale.z);
        Quaternion invRot = orientation.Inverse();

        // Because we're inverting, order is translation, rotation, scale
        // So make translation relative to scale & rotation
        invTranslate *= invScale; // scale
        invTranslate = invRot * invTranslate; // rotate

        // Next, make a 3x3 rotation matrix
        Matrix3 rot3x3;
        invRot.ToRotationMatrix(rot3x3);

        // Set up final matrix with scale, rotation and translation
        m[0][0] = invScale.x * rot3x3[0][0]; m[0][1] = invScale.x * rot3x3[0][1]; m[0][2] = invScale.x * rot3x3[0][2]; m[0][3] = invTranslate.x;
        m[1][0] = invScale.y * rot3x3[1][0]; m[1][1] = invScale.y * rot3x3[1][1]; m[1][2] = invScale.y * rot3x3[1][2]; m[1][3] = invTranslate.y;
        m[2][0] = invScale.z * rot3x3[2][0]; m[2][1] = invScale.z * rot3x3[2][1]; m[2][2] = invScale.z * rot3x3[2][2]; m[2][3] = invTranslate.z;

        // No projection term
        m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
    }
    //-----------------------------------------------------------------------
	void Matrix4::decomposition(Vector3& position, Vector3& scale, Quaternion& orientation) const
	{
		assert(isAffine());

		Matrix3 m3x3;
		extract3x3Matrix(m3x3);

		Matrix3 matQ;
		Vector3 vecU;
		m3x3.QDUDecomposition( matQ, scale, vecU );

		orientation = Quaternion( matQ );
		position = Vector3( m[0][3], m[1][3], m[2][3] );
	}

}
<commit_msg>Patch 2979431: Matrix4::makeInverseTransform bug with non-uniform scale<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2009 Torus Knot Software Ltd

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 "OgreStableHeaders.h"
#include "OgreMatrix4.h"

#include "OgreVector3.h"
#include "OgreMatrix3.h"

namespace Ogre
{

    const Matrix4 Matrix4::ZERO(
        0, 0, 0, 0,
        0, 0, 0, 0,
        0, 0, 0, 0,
        0, 0, 0, 0 );

    const Matrix4 Matrix4::IDENTITY(
        1, 0, 0, 0,
        0, 1, 0, 0,
        0, 0, 1, 0,
        0, 0, 0, 1 );

    const Matrix4 Matrix4::CLIPSPACE2DTOIMAGESPACE(
        0.5,    0,  0, 0.5,
          0, -0.5,  0, 0.5,
          0,    0,  1,   0,
          0,    0,  0,   1);

    //-----------------------------------------------------------------------
    inline static Real
        MINOR(const Matrix4& m, const size_t r0, const size_t r1, const size_t r2,
								const size_t c0, const size_t c1, const size_t c2)
    {
        return m[r0][c0] * (m[r1][c1] * m[r2][c2] - m[r2][c1] * m[r1][c2]) -
            m[r0][c1] * (m[r1][c0] * m[r2][c2] - m[r2][c0] * m[r1][c2]) +
            m[r0][c2] * (m[r1][c0] * m[r2][c1] - m[r2][c0] * m[r1][c1]);
    }
    //-----------------------------------------------------------------------
    Matrix4 Matrix4::adjoint() const
    {
        return Matrix4( MINOR(*this, 1, 2, 3, 1, 2, 3),
            -MINOR(*this, 0, 2, 3, 1, 2, 3),
            MINOR(*this, 0, 1, 3, 1, 2, 3),
            -MINOR(*this, 0, 1, 2, 1, 2, 3),

            -MINOR(*this, 1, 2, 3, 0, 2, 3),
            MINOR(*this, 0, 2, 3, 0, 2, 3),
            -MINOR(*this, 0, 1, 3, 0, 2, 3),
            MINOR(*this, 0, 1, 2, 0, 2, 3),

            MINOR(*this, 1, 2, 3, 0, 1, 3),
            -MINOR(*this, 0, 2, 3, 0, 1, 3),
            MINOR(*this, 0, 1, 3, 0, 1, 3),
            -MINOR(*this, 0, 1, 2, 0, 1, 3),

            -MINOR(*this, 1, 2, 3, 0, 1, 2),
            MINOR(*this, 0, 2, 3, 0, 1, 2),
            -MINOR(*this, 0, 1, 3, 0, 1, 2),
            MINOR(*this, 0, 1, 2, 0, 1, 2));
    }
    //-----------------------------------------------------------------------
    Real Matrix4::determinant() const
    {
        return m[0][0] * MINOR(*this, 1, 2, 3, 1, 2, 3) -
            m[0][1] * MINOR(*this, 1, 2, 3, 0, 2, 3) +
            m[0][2] * MINOR(*this, 1, 2, 3, 0, 1, 3) -
            m[0][3] * MINOR(*this, 1, 2, 3, 0, 1, 2);
    }
    //-----------------------------------------------------------------------
    Matrix4 Matrix4::inverse() const
    {
        Real m00 = m[0][0], m01 = m[0][1], m02 = m[0][2], m03 = m[0][3];
        Real m10 = m[1][0], m11 = m[1][1], m12 = m[1][2], m13 = m[1][3];
        Real m20 = m[2][0], m21 = m[2][1], m22 = m[2][2], m23 = m[2][3];
        Real m30 = m[3][0], m31 = m[3][1], m32 = m[3][2], m33 = m[3][3];

        Real v0 = m20 * m31 - m21 * m30;
        Real v1 = m20 * m32 - m22 * m30;
        Real v2 = m20 * m33 - m23 * m30;
        Real v3 = m21 * m32 - m22 * m31;
        Real v4 = m21 * m33 - m23 * m31;
        Real v5 = m22 * m33 - m23 * m32;

        Real t00 = + (v5 * m11 - v4 * m12 + v3 * m13);
        Real t10 = - (v5 * m10 - v2 * m12 + v1 * m13);
        Real t20 = + (v4 * m10 - v2 * m11 + v0 * m13);
        Real t30 = - (v3 * m10 - v1 * m11 + v0 * m12);

        Real invDet = 1 / (t00 * m00 + t10 * m01 + t20 * m02 + t30 * m03);

        Real d00 = t00 * invDet;
        Real d10 = t10 * invDet;
        Real d20 = t20 * invDet;
        Real d30 = t30 * invDet;

        Real d01 = - (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
        Real d11 = + (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
        Real d21 = - (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
        Real d31 = + (v3 * m00 - v1 * m01 + v0 * m02) * invDet;

        v0 = m10 * m31 - m11 * m30;
        v1 = m10 * m32 - m12 * m30;
        v2 = m10 * m33 - m13 * m30;
        v3 = m11 * m32 - m12 * m31;
        v4 = m11 * m33 - m13 * m31;
        v5 = m12 * m33 - m13 * m32;

        Real d02 = + (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
        Real d12 = - (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
        Real d22 = + (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
        Real d32 = - (v3 * m00 - v1 * m01 + v0 * m02) * invDet;

        v0 = m21 * m10 - m20 * m11;
        v1 = m22 * m10 - m20 * m12;
        v2 = m23 * m10 - m20 * m13;
        v3 = m22 * m11 - m21 * m12;
        v4 = m23 * m11 - m21 * m13;
        v5 = m23 * m12 - m22 * m13;

        Real d03 = - (v5 * m01 - v4 * m02 + v3 * m03) * invDet;
        Real d13 = + (v5 * m00 - v2 * m02 + v1 * m03) * invDet;
        Real d23 = - (v4 * m00 - v2 * m01 + v0 * m03) * invDet;
        Real d33 = + (v3 * m00 - v1 * m01 + v0 * m02) * invDet;

        return Matrix4(
            d00, d01, d02, d03,
            d10, d11, d12, d13,
            d20, d21, d22, d23,
            d30, d31, d32, d33);
    }
    //-----------------------------------------------------------------------
    Matrix4 Matrix4::inverseAffine(void) const
    {
        assert(isAffine());

        Real m10 = m[1][0], m11 = m[1][1], m12 = m[1][2];
        Real m20 = m[2][0], m21 = m[2][1], m22 = m[2][2];

        Real t00 = m22 * m11 - m21 * m12;
        Real t10 = m20 * m12 - m22 * m10;
        Real t20 = m21 * m10 - m20 * m11;

        Real m00 = m[0][0], m01 = m[0][1], m02 = m[0][2];

        Real invDet = 1 / (m00 * t00 + m01 * t10 + m02 * t20);

        t00 *= invDet; t10 *= invDet; t20 *= invDet;

        m00 *= invDet; m01 *= invDet; m02 *= invDet;

        Real r00 = t00;
        Real r01 = m02 * m21 - m01 * m22;
        Real r02 = m01 * m12 - m02 * m11;

        Real r10 = t10;
        Real r11 = m00 * m22 - m02 * m20;
        Real r12 = m02 * m10 - m00 * m12;

        Real r20 = t20;
        Real r21 = m01 * m20 - m00 * m21;
        Real r22 = m00 * m11 - m01 * m10;

        Real m03 = m[0][3], m13 = m[1][3], m23 = m[2][3];

        Real r03 = - (r00 * m03 + r01 * m13 + r02 * m23);
        Real r13 = - (r10 * m03 + r11 * m13 + r12 * m23);
        Real r23 = - (r20 * m03 + r21 * m13 + r22 * m23);

        return Matrix4(
            r00, r01, r02, r03,
            r10, r11, r12, r13,
            r20, r21, r22, r23,
              0,   0,   0,   1);
    }
    //-----------------------------------------------------------------------
    void Matrix4::makeTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation)
    {
        // Ordering:
        //    1. Scale
        //    2. Rotate
        //    3. Translate

        Matrix3 rot3x3;
        orientation.ToRotationMatrix(rot3x3);

        // Set up final matrix with scale, rotation and translation
        m[0][0] = scale.x * rot3x3[0][0]; m[0][1] = scale.y * rot3x3[0][1]; m[0][2] = scale.z * rot3x3[0][2]; m[0][3] = position.x;
        m[1][0] = scale.x * rot3x3[1][0]; m[1][1] = scale.y * rot3x3[1][1]; m[1][2] = scale.z * rot3x3[1][2]; m[1][3] = position.y;
        m[2][0] = scale.x * rot3x3[2][0]; m[2][1] = scale.y * rot3x3[2][1]; m[2][2] = scale.z * rot3x3[2][2]; m[2][3] = position.z;

        // No projection term
        m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
    }
    //-----------------------------------------------------------------------
    void Matrix4::makeInverseTransform(const Vector3& position, const Vector3& scale, const Quaternion& orientation)
    {
        // Invert the parameters
        Vector3 invTranslate = -position;
        Vector3 invScale(1 / scale.x, 1 / scale.y, 1 / scale.z);
        Quaternion invRot = orientation.Inverse();

        // Because we're inverting, order is translation, rotation, scale
        // So make translation relative to scale & rotation
        invTranslate = invRot * invTranslate; // rotate
        invTranslate *= invScale; // scale

        // Next, make a 3x3 rotation matrix
        Matrix3 rot3x3;
        invRot.ToRotationMatrix(rot3x3);

        // Set up final matrix with scale, rotation and translation
        m[0][0] = invScale.x * rot3x3[0][0]; m[0][1] = invScale.x * rot3x3[0][1]; m[0][2] = invScale.x * rot3x3[0][2]; m[0][3] = invTranslate.x;
        m[1][0] = invScale.y * rot3x3[1][0]; m[1][1] = invScale.y * rot3x3[1][1]; m[1][2] = invScale.y * rot3x3[1][2]; m[1][3] = invTranslate.y;
        m[2][0] = invScale.z * rot3x3[2][0]; m[2][1] = invScale.z * rot3x3[2][1]; m[2][2] = invScale.z * rot3x3[2][2]; m[2][3] = invTranslate.z;

        // No projection term
        m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
    }
    //-----------------------------------------------------------------------
	void Matrix4::decomposition(Vector3& position, Vector3& scale, Quaternion& orientation) const
	{
		assert(isAffine());

		Matrix3 m3x3;
		extract3x3Matrix(m3x3);

		Matrix3 matQ;
		Vector3 vecU;
		m3x3.QDUDecomposition( matQ, scale, vecU );

		orientation = Quaternion( matQ );
		position = Vector3( m[0][3], m[1][3], m[2][3] );
	}

}
<|endoftext|>


<commit_before>/*
 * Fonction
 * ~~~~~~~~
 *   Gestion des extensions sous OpenGL
 *
 *
 * Attention:
 * ~~~~~~~~~~~
 *  Ce package a ete teste sur SGI, OSF, SUN,  HP et WNT.
 *
 * Remarques:
 * ~~~~~~~~~~~
 *  Le InitExtensionGLX permet d'initialiser le display. Ceci est necessaire
 *  pour travailler sur les extensions de GLX. On ne peut appeler QueryExtensionGLX
 *  si on n'a pas fait cette manip.
 *  Par contre QueryExtension gere les extensions a GL,  on n'a pas besoin du
 *  Display.
 *
 *  Pour l'instant on ne gere pas les extensions a GLU et a WGL.
 *
 * Historique des modifications
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *   14-10-97: FMN ; Creation
 *   23-10-97: FMN ; Ajout gestion glx
 *   19-11-97: FMN ; Ajout GetCurrentDisplay
 *   04-12-97: FMN ; Ajout supportsOneDotOne
 *   19-06-98: FMN ; Portage Optimizer (C++)
 */
/*----------------------------------------------------------------------*/

#ifndef _OPENGL_EXTENSION_H__
#define _OPENGL_EXTENSION_H__

/*----------------------------------------------------------------------*/
/*
 * Includes
 */

#if defined(WNT) && !defined(HAVE_NO_DLL)
# ifdef __OpenGl_DLL
#  define EXPORT __declspec(dllexport)
# else
#  define EXPORT
# endif  /* DLL */
# ifdef STRICT
#  undef STRICT
# endif
# define STRICT
# include <windows.h>
#else
# define EXPORT
#endif  /* WNT */

#include <GL/gl.h>
#include <GL/glu.h>

#ifdef WNT
# include <windows.h>
# ifndef Display
# define Display char
# endif  /* Display */
#else
# include <GL/glx.h>
#endif /* WNT */

#ifdef GL_VERSION_1_1
#define GL_EXT_vertex_array                 1
#define GL_EXT_polygon_offset               1
#define GL_EXT_blend_logic_op               1
#define GL_EXT_texture                      1
#define GL_EXT_copy_texture                 1
#define GL_EXT_subtexture                   1
#define GL_EXT_texture_object               1
#endif /* GL_VERSION_1_1 */

#ifndef  GLU_VERSION_1_2
#define GLUtesselator    GLUtriangulatorObj
#define GLU_TESS_BEGIN   100100
#define GLU_TESS_VERTEX  100101
#define GLU_TESS_END     100102
#define GLU_TESS_ERROR   100103
#define GLU_TESS_COMBINE 100105
#endif

#define INVALID_EXT_FUNCTION_PTR 0xffffffff
/*
 * Contournement temporaire glPolygoneOffsetEXT
 * La syntaxe change entre OpenGL 1.0 et OpenGL 1.1
 */

#if defined (__sun) || defined (__osf__) || defined (__hp)
#define glPolygonOffsetEXT(a, b) glPolygonOffset(a, b)
#endif
#if defined (__sun)
#define GL_POLYGON_OFFSET_EXT   GL_POLYGON_OFFSET_FILL
#endif

#ifdef WNT
#define glPolygonOffsetEXT(a, b) glPolygonOffset(a, b)
#define GL_POLYGON_OFFSET_EXT   GL_POLYGON_OFFSET_FILL
#endif /* WNT */

#if defined (__sun) || defined (__osf__) || defined (__hp) || defined (__sgi)
#else
typedef void (APIENTRY * PFNGLBLENDEQUATIONEXTPROC) (GLenum mode);
#endif

/*----------------------------------------------------------------------*/
/*
 * Prototypes
 */

/*
 * Points d'entree Public du module
 */

extern GLboolean InitExtensionGLX(Display *display);
extern GLboolean QueryExtensionGLX(const char *extName);

extern GLboolean QueryExtension(const char *extName);

extern Display *GetCurrentDisplay(void);

extern GLboolean supportsOneDotOne(void);

extern GLboolean CheckExtension(const char *extName, const char *extString);

/* Methods defined in OpenGl_GraphicDriver.cxx */

EXPORT GLboolean OpenGl_QueryExtensionGLX (const char *extName);

EXPORT GLboolean OpenGl_QueryExtension    (const char *extName);

/*----------------------------------------------------------------------*/

#endif /* _OPENGL_EXTENSION_H__ */
<commit_msg>Fix Win32 TKOpenGL build error when using static libraries<commit_after>/*
 * Fonction
 * ~~~~~~~~
 *   Gestion des extensions sous OpenGL
 *
 *
 * Attention:
 * ~~~~~~~~~~~
 *  Ce package a ete teste sur SGI, OSF, SUN,  HP et WNT.
 *
 * Remarques:
 * ~~~~~~~~~~~
 *  Le InitExtensionGLX permet d'initialiser le display. Ceci est necessaire
 *  pour travailler sur les extensions de GLX. On ne peut appeler QueryExtensionGLX
 *  si on n'a pas fait cette manip.
 *  Par contre QueryExtension gere les extensions a GL,  on n'a pas besoin du
 *  Display.
 *
 *  Pour l'instant on ne gere pas les extensions a GLU et a WGL.
 *
 * Historique des modifications
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *   14-10-97: FMN ; Creation
 *   23-10-97: FMN ; Ajout gestion glx
 *   19-11-97: FMN ; Ajout GetCurrentDisplay
 *   04-12-97: FMN ; Ajout supportsOneDotOne
 *   19-06-98: FMN ; Portage Optimizer (C++)
 */
/*----------------------------------------------------------------------*/

#ifndef _OPENGL_EXTENSION_H__
#define _OPENGL_EXTENSION_H__

/*----------------------------------------------------------------------*/
/*
 * Includes
 */

#if defined(WNT) && !defined(HAVE_NO_DLL)
# ifdef __OpenGl_DLL
#  define EXPORT __declspec(dllexport)
# else
#  define EXPORT
# endif  /* DLL */
#else
# define EXPORT
#endif  /* WNT */

#if defined(WNT)
# ifdef STRICT
#  undef STRICT
# endif
# define STRICT
# include <windows.h>
#endif

#include <GL/gl.h>
#include <GL/glu.h>

#ifdef WNT
# include <windows.h>
# ifndef Display
# define Display char
# endif  /* Display */
#else
# include <GL/glx.h>
#endif /* WNT */

#ifdef GL_VERSION_1_1
#define GL_EXT_vertex_array                 1
#define GL_EXT_polygon_offset               1
#define GL_EXT_blend_logic_op               1
#define GL_EXT_texture                      1
#define GL_EXT_copy_texture                 1
#define GL_EXT_subtexture                   1
#define GL_EXT_texture_object               1
#endif /* GL_VERSION_1_1 */

#ifndef  GLU_VERSION_1_2
#define GLUtesselator    GLUtriangulatorObj
#define GLU_TESS_BEGIN   100100
#define GLU_TESS_VERTEX  100101
#define GLU_TESS_END     100102
#define GLU_TESS_ERROR   100103
#define GLU_TESS_COMBINE 100105
#endif

#define INVALID_EXT_FUNCTION_PTR 0xffffffff
/*
 * Contournement temporaire glPolygoneOffsetEXT
 * La syntaxe change entre OpenGL 1.0 et OpenGL 1.1
 */

#if defined (__sun) || defined (__osf__) || defined (__hp)
#define glPolygonOffsetEXT(a, b) glPolygonOffset(a, b)
#endif
#if defined (__sun)
#define GL_POLYGON_OFFSET_EXT   GL_POLYGON_OFFSET_FILL
#endif

#ifdef WNT
#define glPolygonOffsetEXT(a, b) glPolygonOffset(a, b)
#define GL_POLYGON_OFFSET_EXT   GL_POLYGON_OFFSET_FILL
#endif /* WNT */

#if defined (__sun) || defined (__osf__) || defined (__hp) || defined (__sgi)
#else
typedef void (APIENTRY * PFNGLBLENDEQUATIONEXTPROC) (GLenum mode);
#endif

/*----------------------------------------------------------------------*/
/*
 * Prototypes
 */

/*
 * Points d'entree Public du module
 */

extern GLboolean InitExtensionGLX(Display *display);
extern GLboolean QueryExtensionGLX(const char *extName);

extern GLboolean QueryExtension(const char *extName);

extern Display *GetCurrentDisplay(void);

extern GLboolean supportsOneDotOne(void);

extern GLboolean CheckExtension(const char *extName, const char *extString);

/* Methods defined in OpenGl_GraphicDriver.cxx */

EXPORT GLboolean OpenGl_QueryExtensionGLX (const char *extName);

EXPORT GLboolean OpenGl_QueryExtension    (const char *extName);

/*----------------------------------------------------------------------*/

#endif /* _OPENGL_EXTENSION_H__ */
<|endoftext|>


<commit_before>#ifndef CAFFE_OPTIMIZATION_SOLVER_HPP_
#define CAFFE_OPTIMIZATION_SOLVER_HPP_

#include <string>
#include <vector>

#include "caffe/net.hpp"

namespace caffe {

template <typename Dtype>
class Solver {
 public:
  explicit Solver(const SolverParameter& param);
  explicit Solver(const string& param_file);
  void Init(const SolverParameter& param);
  void InitTrainNet();
  void InitTestNets();
  // The main entry of the solver function. In default, iter will be zero. Pass
  // in a non-zero iter number to resume training for a pre-trained net.
  virtual void Solve(const char* resume_file = NULL);
  inline void Solve(const string resume_file) { Solve(resume_file.c_str()); }
  virtual ~Solver() {}
  inline shared_ptr<Net<Dtype> > net() { return net_; }
  inline const vector<shared_ptr<Net<Dtype> > >& test_nets() {
    return test_nets_;
  }

 protected:
  // PreSolve is run before any solving iteration starts, allowing one to
  // put up some scaffold.
  virtual void PreSolve() {}
  // Get the update value for the current iteration.
  virtual void ComputeUpdateValue() = 0;
  // The Solver::Snapshot function implements the basic snapshotting utility
  // that stores the learned net. You should implement the SnapshotSolverState()
  // function that produces a SolverState protocol buffer that needs to be
  // written to disk together with the learned net.
  void Snapshot();
  // The test routine
  void TestAll();
  void Test(const int test_net_id = 0);
  virtual void SnapshotSolverState(SolverState* state) = 0;
  // The Restore function implements how one should restore the solver to a
  // previously snapshotted state. You should implement the RestoreSolverState()
  // function that restores the state from a SolverState protocol buffer.
  void Restore(const char* resume_file);
  virtual void RestoreSolverState(const SolverState& state) = 0;
  void DisplayOutputBlobs(const int net_id);

  SolverParameter param_;
  int iter_;
  shared_ptr<Net<Dtype> > net_;
  vector<shared_ptr<Net<Dtype> > > test_nets_;

  DISABLE_COPY_AND_ASSIGN(Solver);
};

template <typename Dtype>
class SGDSolver : public Solver<Dtype> {
 public:
  explicit SGDSolver(const SolverParameter& param)
      : Solver<Dtype>(param) {}
  explicit SGDSolver(const string& param_file)
      : Solver<Dtype>(param_file) {}

 protected:
  void PreSolve();
  Dtype GetLearningRate();
  virtual void ComputeUpdateValue();
  void SnapshotSolverState(SolverState * state);
  void RestoreSolverState(const SolverState& state);
  // history maintains the historical momentum data.
  // update maintains update related data and is not needed in snapshots.
  vector<shared_ptr<Blob<Dtype> > > history_, update_;

  DISABLE_COPY_AND_ASSIGN(SGDSolver);
};

template <typename Dtype>
class NesterovSolver : public SGDSolver<Dtype> {
 public:
  explicit NesterovSolver(const SolverParameter& param)
      : SGDSolver<Dtype>(param) {}
  explicit NesterovSolver(const string& param_file)
      : SGDSolver<Dtype>(param_file) {}

 protected:
  virtual void ComputeUpdateValue();

  DISABLE_COPY_AND_ASSIGN(NesterovSolver);
};

template <typename Dtype>
class AdaGradSolver : public SGDSolver<Dtype> {
 public:
  explicit AdaGradSolver(const SolverParameter& param)
      : SGDSolver<Dtype>(param) {}
  explicit AdaGradSolver(const string& param_file)
      : SGDSolver<Dtype>(param_file) {}

 protected:
  virtual void ComputeUpdateValue();

  DISABLE_COPY_AND_ASSIGN(AdaGradSolver);
};

template <typename Dtype>
Solver<Dtype>* GetSolver(const SolverParameter& param) {
  SolverParameter_SolverType type = param.solver_type();

  switch (type) {
  case SolverParameter_SolverType_SGD:
      return new SGDSolver<Dtype>(param);
  case SolverParameter_SolverType_NESTEROV:
      return new NesterovSolver<Dtype>(param);
  case SolverParameter_SolverType_ADAGRAD:
      return new AdaGradSolver<Dtype>(param);
  default:
      LOG(FATAL) << "Unknown SolverType: " << type;
  }
}

}  // namespace caffe

#endif  // CAFFE_OPTIMIZATION_SOLVER_HPP_
<commit_msg>restored vituals in solver.hpp<commit_after>#ifndef CAFFE_OPTIMIZATION_SOLVER_HPP_
#define CAFFE_OPTIMIZATION_SOLVER_HPP_

#include <string>
#include <vector>

#include "caffe/net.hpp"

namespace caffe {

template <typename Dtype>
class Solver {
 public:
  explicit Solver(const SolverParameter& param);
  explicit Solver(const string& param_file);
  void Init(const SolverParameter& param);
  void InitTrainNet();
  void InitTestNets();
  // The main entry of the solver function. In default, iter will be zero. Pass
  // in a non-zero iter number to resume training for a pre-trained net.
  virtual void Solve(const char* resume_file = NULL);
  inline void Solve(const string resume_file) { Solve(resume_file.c_str()); }
  virtual ~Solver() {}
  inline shared_ptr<Net<Dtype> > net() { return net_; }
  inline const vector<shared_ptr<Net<Dtype> > >& test_nets() {
    return test_nets_;
  }

 protected:
  // PreSolve is run before any solving iteration starts, allowing one to
  // put up some scaffold.
  virtual void PreSolve() {}
  // Get the update value for the current iteration.
  virtual void ComputeUpdateValue() = 0;
  // The Solver::Snapshot function implements the basic snapshotting utility
  // that stores the learned net. You should implement the SnapshotSolverState()
  // function that produces a SolverState protocol buffer that needs to be
  // written to disk together with the learned net.
  void Snapshot();
  // The test routine
  void TestAll();
  void Test(const int test_net_id = 0);
  virtual void SnapshotSolverState(SolverState* state) = 0;
  // The Restore function implements how one should restore the solver to a
  // previously snapshotted state. You should implement the RestoreSolverState()
  // function that restores the state from a SolverState protocol buffer.
  void Restore(const char* resume_file);
  virtual void RestoreSolverState(const SolverState& state) = 0;
  void DisplayOutputBlobs(const int net_id);

  SolverParameter param_;
  int iter_;
  shared_ptr<Net<Dtype> > net_;
  vector<shared_ptr<Net<Dtype> > > test_nets_;

  DISABLE_COPY_AND_ASSIGN(Solver);
};

template <typename Dtype>
class SGDSolver : public Solver<Dtype> {
 public:
  explicit SGDSolver(const SolverParameter& param)
      : Solver<Dtype>(param) {}
  explicit SGDSolver(const string& param_file)
      : Solver<Dtype>(param_file) {}

 protected:
  virtual void PreSolve();
  Dtype GetLearningRate();
  virtual void ComputeUpdateValue();
  virtual void SnapshotSolverState(SolverState * state);
  virtual void RestoreSolverState(const SolverState& state);
  // history maintains the historical momentum data.
  // update maintains update related data and is not needed in snapshots.
  vector<shared_ptr<Blob<Dtype> > > history_, update_;

  DISABLE_COPY_AND_ASSIGN(SGDSolver);
};

template <typename Dtype>
class NesterovSolver : public SGDSolver<Dtype> {
 public:
  explicit NesterovSolver(const SolverParameter& param)
      : SGDSolver<Dtype>(param) {}
  explicit NesterovSolver(const string& param_file)
      : SGDSolver<Dtype>(param_file) {}

 protected:
  virtual void ComputeUpdateValue();

  DISABLE_COPY_AND_ASSIGN(NesterovSolver);
};

template <typename Dtype>
class AdaGradSolver : public SGDSolver<Dtype> {
 public:
  explicit AdaGradSolver(const SolverParameter& param)
      : SGDSolver<Dtype>(param) {}
  explicit AdaGradSolver(const string& param_file)
      : SGDSolver<Dtype>(param_file) {}

 protected:
  virtual void ComputeUpdateValue();

  DISABLE_COPY_AND_ASSIGN(AdaGradSolver);
};

template <typename Dtype>
Solver<Dtype>* GetSolver(const SolverParameter& param) {
  SolverParameter_SolverType type = param.solver_type();

  switch (type) {
  case SolverParameter_SolverType_SGD:
      return new SGDSolver<Dtype>(param);
  case SolverParameter_SolverType_NESTEROV:
      return new NesterovSolver<Dtype>(param);
  case SolverParameter_SolverType_ADAGRAD:
      return new AdaGradSolver<Dtype>(param);
  default:
      LOG(FATAL) << "Unknown SolverType: " << type;
  }
}

}  // namespace caffe

#endif  // CAFFE_OPTIMIZATION_SOLVER_HPP_
<|endoftext|>


<commit_before>/******************************************************************************
 *                    _   _____   __________                                  *
 *                   | | / / _ | / __/_  __/     Visibility                   *
 *                   | |/ / __ |_\ \  / /          Across                     *
 *                   |___/_/ |_/___/ /_/       Space and Time                 *
 *                                                                            *
 * This file is part of VAST. It is subject to the license terms in the       *
 * LICENSE file found in the top-level directory of this distribution and at  *
 * http://vast.io/license. No part of VAST, including this file, may be       *
 * copied, modified, propagated, or distributed except according to the terms *
 * contained in the LICENSE file.                                             *
 ******************************************************************************/

#pragma once

#include "vast/concept/parseable/vast/json.hpp"
#include "vast/defaults.hpp"
#include "vast/detail/line_range.hpp"
#include "vast/error.hpp"
#include "vast/event.hpp"
#include "vast/format/multi_layout_reader.hpp"
#include "vast/format/ostream_writer.hpp"
#include "vast/fwd.hpp"
#include "vast/json.hpp"
#include "vast/logger.hpp"
#include "vast/schema.hpp"

#include <caf/expected.hpp>
#include <caf/fwd.hpp>

namespace vast::format::json {

class writer : public ostream_writer {
public:
  using defaults = vast::defaults::export_::json;

  using super = ostream_writer;

  using super::super;

  caf::error write(const table_slice& x) override;

  const char* name() const override;
};

/// Adds a JSON object to a table slice builder according to a given layout.
/// @param builder The builder to add the JSON object to.
/// @param xs The JSON object to add to *builder.
/// @param layout The record type describing *xs*.
/// @returns An error iff the operation failed.
caf::error add(table_slice_builder& builder, const vast::json::object& xs,
               const record_type& layout);

/// @relates reader
struct default_selector {
  caf::optional<record_type> operator()(const vast::json::object&) {
    return layout;
  }

  caf::error schema(vast::schema sch) {
    auto entry = *sch.begin();
    if (!caf::holds_alternative<record_type>(entry))
      return make_error(ec::invalid_configuration,
                        "only record_types supported for json schema");
    layout = flatten(caf::get<record_type>(entry));
    return caf::none;
  }

  vast::schema schema() const {
    vast::schema result;
    if (layout)
      result.add(*layout);
    return result;
  }

  static const char* name() {
    return "json-reader";
  }

  caf::optional<record_type> layout = caf::none;
};

/// A reader for JSON data. It operates with a *selector* to determine the
/// mapping of JSON object to the appropriate record type in the schema.
template <class Selector = default_selector>
class reader final : public multi_layout_reader {
public:
  using super = multi_layout_reader;

  /// Constructs a JSON reader.
  /// @param table_slice_type The ID for table slice type to build.
  /// @param options Additional options.
  /// @param in The stream of JSON objects.
  explicit reader(caf::atom_value table_slice_type,
                  const caf::settings& options,
                  std::unique_ptr<std::istream> in = nullptr);

  void reset(std::unique_ptr<std::istream> in);

  caf::error schema(vast::schema sch) override;

  vast::schema schema() const override;

  const char* name() const override;

protected:
  caf::error read_impl(size_t max_events, size_t max_slice_size,
                       consumer& f) override;

private:
  using iterator_type = std::string_view::const_iterator;

  Selector selector_;
  std::unique_ptr<std::istream> input_;
  std::unique_ptr<detail::line_range> lines_;
  caf::optional<size_t> proto_field_;
  std::vector<size_t> port_fields_;
};

// -- implementation ----------------------------------------------------------

template <class Selector>
reader<Selector>::reader(caf::atom_value table_slice_type,
                         const caf::settings& /*options*/,
                         std::unique_ptr<std::istream> in)
  : super(table_slice_type) {
  if (in != nullptr)
    reset(std::move(in));
}

template <class Selector>
void reader<Selector>::reset(std::unique_ptr<std::istream> in) {
  VAST_ASSERT(in != nullptr);
  input_ = std::move(in);
  lines_ = std::make_unique<detail::line_range>(*input_);
}

template <class Selector>
caf::error reader<Selector>::schema(vast::schema s) {
  return selector_.schema(std::move(s));
}

template <class Selector>
vast::schema reader<Selector>::schema() const {
  return selector_.schema();
}

template <class Selector>
const char* reader<Selector>::name() const {
  return Selector::name();
}

template <class Selector>
caf::error reader<Selector>::read_impl(size_t max_events, size_t max_slice_size,
                                       consumer& cons) {
  VAST_ASSERT(max_events > 0);
  VAST_ASSERT(max_slice_size > 0);
  size_t produced = 0;
  for (; produced < max_events; lines_->next()) {
    // EOF check.
    if (lines_->done())
      return finish(cons, make_error(ec::end_of_input, "input exhausted"));
    auto& line = lines_->get();
    vast::json j;
    if (!parsers::json(line, j))
      return make_error(ec::parse_error, "unable to parse json");
    auto xs = caf::get_if<vast::json::object>(&j);
    if (!xs)
      return make_error(ec::type_clash, "not a json object");
    auto layout = selector_(*xs);
    if (!layout)
      continue;
    auto bptr = builder(*layout);
    if (bptr == nullptr)
      return make_error(ec::parse_error, "unable to get a builder");
    if (auto err = add(*bptr, *xs, *layout)) {
      err.context() += caf::make_message("line", lines_->line_number());
      return finish(cons, err);
    }
    produced++;
    if (bptr->rows() == max_slice_size)
      if (auto err = finish(cons, bptr))
        return err;
  }
  return finish(cons);
}

} // namespace vast::format::json
<commit_msg>Be more resilient towards malformed JSON input<commit_after>/******************************************************************************
 *                    _   _____   __________                                  *
 *                   | | / / _ | / __/_  __/     Visibility                   *
 *                   | |/ / __ |_\ \  / /          Across                     *
 *                   |___/_/ |_/___/ /_/       Space and Time                 *
 *                                                                            *
 * This file is part of VAST. It is subject to the license terms in the       *
 * LICENSE file found in the top-level directory of this distribution and at  *
 * http://vast.io/license. No part of VAST, including this file, may be       *
 * copied, modified, propagated, or distributed except according to the terms *
 * contained in the LICENSE file.                                             *
 ******************************************************************************/

#pragma once

#include "vast/concept/parseable/vast/json.hpp"
#include "vast/defaults.hpp"
#include "vast/detail/line_range.hpp"
#include "vast/error.hpp"
#include "vast/event.hpp"
#include "vast/format/multi_layout_reader.hpp"
#include "vast/format/ostream_writer.hpp"
#include "vast/fwd.hpp"
#include "vast/json.hpp"
#include "vast/logger.hpp"
#include "vast/schema.hpp"

#include <caf/expected.hpp>
#include <caf/fwd.hpp>

namespace vast::format::json {

class writer : public ostream_writer {
public:
  using defaults = vast::defaults::export_::json;

  using super = ostream_writer;

  using super::super;

  caf::error write(const table_slice& x) override;

  const char* name() const override;
};

/// Adds a JSON object to a table slice builder according to a given layout.
/// @param builder The builder to add the JSON object to.
/// @param xs The JSON object to add to *builder.
/// @param layout The record type describing *xs*.
/// @returns An error iff the operation failed.
caf::error add(table_slice_builder& builder, const vast::json::object& xs,
               const record_type& layout);

/// @relates reader
struct default_selector {
  caf::optional<record_type> operator()(const vast::json::object&) {
    return layout;
  }

  caf::error schema(vast::schema sch) {
    auto entry = *sch.begin();
    if (!caf::holds_alternative<record_type>(entry))
      return make_error(ec::invalid_configuration,
                        "only record_types supported for json schema");
    layout = flatten(caf::get<record_type>(entry));
    return caf::none;
  }

  vast::schema schema() const {
    vast::schema result;
    if (layout)
      result.add(*layout);
    return result;
  }

  static const char* name() {
    return "json-reader";
  }

  caf::optional<record_type> layout = caf::none;
};

/// A reader for JSON data. It operates with a *selector* to determine the
/// mapping of JSON object to the appropriate record type in the schema.
template <class Selector = default_selector>
class reader final : public multi_layout_reader {
public:
  using super = multi_layout_reader;

  /// Constructs a JSON reader.
  /// @param table_slice_type The ID for table slice type to build.
  /// @param options Additional options.
  /// @param in The stream of JSON objects.
  explicit reader(caf::atom_value table_slice_type,
                  const caf::settings& options,
                  std::unique_ptr<std::istream> in = nullptr);

  void reset(std::unique_ptr<std::istream> in);

  caf::error schema(vast::schema sch) override;

  vast::schema schema() const override;

  const char* name() const override;

protected:
  caf::error read_impl(size_t max_events, size_t max_slice_size,
                       consumer& f) override;

private:
  using iterator_type = std::string_view::const_iterator;

  Selector selector_;
  std::unique_ptr<std::istream> input_;
  std::unique_ptr<detail::line_range> lines_;
  caf::optional<size_t> proto_field_;
  std::vector<size_t> port_fields_;
};

// -- implementation ----------------------------------------------------------

template <class Selector>
reader<Selector>::reader(caf::atom_value table_slice_type,
                         const caf::settings& /*options*/,
                         std::unique_ptr<std::istream> in)
  : super(table_slice_type) {
  if (in != nullptr)
    reset(std::move(in));
}

template <class Selector>
void reader<Selector>::reset(std::unique_ptr<std::istream> in) {
  VAST_ASSERT(in != nullptr);
  input_ = std::move(in);
  lines_ = std::make_unique<detail::line_range>(*input_);
}

template <class Selector>
caf::error reader<Selector>::schema(vast::schema s) {
  return selector_.schema(std::move(s));
}

template <class Selector>
vast::schema reader<Selector>::schema() const {
  return selector_.schema();
}

template <class Selector>
const char* reader<Selector>::name() const {
  return Selector::name();
}

template <class Selector>
caf::error reader<Selector>::read_impl(size_t max_events, size_t max_slice_size,
                                       consumer& cons) {
  VAST_ASSERT(max_events > 0);
  VAST_ASSERT(max_slice_size > 0);
  size_t produced = 0;
  for (; produced < max_events; lines_->next()) {
    // EOF check.
    if (lines_->done())
      return finish(cons, make_error(ec::end_of_input, "input exhausted"));
    auto& line = lines_->get();
    vast::json j;
    if (!parsers::json(line, j)) {
      VAST_WARNING(this, "failed to parse", line);
      continue;
    }
    auto xs = caf::get_if<vast::json::object>(&j);
    if (!xs)
      return make_error(ec::type_clash, "not a json object");
    auto layout = selector_(*xs);
    if (!layout)
      continue;
    auto bptr = builder(*layout);
    if (bptr == nullptr)
      return make_error(ec::parse_error, "unable to get a builder");
    if (auto err = add(*bptr, *xs, *layout)) {
      err.context() += caf::make_message("line", lines_->line_number());
      return finish(cons, err);
    }
    produced++;
    if (bptr->rows() == max_slice_size)
      if (auto err = finish(cons, bptr))
        return err;
  }
  return finish(cons);
}

} // namespace vast::format::json
<|endoftext|>


<commit_before>/**
 * \file dcs/testbed/libvirt/virtual_machine_manager.hpp
 *
 * \brief Libvirt-based Virtual Machine Manager.
 *
 * \author Marco Guazzone (marco.guazzone@gmail.com)
 *
 *

 *
 * Copyright 2012 Marco Guazzone (marco.guazzone@gmail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef DCS_TESTBED_LIBVIRT_VIRTUAL_MACHINE_MANAGER_HPP
#define DCS_TESTBED_LIBVIRT_VIRTUAL_MACHINE_MANAGER_HPP

#include <dcs/assert.hpp>
#include <dcs/debug.hpp>
#include <dcs/exception.hpp>
#include <dcs/logging.hpp>
#include <dcs/testbed/base_virtual_machine_manager.hpp>
#include <dcs/testbed/libvirt/detail/utility.hpp>
#include <dcs/testbed/libvirt/virtual_machine.hpp>
#include <dcs/uri.hpp>
#include <exception>
#include <map>
#include <sstream>
#include <stdexcept>
#include <string>

namespace dcs { namespace testbed { namespace libvirt {

/*
inline
::std::string strip_vmm_uri(::std::string const& uri)
{
	::std::ostringstream oss;

	::dcs::uri u(uri);
	if (!u.relative())
	{
		oss << u.scheme() << "://" << u.authority() << "/";
	}

	return oss.str();
}
*/

template <typename TraitsT>
class virtual_machine_manager: public base_virtual_machine_manager<TraitsT>
{
	private: typedef base_virtual_machine_manager<TraitsT> base_type;
	public: typedef typename base_type::traits_type traits_type;
	public: typedef typename base_type::identifier_type identifier_type;
	public: typedef typename base_type::vm_identifier_type vm_identifier_type;
	public: typedef typename base_type::vm_pointer vm_pointer;
	public: typedef typename base_type::uint_type uint_type;
	private: typedef ::std::map<vm_identifier_type,vm_pointer> vm_container;

	public: virtual_machine_manager(::std::string const& uri)
	: uri_(detail::vmm_uri(uri)),
	  p_conn_(0)
	{
		init();
	}

	public: ~virtual_machine_manager()
	{
		// According to http://www.stlport.org/doc/exception_safety.html we avoid to throw any exception inside the destructor
		try
		{
			if (p_conn_)
			{
				detail::disconnect(p_conn_);
			}
		}
		catch (::std::exception const& e)
		{
			::std::ostringstream oss;
			oss << "Failed to disconnect from hypervisor '" << uri_ << "': " << e.what();
			dcs::log_error(DCS_LOGGING_AT, oss.str());
		}
		catch (...)
		{
			::std::ostringstream oss;
			oss << "Failed to disconnect from hypervisor '" << uri_ << "': Unknown error";
			dcs::log_error(DCS_LOGGING_AT, oss.str());
		}
	}

	public: ::std::string uri() const
	{
		return uri_;
	}

	public: ::virConnectPtr connection()
	{
		return p_conn_;
	}

	public: ::virConnectPtr connection() const
	{
		return p_conn_;
	}

	private: void init()
	{
		// Connect to libvirtd daemon
		p_conn_ = detail::connect(uri_);
	}

	private: identifier_type do_id() const
	{
		return uri_;
	}

	private: bool do_alive() const
	{
		int ret = ::virConnectIsAlive(p_conn_);
		if (-1 == ret)
		{
			::std::ostringstream oss;
			oss << "Failed to check for VMM aliveness " << detail::last_error(p_conn_);
			DCS_EXCEPTION_THROW(::std::runtime_error, oss.str());
		}

		return ret ? true : false;
	}

	private: vm_pointer do_vm(vm_identifier_type const& id)
	{
		if (vm_map_.count(id) == 0)
		{
			vm_map_[id] = ::boost::make_shared< virtual_machine<traits_type> >(this, id);

			// check: vm_map.at(id) != null
			DCS_DEBUG_ASSERT( vm_map_.at(id) );
		}

		return vm_map_.at(id);
	}

	private: vm_pointer do_vm(vm_identifier_type const& id) const
	{
		DCS_ASSERT(vm_map_.count(id) > 0,
				   DCS_EXCEPTION_THROW(::std::invalid_argument,
									   "VM not found"));

		return vm_map_.at(id);
	}

	private: uint_type do_max_supported_num_vcpus() const
	{
		DCS_ASSERT(p_conn_,
				   DCS_EXCEPTION_THROW(::std::logic_error,
									   "Not connected"));

		int max_nvcpus = detail::max_supported_num_vcpus(p_conn_);

		return static_cast<uint_type>(max_nvcpus);
	}

	private: ::std::string uri_;
	private: ::virConnectPtr p_conn_;
	private: vm_container vm_map_;
}; // virtual_machine_manager

}}} // Namespace dcs::testbed::libvirt

#endif // DCS_TESTBED_LIBVIRT_VIRTUAL_MACHINE_MANAGER_HPP
<commit_msg>New function 'vmm_uri'<commit_after>/**
 * \file dcs/testbed/libvirt/virtual_machine_manager.hpp
 *
 * \brief Libvirt-based Virtual Machine Manager.
 *
 * \author Marco Guazzone (marco.guazzone@gmail.com)
 *
 *

 *
 * Copyright 2012 Marco Guazzone (marco.guazzone@gmail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef DCS_TESTBED_LIBVIRT_VIRTUAL_MACHINE_MANAGER_HPP
#define DCS_TESTBED_LIBVIRT_VIRTUAL_MACHINE_MANAGER_HPP

#include <dcs/assert.hpp>
#include <dcs/debug.hpp>
#include <dcs/exception.hpp>
#include <dcs/logging.hpp>
#include <dcs/testbed/base_virtual_machine_manager.hpp>
#include <dcs/testbed/libvirt/detail/utility.hpp>
#include <dcs/testbed/libvirt/virtual_machine.hpp>
#include <dcs/uri.hpp>
#include <exception>
#include <map>
#include <sstream>
#include <stdexcept>
#include <string>

namespace dcs { namespace testbed { namespace libvirt {

/*
inline
::std::string strip_vmm_uri(::std::string const& uri)
{
	::std::ostringstream oss;

	::dcs::uri u(uri);
	if (!u.relative())
	{
		oss << u.scheme() << "://" << u.authority() << "/";
	}

	return oss.str();
}
*/

/// Gets the URI for the virtual machine manager from the given URI
inline
std::string vmm_uri(std::string const& uri)
{
	return detail::vmm_uri(uri);
}

template <typename TraitsT>
class virtual_machine_manager: public base_virtual_machine_manager<TraitsT>
{
	private: typedef base_virtual_machine_manager<TraitsT> base_type;
	public: typedef typename base_type::traits_type traits_type;
	public: typedef typename base_type::identifier_type identifier_type;
	public: typedef typename base_type::vm_identifier_type vm_identifier_type;
	public: typedef typename base_type::vm_pointer vm_pointer;
	public: typedef typename base_type::uint_type uint_type;
	private: typedef ::std::map<vm_identifier_type,vm_pointer> vm_container;

	public: virtual_machine_manager(::std::string const& uri)
	: uri_(detail::vmm_uri(uri)),
	  p_conn_(0)
	{
		init();
	}

	public: ~virtual_machine_manager()
	{
		// According to http://www.stlport.org/doc/exception_safety.html we avoid to throw any exception inside the destructor
		try
		{
			if (p_conn_)
			{
				detail::disconnect(p_conn_);
			}
		}
		catch (::std::exception const& e)
		{
			::std::ostringstream oss;
			oss << "Failed to disconnect from hypervisor '" << uri_ << "': " << e.what();
			dcs::log_error(DCS_LOGGING_AT, oss.str());
		}
		catch (...)
		{
			::std::ostringstream oss;
			oss << "Failed to disconnect from hypervisor '" << uri_ << "': Unknown error";
			dcs::log_error(DCS_LOGGING_AT, oss.str());
		}
	}

	public: ::std::string uri() const
	{
		return uri_;
	}

	public: ::virConnectPtr connection()
	{
		return p_conn_;
	}

	public: ::virConnectPtr connection() const
	{
		return p_conn_;
	}

	private: void init()
	{
		// Connect to libvirtd daemon
		p_conn_ = detail::connect(uri_);
	}

	private: identifier_type do_id() const
	{
		return uri_;
	}

	private: bool do_alive() const
	{
		int ret = ::virConnectIsAlive(p_conn_);
		if (-1 == ret)
		{
			::std::ostringstream oss;
			oss << "Failed to check for VMM aliveness " << detail::last_error(p_conn_);
			DCS_EXCEPTION_THROW(::std::runtime_error, oss.str());
		}

		return ret ? true : false;
	}

	private: vm_pointer do_vm(vm_identifier_type const& id)
	{
		if (vm_map_.count(id) == 0)
		{
			vm_map_[id] = ::boost::make_shared< virtual_machine<traits_type> >(this, id);

			// check: vm_map.at(id) != null
			DCS_DEBUG_ASSERT( vm_map_.at(id) );
		}

		return vm_map_.at(id);
	}

	private: vm_pointer do_vm(vm_identifier_type const& id) const
	{
		DCS_ASSERT(vm_map_.count(id) > 0,
				   DCS_EXCEPTION_THROW(::std::invalid_argument,
									   "VM not found"));

		return vm_map_.at(id);
	}

	private: uint_type do_max_supported_num_vcpus() const
	{
		DCS_ASSERT(p_conn_,
				   DCS_EXCEPTION_THROW(::std::logic_error,
									   "Not connected"));

		int max_nvcpus = detail::max_supported_num_vcpus(p_conn_);

		return static_cast<uint_type>(max_nvcpus);
	}

	private: ::std::string uri_;
	private: ::virConnectPtr p_conn_;
	private: vm_container vm_map_;
}; // virtual_machine_manager

}}} // Namespace dcs::testbed::libvirt

#endif // DCS_TESTBED_LIBVIRT_VIRTUAL_MACHINE_MANAGER_HPP
<|endoftext|>


<commit_before>// Copyright (c) 2016, LAAS-CNRS
// Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
//
// This file is part of hpp-pinocchio.
// hpp-pinocchio is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// hpp-pinocchio is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-pinocchio. If not, see <http://www.gnu.org/licenses/>.

#ifndef HPP_PINOCCHIO_CENTER_OF_MASS_COMPUTATION_HH
# define HPP_PINOCCHIO_CENTER_OF_MASS_COMPUTATION_HH

# include <list>

# include <pinocchio/multibody/model.hpp> // se3::Data

# include <hpp/pinocchio/fwd.hh>
# include <hpp/pinocchio/device.hh>

namespace hpp {
  namespace pinocchio {
    class CenterOfMassComputation
    {
      public:
        typedef std::vector <JointIndex> JointRootIndexes_t;
        /// \cond
        // This fixes an alignment issue of se3::Data::hg
        EIGEN_MAKE_ALIGNED_OPERATOR_NEW
        /// \endcond

      public:

        static CenterOfMassComputationPtr_t create (const DevicePtr_t& device);

        void add (const JointPtr_t& rootOfSubtree);

        void compute (const Device::Computation_t& flag
            = Device::ALL);

        const vector3_t&     com         () const { return data.com [0]; }
        const value_type&    mass        () const { return data.mass[0]; }
        const ComJacobian_t& jacobian    () const { return data.Jcom   ; }
        const JointRootIndexes_t & roots () const { return roots_; }

        ~CenterOfMassComputation ();

      protected:
        CenterOfMassComputation (const DevicePtr_t& device);

      private:
        DevicePtr_t robot_;
        // Root of the subtrees
        JointRootIndexes_t roots_;
        // Specific pinocchio Data to store the computation results
        Data data;

        // value_type mass_;
        // vector3_t com_;
        // ComJacobian_t jacobianCom_;

    }; // class CenterOfMassComputation
  }  // namespace pinocchio
}  // namespace hpp
#endif // HPP_PINOCCHIO_CENTER_OF_MASS_COMPUTATION_HH
<commit_msg>Cosmetic: add documentation to class CenterOfMassComputation.<commit_after>// Copyright (c) 2016, LAAS-CNRS
// Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
//
// This file is part of hpp-pinocchio.
// hpp-pinocchio is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// hpp-pinocchio is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-pinocchio. If not, see <http://www.gnu.org/licenses/>.

#ifndef HPP_PINOCCHIO_CENTER_OF_MASS_COMPUTATION_HH
# define HPP_PINOCCHIO_CENTER_OF_MASS_COMPUTATION_HH

# include <list>

# include <pinocchio/multibody/model.hpp> // se3::Data

# include <hpp/pinocchio/fwd.hh>
# include <hpp/pinocchio/device.hh>

namespace hpp {
  namespace pinocchio {
    /// Computation of the center of mass of a subtree of a kinematic tree
    ///
    /// To use this class, create an instance using
    /// CenterOfMassComputation::create method and call method
    /// CenterOfMassComputation::add with parameter the root joint
    /// of the subtree.
    ///
    /// In most cases, the root joint of the subtree is the root joint of
    /// the robot (hpp::pinocchio::Device::rootJoint ()), but in a manipulation
    /// context, the kinematic tree contains several robots and objects.
    /// This class enables users to compute the center of mass of only one
    /// robot or object.
    class CenterOfMassComputation
    {
      public:
        typedef std::vector <JointIndex> JointRootIndexes_t;
        /// \cond
        // This fixes an alignment issue of se3::Data::hg
        EIGEN_MAKE_ALIGNED_OPERATOR_NEW
        /// \endcond

      public:
        /// Create instance and return shared pointer.
        ///
        /// Do not forget to call method add to specify the root joint of
        /// relevant kinematic tree.
        static CenterOfMassComputationPtr_t create (const DevicePtr_t& device);

        /// Add a subtree to the computation of the center of mass.
        ///
        /// When several subtrees are provided, method \c compute computes the
        /// center of mass of the union of the subtrees.
        void add (const JointPtr_t& rootOfSubtree);

        /// Compute the center of mass and Jacobian of the sub-trees.
        void compute (const Device::Computation_t& flag
            = Device::ALL);

        /// Get center of mass of the subtree.
        const vector3_t&     com         () const { return data.com [0]; }
        /// Get mass of the sub-tree.
        const value_type&    mass        () const { return data.mass[0]; }
        /// Get Jacobian of center of mass of the sub-tree.
        const ComJacobian_t& jacobian    () const { return data.Jcom   ; }
        /// Get const reference to the vector of sub-tree roots.
        const JointRootIndexes_t & roots () const { return roots_; }

        ~CenterOfMassComputation ();

      protected:
        CenterOfMassComputation (const DevicePtr_t& device);

      private:
        DevicePtr_t robot_;
        // Root of the subtrees
        JointRootIndexes_t roots_;
        // Specific pinocchio Data to store the computation results
        Data data;

        // value_type mass_;
        // vector3_t com_;
        // ComJacobian_t jacobianCom_;

    }; // class CenterOfMassComputation
  }  // namespace pinocchio
}  // namespace hpp
#endif // HPP_PINOCCHIO_CENTER_OF_MASS_COMPUTATION_HH
<|endoftext|>


<commit_before>/* File: BinaryFileFactory.cpp
 * Desc: This file contains the implementation of the factory function
 * BinaryFile::getInstanceFor(), and also BinaryFile::Load()
 *
 * This function determines the type of a binary and loads the appropriate
 * loader class dynamically.
*/

#include "BinaryFile.h"
#include "ElfBinaryFile.h"
#include "Win32BinaryFile.h"
#include "PalmBinaryFile.h"
#include "HpSomBinaryFile.h"
#include "ExeBinaryFile.h"

#include <iostream>
#ifndef _WIN32
#include <dlfcn.h>
#else
#include <windows.h>
#endif

BinaryFile *BinaryFileFactory::Load( const char *sName )
{
	BinaryFile *pBF = getInstanceFor( sName );
	if( pBF == NULL ) {
		std::cerr << "unrecognised binary file format.\n";
		return NULL;
	}
	if( pBF->RealLoad( sName ) == 0 ) {
		fprintf( stderr, "Loading '%s' failed\n", sName );
		delete pBF;
		return NULL;
	}
pBF->getTextLimits();
	return pBF;
}

#define TESTMAGIC2(buf,off,a,b)		(buf[off] == a && buf[off+1] == b)
#define TESTMAGIC4(buf,off,a,b,c,d) (buf[off] == a && buf[off+1] == b && \
									 buf[off+2] == c && buf[off+3] == d)

// Declare a pointer to a constructor function; returns a BinaryFile*
typedef BinaryFile* (*constructFcn)();

BinaryFile* BinaryFileFactory::getInstanceFor( const char *sName )
{
	FILE *f;
	unsigned char buf[64];
	std::string libName;
	BinaryFile *res = NULL;

	f = fopen (sName, "ro");
	if( f == NULL ) {
		fprintf(stderr, "Unable to open binary file: %s\n", sName );
		return NULL;
	}
	fread (buf, sizeof(buf), 1, f);
	if( TESTMAGIC4(buf,0, '\177','E','L','F') ) {
		/* ELF Binary */
		libName = "ElfBinaryFile";
	} else if( TESTMAGIC2( buf,0, 'M','Z' ) ) { /* DOS-based file */
		int peoff = LMMH(buf[0x3C]);
		if( peoff != 0 && fseek(f, peoff, SEEK_SET) != -1 ) {
			fread( buf, 4, 1, f );
			if( TESTMAGIC4( buf,0, 'P','E',0,0 ) ) {
				/* Win32 Binary */
				libName = "Win32BinaryFile";
			} else if( TESTMAGIC2( buf,0, 'N','E' ) ) {
				/* Win16 / Old OS/2 Binary */
			} else if( TESTMAGIC2( buf,0, 'L','E' ) ) {
				/* Win32 VxD (Linear Executable) or DOS4GW app */
                libName = "DOS4GWBinaryFile";
			} else if( TESTMAGIC2( buf,0, 'L','X' ) ) {
				/* New OS/2 Binary */
			}
		}
		/* Assume MS-DOS Real-mode binary. */
		if( libName.size() == 0 )
			libName = "ExeBinaryFile";
	} else if( TESTMAGIC4( buf,0x3C, 'a','p','p','l' ) ||
			   TESTMAGIC4( buf,0x3C, 'p','a','n','l' ) ) {
		/* PRC Palm-pilot binary */
		libName = "PalmBinaryFile";
    } else if( buf[0] == 0xfe && buf[1] == 0xed && buf[2] == 0xfa && buf[3] == 0xce ) {
        /* Mach-O Mac OS-X binary */
        libName = "MachOBinaryFile";
	} else if( buf[0] == 0x02 && buf[2] == 0x01 &&
			   (buf[1] == 0x10 || buf[1] == 0x0B) &&
			   (buf[3] == 0x07 || buf[3] == 0x08 || buf[4] == 0x0B) ) {
		/* HP Som binary (last as it's not really particularly good magic) */
		libName = "HpSomBinaryFile";
	} else {
		fprintf( stderr, "Unrecognised binary file\n" );
		fclose(f);
		return NULL;
	}

// Load the specific loader library
#ifndef _WIN32		// Cygwin, Unix/Linux
	libName = std::string("lib/lib") + libName;
#ifdef	__CYGWIN__
	libName += ".dll";		// Cygwin wants .dll, but is otherwise like Unix
#else
	libName += ".so";
#endif
	void* dlHandle = dlopen(libName.c_str(), RTLD_LAZY);
	if (dlHandle == NULL) {
		fprintf( stderr, "Could not open dynamic loader library %s\n", libName.c_str());
		fprintf( stderr, "%s\n", dlerror());
		fclose(f);
		return NULL;
	}
	// Use the handle to find the "construct" function
	constructFcn pFcn = (constructFcn) dlsym(dlHandle, "construct");
#else						// Else MSVC, MinGW
	libName += ".dll";		// Example: ElfBinaryFile.dll (same dir as boomerang.exe)
#ifdef __MINGW32__
	libName = "lib/lib" + libName;
#endif
	HMODULE hModule = LoadLibrary(libName.c_str());
	if(hModule == NULL) {
		int err = GetLastError();
		fprintf( stderr, "Could not open dynamic loader library %s (error #%d)\n", libName.c_str(), err);
		fclose(f);
		return NULL;
	}
	// Use the handle to find the "construct" function
	constructFcn pFcn = (constructFcn) GetProcAddress(hModule, "construct");
#endif

	if (pFcn == NULL) {
		fprintf( stderr, "Loader library %s does not have a construct function\n", libName.c_str());
		fclose(f);
		return NULL;
	}
	// Call the construct function
	res = (*pFcn)();
	fclose(f);
	return res;
}

<commit_msg>Minor change to avoid a warning when compiling under Windows<commit_after>/* File: BinaryFileFactory.cpp
 * Desc: This file contains the implementation of the factory function
 * BinaryFile::getInstanceFor(), and also BinaryFile::Load()
 *
 * This function determines the type of a binary and loads the appropriate
 * loader class dynamically.
*/

#ifndef _WIN32
#include <dlfcn.h>
#else
#include <windows.h>			// include before types.h: name collision of NO_ADDRESS and WinSock.h
#endif

#include "BinaryFile.h"
#include "ElfBinaryFile.h"
#include "Win32BinaryFile.h"
#include "PalmBinaryFile.h"
#include "HpSomBinaryFile.h"
#include "ExeBinaryFile.h"

#include <iostream>

BinaryFile *BinaryFileFactory::Load( const char *sName )
{
	BinaryFile *pBF = getInstanceFor( sName );
	if( pBF == NULL ) {
		std::cerr << "unrecognised binary file format.\n";
		return NULL;
	}
	if( pBF->RealLoad( sName ) == 0 ) {
		fprintf( stderr, "Loading '%s' failed\n", sName );
		delete pBF;
		return NULL;
	}
pBF->getTextLimits();
	return pBF;
}

#define TESTMAGIC2(buf,off,a,b)		(buf[off] == a && buf[off+1] == b)
#define TESTMAGIC4(buf,off,a,b,c,d) (buf[off] == a && buf[off+1] == b && \
									 buf[off+2] == c && buf[off+3] == d)

// Declare a pointer to a constructor function; returns a BinaryFile*
typedef BinaryFile* (*constructFcn)();

BinaryFile* BinaryFileFactory::getInstanceFor( const char *sName )
{
	FILE *f;
	unsigned char buf[64];
	std::string libName;
	BinaryFile *res = NULL;

	f = fopen (sName, "ro");
	if( f == NULL ) {
		fprintf(stderr, "Unable to open binary file: %s\n", sName );
		return NULL;
	}
	fread (buf, sizeof(buf), 1, f);
	if( TESTMAGIC4(buf,0, '\177','E','L','F') ) {
		/* ELF Binary */
		libName = "ElfBinaryFile";
	} else if( TESTMAGIC2( buf,0, 'M','Z' ) ) { /* DOS-based file */
		int peoff = LMMH(buf[0x3C]);
		if( peoff != 0 && fseek(f, peoff, SEEK_SET) != -1 ) {
			fread( buf, 4, 1, f );
			if( TESTMAGIC4( buf,0, 'P','E',0,0 ) ) {
				/* Win32 Binary */
				libName = "Win32BinaryFile";
			} else if( TESTMAGIC2( buf,0, 'N','E' ) ) {
				/* Win16 / Old OS/2 Binary */
			} else if( TESTMAGIC2( buf,0, 'L','E' ) ) {
				/* Win32 VxD (Linear Executable) or DOS4GW app */
                libName = "DOS4GWBinaryFile";
			} else if( TESTMAGIC2( buf,0, 'L','X' ) ) {
				/* New OS/2 Binary */
			}
		}
		/* Assume MS-DOS Real-mode binary. */
		if( libName.size() == 0 )
			libName = "ExeBinaryFile";
	} else if( TESTMAGIC4( buf,0x3C, 'a','p','p','l' ) ||
			   TESTMAGIC4( buf,0x3C, 'p','a','n','l' ) ) {
		/* PRC Palm-pilot binary */
		libName = "PalmBinaryFile";
    } else if( buf[0] == 0xfe && buf[1] == 0xed && buf[2] == 0xfa && buf[3] == 0xce ) {
        /* Mach-O Mac OS-X binary */
        libName = "MachOBinaryFile";
	} else if( buf[0] == 0x02 && buf[2] == 0x01 &&
			   (buf[1] == 0x10 || buf[1] == 0x0B) &&
			   (buf[3] == 0x07 || buf[3] == 0x08 || buf[4] == 0x0B) ) {
		/* HP Som binary (last as it's not really particularly good magic) */
		libName = "HpSomBinaryFile";
	} else {
		fprintf( stderr, "Unrecognised binary file\n" );
		fclose(f);
		return NULL;
	}

// Load the specific loader library
#ifndef _WIN32		// Cygwin, Unix/Linux
	libName = std::string("lib/lib") + libName;
#ifdef	__CYGWIN__
	libName += ".dll";		// Cygwin wants .dll, but is otherwise like Unix
#else
	libName += ".so";
#endif
	void* dlHandle = dlopen(libName.c_str(), RTLD_LAZY);
	if (dlHandle == NULL) {
		fprintf( stderr, "Could not open dynamic loader library %s\n", libName.c_str());
		fprintf( stderr, "%s\n", dlerror());
		fclose(f);
		return NULL;
	}
	// Use the handle to find the "construct" function
	constructFcn pFcn = (constructFcn) dlsym(dlHandle, "construct");
#else						// Else MSVC, MinGW
	libName += ".dll";		// Example: ElfBinaryFile.dll (same dir as boomerang.exe)
#ifdef __MINGW32__
	libName = "lib/lib" + libName;
#endif
	HMODULE hModule = LoadLibrary(libName.c_str());
	if(hModule == NULL) {
		int err = GetLastError();
		fprintf( stderr, "Could not open dynamic loader library %s (error #%d)\n", libName.c_str(), err);
		fclose(f);
		return NULL;
	}
	// Use the handle to find the "construct" function
	constructFcn pFcn = (constructFcn) GetProcAddress(hModule, "construct");
#endif

	if (pFcn == NULL) {
		fprintf( stderr, "Loader library %s does not have a construct function\n", libName.c_str());
		fclose(f);
		return NULL;
	}
	// Call the construct function
	res = (*pFcn)();
	fclose(f);
	return res;
}

<|endoftext|>