{"action":"created","comment":{"url":"https://api.github.com/repos/dneg/openvdb_points_dev/pulls/comments/64125601","id":64125601,"diff_hunk":"@@ -0,0 +1,495 @@\n+///////////////////////////////////////////////////////////////////////////\n+//\n+// Copyright (c) 2015-2016 Double Negative Visual Effects\n+//\n+// All rights reserved. This software is distributed under the\n+// Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )\n+//\n+// Redistributions of source code must retain the above copyright\n+// and license notice and the following restrictions and disclaimer.\n+//\n+// *     Neither the name of Double Negative Visual Effects nor the names\n+// of its contributors may be used to endorse or promote products derived\n+// from this software without specific prior written permission.\n+//\n+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,\n+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+// IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE\n+// LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.\n+//\n+///////////////////////////////////////////////////////////////////////////\n+//\n+/// @file IndexFilter.h\n+///\n+/// @authors Dan Bailey\n+///\n+/// @brief  Index filters primarily designed to be used with a FilterIndexIter.\n+///\n+\n+\n+#ifndef OPENVDB_TOOLS_INDEX_FILTER_HAS_BEEN_INCLUDED\n+#define OPENVDB_TOOLS_INDEX_FILTER_HAS_BEEN_INCLUDED\n+\n+#include <openvdb/version.h>\n+#include <openvdb/Types.h>\n+\n+#include <openvdb/math/Transform.h>\n+#include <openvdb/tools/Interpolation.h>\n+\n+#include <openvdb_points/tools/IndexIterator.h>\n+#include <openvdb_points/tools/AttributeArray.h>\n+#include <openvdb_points/tools/AttributeGroup.h>\n+\n+#include <boost/random/uniform_real_distribution.hpp>\n+#include <boost/ptr_container/ptr_vector.hpp>\n+\n+namespace openvdb {\n+OPENVDB_USE_VERSION_NAMESPACE\n+namespace OPENVDB_VERSION_NAME {\n+namespace tools {\n+\n+\n+////////////////////////////////////////\n+\n+\n+namespace index_filter_internal {\n+\n+template <typename RandGenT, typename IntType>\n+struct RandGen\n+{\n+    RandGen(const unsigned int seed, const IntType length) : randGen(seed, 0, length-1) { }\n+    IntType operator()(IntType) { return randGen(); }\n+    openvdb::math::RandInt<IntType, RandGenT> randGen;\n+};\n+\n+// generate a random subset of n indices from the range [0:m]\n+template <typename RandGenT, typename IntType>\n+void generateRandomSubset(std::vector<IntType>& values, const unsigned int seed, const IntType n, const IntType m)\n+{\n+    if (n <= 0)     return;\n+\n+    if (n >= m) {\n+        values.reserve(n);\n+        for (int i = 0; i < int(m); i++)    values.push_back(IntType(i));\n+        return;\n+    }\n+\n+    // reserve and fill vector with ascending indices\n+    values.reserve(m);\n+    for (int i = 0; i < int(m); i++)    values.push_back(i);\n+\n+    // shuffle indices using random generator\n+    RandGen<RandGenT, IntType> randGen(seed, m);\n+    std::random_shuffle(values.begin(), values.end(), randGen);\n+\n+    // resize the container to n elements (does not reduce capacity)\n+    values.resize(n);\n+\n+    // sort the subset of the indices vector that will be used\n+    std::sort(values.begin(), values.end());\n+}\n+\n+\n+} // namespace index_filter_internal\n+\n+\n+/// Index filtering on multiple group membership for inclusion and exclusion\n+class MultiGroupFilter\n+{\n+public:\n+    typedef std::vector<Name> NameVector;\n+    typedef boost::ptr_vector<GroupHandle> HandleVector;\n+\n+    struct Data\n+    {\n+        Data(   const NameVector& _include,\n+                const NameVector& _exclude)\n+            : include(_include)\n+            , exclude(_exclude) { }\n+        const NameVector include;\n+        const NameVector exclude;\n+    };\n+\n+    MultiGroupFilter(   const HandleVector& includeHandles,\n+                        const HandleVector& excludeHandles)\n+        : mIncludeHandles(includeHandles)\n+        , mExcludeHandles(excludeHandles) { }\n+\n+    template <typename LeafT>\n+    static MultiGroupFilter create(const LeafT& leaf, const Data& data) {\n+        HandleVector include;\n+        HandleVector exclude;\n+        for (NameVector::const_iterator  it = data.include.begin(),\n+                                                itEnd = data.include.end(); it != itEnd; ++it) {\n+            if (!leaf.attributeSet().descriptor().hasGroup(*it))    continue;\n+            include.push_back(new GroupHandle(leaf.groupHandle(*it)));\n+        }\n+        for (NameVector::const_iterator  it = data.exclude.begin(),\n+                                                itEnd = data.exclude.end(); it != itEnd; ++it) {\n+            if (!leaf.attributeSet().descriptor().hasGroup(*it))    continue;\n+            exclude.push_back(new GroupHandle(leaf.groupHandle(*it)));\n+        }\n+        return MultiGroupFilter(include, exclude);\n+    }\n+\n+    template <typename IterT>\n+    bool valid(const IterT& iter) const {\n+        for (HandleVector::const_iterator   it = mIncludeHandles.begin(),\n+                                            itEnd = mIncludeHandles.end(); it != itEnd; ++it) {\n+            if (!it->get(*iter))    return false;\n+        }\n+        for (HandleVector::const_iterator   it = mExcludeHandles.begin(),\n+                                            itEnd = mExcludeHandles.end(); it != itEnd; ++it) {\n+            if (it->get(*iter))     return false;\n+        }\n+        return true;\n+    }\n+\n+private:\n+    HandleVector mIncludeHandles;\n+    HandleVector mExcludeHandles;\n+}; // class MultiGroupFilter\n+\n+\n+struct LeafMapData\n+{\n+    typedef std::pair<Index, Index> SeedCountPair;\n+    typedef std::map<openvdb::Coord, SeedCountPair> LeafMap;\n+\n+    LeafMapData() { }\n+\n+    template <typename PointDataTreeT>\n+    void populateByTargetPoints(const PointDataTreeT& tree,\n+                                const Index64 targetPoints,\n+                                const unsigned int seed = 0)\n+    {\n+        const Index64 currentPoints = pointCount(tree);\n+        const float factor = targetPoints > currentPoints ? 1.0f : float(targetPoints) / float(currentPoints);\n+\n+        math::RandInt<unsigned int, boost::mt19937> randGen(seed, 0, std::numeric_limits<unsigned int>::max()-1);\n+\n+        Index32 leafCounter = 0;\n+        float totalPointsFloat = 0.0f;\n+        int totalPoints = 0;\n+        for (typename PointDataTreeT::LeafCIter iter = tree.cbeginLeaf(); iter; ++iter) {\n+            // for the last leaf - use the remaining points to reach the target points\n+            if (leafCounter + 1 == tree.leafCount()) {\n+                const int leafPoints = targetPoints - totalPoints;\n+                leafMap[iter->origin()] = SeedCountPair(randGen(), leafPoints);\n+                break;\n+            }\n+            totalPointsFloat += factor * iter->pointCount();\n+            const int leafPoints = math::Floor(totalPointsFloat);\n+            totalPointsFloat -= leafPoints;\n+            totalPoints += leafPoints;\n+\n+            leafMap[iter->origin()] = SeedCountPair(randGen(), leafPoints);\n+\n+            leafCounter++;\n+        }\n+    }\n+\n+    template <typename PointDataTreeT>\n+    void populateByPercentagePoints(const PointDataTreeT& tree,\n+                                    const float percentage = 10.0f,\n+                                    const unsigned int seed = 0)\n+    {\n+        const int currentPoints = pointCount(tree);\n+        const int targetPoints = int(math::Round((percentage * currentPoints)/100.0f));\n+\n+        populateByTargetPoints(tree, targetPoints, seed);\n+    }\n+\n+    LeafMap leafMap;\n+}; // struct LeafMapData\n+\n+\n+// Random index filtering per leaf\n+template <typename RandGenT>\n+class RandomLeafFilter\n+{\n+public:\n+    typedef LeafMapData Data;\n+    typedef LeafMapData::SeedCountPair SeedCountPair;\n+\n+    RandomLeafFilter(const unsigned int seed, const Index count, const Index total)\n+        : mIndices()\n+        , mCount(count)\n+        , mSubsetOffset(-1)\n+        , mNextIndex(-1)\n+    {\n+        using index_filter_internal::generateRandomSubset;\n+        generateRandomSubset<RandGenT, int>(mIndices, seed, count, total);\n+    }\n+\n+    template <typename LeafT>\n+    static RandomLeafFilter create(const LeafT& leaf, const Data& data) {\n+        const Data::LeafMap::const_iterator it = data.leafMap.find(leaf.origin());\n+        if (it == data.leafMap.end()) {\n+            OPENVDB_THROW(openvdb::KeyError, \"Cannot find leaf origin in map for random filter - \" << leaf.origin());\n+        }\n+        const SeedCountPair& value = it->second;\n+        const unsigned int seed = (unsigned int) value.first;\n+        const Index total = leaf.pointCount();\n+        const Index count = std::min(value.second, total);\n+        return RandomLeafFilter(seed, count, total);\n+    }\n+\n+    inline void next() const {\n+        mSubsetOffset++;\n+        mNextIndex =    mSubsetOffset >= mCount ?\n+                        std::numeric_limits<int>::max() :\n+                        mIndices[mSubsetOffset];\n+    }\n+\n+    template <typename IterT>\n+    bool valid(const IterT& iter) const {\n+        const int index = *iter;\n+        while (mNextIndex < index)     this->next();\n+        return mNextIndex == index;\n+    }\n+\n+private:\n+    std::vector<int> mIndices;\n+    int mCount;\n+    mutable int mSubsetOffset;\n+    mutable int mNextIndex;\n+}; // class RandomLeafFilter\n+\n+\n+// Hash attribute value for deterministic, but approximate filtering\n+template <typename RandGenT, typename IntType>\n+class AttributeHashFilter\n+{\n+public:\n+    struct Data\n+    {\n+        Data(const size_t _index, const double _percentage, const unsigned int _seed = 0)\n+            : index(_index)\n+            , factor(_percentage / 100.0)\n+            , seed(_seed) { }\n+\n+        const size_t index;\n+        const double factor;\n+        const unsigned int seed;\n+    };\n+\n+    AttributeHashFilter(const Data& data,\n+                        const typename AttributeHandle<IntType>::Ptr& idHandle)\n+        : mData(data)\n+        , mIdHandle(idHandle) { }\n+\n+    template <typename LeafT>\n+    static AttributeHashFilter create(const LeafT& leaf, const Data& data) {\n+        return AttributeHashFilter(data, AttributeHandle<IntType>::create(leaf.constAttributeArray(data.index)));\n+    }\n+\n+    template <typename IterT>\n+    bool valid(const IterT& iter) const {\n+        const IntType id = mIdHandle->get(*iter);\n+        const unsigned int seed = mData.seed + (unsigned int) id;\n+        math::Rand01<double, RandGenT> randGen(seed);\n+        return randGen() < mData.factor;\n+    }\n+\n+private:\n+    const Data& mData;\n+    const typename AttributeHandle<IntType>::Ptr mIdHandle;\n+}; // class AttributeHashFilter\n+\n+\n+template <typename LevelSetGridT>\n+class LevelSetFilter\n+{\n+public:\n+    typedef typename LevelSetGridT::ValueType ValueT;\n+\n+    struct Data\n+    {\n+        Data(const LevelSetGridT& _grid, const math::Transform& _transform,\n+             const ValueT _min, const ValueT _max)\n+            : accessor(_grid.getConstAccessor())\n+            , levelSetTransform(_grid.transform())\n+            , transform(_transform)\n+            , min(_min)\n+            , max(_max) { }\n+\n+        // not a reference to ensure const-accessor is unique per-thread\n+        const typename LevelSetGridT::ConstAccessor accessor;\n+        const math::Transform& levelSetTransform;\n+        const math::Transform& transform;\n+        const ValueT min;\n+        const ValueT max;\n+    };\n+\n+    LevelSetFilter(const Data& data,\n+                   const AttributeHandle<openvdb::Vec3f>::Ptr& positionHandle)\n+        : mData(&data)\n+        , mPositionHandle(positionHandle) { }\n+\n+    template <typename LeafT>\n+    static LevelSetFilter create(const LeafT& leaf, const Data& data) {\n+        return LevelSetFilter(data, AttributeHandle<openvdb::Vec3f>::create(leaf.constAttributeArray(\"P\")));\n+    }\n+\n+    template <typename IterT>\n+    bool valid(const IterT& iter) const {\n+        assert(mData);\n+        assert(iter);\n+\n+        const openvdb::Coord ijk = iter.getCoord();\n+        const openvdb::Vec3f voxelIndexSpace = ijk.asVec3d();\n+\n+        // Retrieve point position in voxel space\n+        const openvdb::Vec3f& pointVoxelSpace = mPositionHandle->get(*iter);\n+\n+        // Compute point position in index space\n+        const openvdb::Vec3f pointWorldSpace = mData->transform.indexToWorld(pointVoxelSpace + voxelIndexSpace);\n+        const openvdb::Vec3f pointIndexSpace = mData->levelSetTransform.worldToIndex(pointWorldSpace);\n+\n+        // Perform level-set sampling\n+        const typename LevelSetGridT::ValueType value = BoxSampler::sample(mData->accessor, pointIndexSpace);\n+\n+        // if min is greater than max, we invert so that values are valid outside of the range (not inside)\n+        const bool invert = mData->min > mData->max;\n+\n+        return invert ? (value < mData->max || value > mData->min) : (value < mData->max && value > mData->min);\n+    }\n+\n+private:\n+    const Data* mData;\n+    AttributeHandle<openvdb::Vec3f>::Ptr mPositionHandle;\n+}; // class LevelSetFilter\n+\n+\n+// BBox index filtering\n+class BBoxFilter\n+{\n+public:\n+    struct Data\n+    {\n+        Data(const openvdb::math::Transform& _transform,\n+             const openvdb::BBoxd& _bboxWS)\n+            : transform(_transform)\n+            , bbox(transform.worldToIndex(_bboxWS)) { }\n+        const openvdb::math::Transform& transform;\n+        const openvdb::BBoxd bbox;\n+    };\n+\n+    BBoxFilter( const Data& data,\n+                const AttributeHandle<openvdb::Vec3f>::Ptr& positionHandle)\n+        : mData(&data)\n+        , mPositionHandle(positionHandle) { }\n+\n+    template <typename LeafT>\n+    static BBoxFilter create(const LeafT& leaf, const Data& data) {\n+        return BBoxFilter(data, AttributeHandle<openvdb::Vec3f>::create(leaf.constAttributeArray(\"P\")));\n+    }\n+\n+    template <typename IterT>\n+    bool valid(const IterT& iter) const {\n+        assert(mData);\n+\n+        const openvdb::Coord ijk = iter.getCoord();\n+        const openvdb::Vec3f voxelIndexSpace = ijk.asVec3d();\n+\n+        // Retrieve point position in voxel space\n+        const openvdb::Vec3f& pointVoxelSpace = mPositionHandle->get(*iter);\n+\n+        // Compute point position in index space\n+        const openvdb::Vec3f pointIndexSpace = pointVoxelSpace + voxelIndexSpace;\n+\n+        return mData->bbox.isInside(pointIndexSpace);\n+    }\n+\n+private:\n+    const Data* mData;\n+    const AttributeHandle<openvdb::Vec3f>::Ptr mPositionHandle;\n+}; // class BBoxFilter\n+\n+\n+// Index filtering based on evaluating both sub-filters\n+template <typename T1, typename T2, bool And = true>\n+class BinaryFilter","path":"openvdb_points/tools/IndexFilter.h","position":422,"original_position":422,"commit_id":"eb43a8d20695ac7c1592d20022a29b649619603c","original_commit_id":"fe3dc0b76c3fbc0a114fc8829a6f8aac8767e65c","user":{"login":"danrbailey","id":5251654,"avatar_url":"https://avatars.githubusercontent.com/u/5251654?v=3","gravatar_id":"","url":"https://api.github.com/users/danrbailey","html_url":"https://github.com/danrbailey","followers_url":"https://api.github.com/users/danrbailey/followers","following_url":"https://api.github.com/users/danrbailey/following{/other_user}","gists_url":"https://api.github.com/users/danrbailey/gists{/gist_id}","starred_url":"https://api.github.com/users/danrbailey/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/danrbailey/subscriptions","organizations_url":"https://api.github.com/users/danrbailey/orgs","repos_url":"https://api.github.com/users/danrbailey/repos","events_url":"https://api.github.com/users/danrbailey/events{/privacy}","received_events_url":"https://api.github.com/users/danrbailey/received_events","type":"User","site_admin":false},"body":"Think it's better to leave it as one class, just because it's less code and I don't have to define more cases for the trait.","created_at":"2016-05-21T01:24:54Z","updated_at":"2016-05-21T01:24:54Z","html_url":"https://github.com/dneg/openvdb_points_dev/pull/33#discussion_r64125601","pull_request_url":"https://api.github.com/repos/dneg/openvdb_points_dev/pulls/33","_links":{"self":{"href":"https://api.github.com/repos/dneg/openvdb_points_dev/pulls/comments/64125601"},"html":{"href":"https://github.com/dneg/openvdb_points_dev/pull/33#discussion_r64125601"},"pull_request":{"href":"https://api.github.com/repos/dneg/openvdb_points_dev/pulls/33"}}},"pull_request":{"url":"https://api.github.com/repos/dneg/openvdb_points_dev/pulls/33","id":67677107,"html_url":"https://github.com/dneg/openvdb_points_dev/pull/33","diff_url":"https://github.com/dneg/openvdb_points_dev/pull/33.diff","patch_url":"https://github.com/dneg/openvdb_points_dev/pull/33.patch","issue_url":"https://api.github.com/repos/dneg/openvdb_points_dev/issues/33","number":33,"state":"open","locked":false,"title":"Index Filter","user":{"login":"danrbailey","id":5251654,"avatar_url":"https://avatars.githubusercontent.com/u/5251654?v=3","gravatar_id":"","url":"https://api.github.com/users/danrbailey","html_url":"https://github.com/danrbailey","followers_url":"https://api.github.com/users/danrbailey/followers","following_url":"https://api.github.com/users/danrbailey/following{/other_user}","gists_url":"https://api.github.com/users/danrbailey/gists{/gist_id}","starred_url":"https://api.github.com/users/danrbailey/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/danrbailey/subscriptions","organizations_url":"https://api.github.com/users/danrbailey/orgs","repos_url":"https://api.github.com/users/danrbailey/repos","events_url":"https://api.github.com/users/danrbailey/events{/privacy}","received_events_url":"https://api.github.com/users/danrbailey/received_events","type":"User","site_admin":false},"body":"* Index filters - random per leaf, hashed, bbox, level set, etc\r\n* GR Primitive extension to display only a specific group\r\n* OpenVDB Points Group SOP for filtering points","created_at":"2016-04-25T07:43:46Z","updated_at":"2016-05-21T01:24:54Z","closed_at":null,"merged_at":null,"merge_commit_sha":"56f014860f82717a5aa417af0bcb91346e0eec3f","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/dneg/openvdb_points_dev/pulls/33/commits","review_comments_url":"https://api.github.com/repos/dneg/openvdb_points_dev/pulls/33/comments","review_comment_url":"https://api.github.com/repos/dneg/openvdb_points_dev/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dneg/openvdb_points_dev/issues/33/comments","statuses_url":"https://api.github.com/repos/dneg/openvdb_points_dev/statuses/eb43a8d20695ac7c1592d20022a29b649619603c","head":{"label":"dneg:indexfilter","ref":"indexfilter","sha":"eb43a8d20695ac7c1592d20022a29b649619603c","user":{"login":"dneg","id":5524887,"avatar_url":"https://avatars.githubusercontent.com/u/5524887?v=3","gravatar_id":"","url":"https://api.github.com/users/dneg","html_url":"https://github.com/dneg","followers_url":"https://api.github.com/users/dneg/followers","following_url":"https://api.github.com/users/dneg/following{/other_user}","gists_url":"https://api.github.com/users/dneg/gists{/gist_id}","starred_url":"https://api.github.com/users/dneg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dneg/subscriptions","organizations_url":"https://api.github.com/users/dneg/orgs","repos_url":"https://api.github.com/users/dneg/repos","events_url":"https://api.github.com/users/dneg/events{/privacy}","received_events_url":"https://api.github.com/users/dneg/received_events","type":"Organization","site_admin":false},"repo":{"id":35619792,"name":"openvdb_points_dev","full_name":"dneg/openvdb_points_dev","owner":{"login":"dneg","id":5524887,"avatar_url":"https://avatars.githubusercontent.com/u/5524887?v=3","gravatar_id":"","url":"https://api.github.com/users/dneg","html_url":"https://github.com/dneg","followers_url":"https://api.github.com/users/dneg/followers","following_url":"https://api.github.com/users/dneg/following{/other_user}","gists_url":"https://api.github.com/users/dneg/gists{/gist_id}","starred_url":"https://api.github.com/users/dneg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dneg/subscriptions","organizations_url":"https://api.github.com/users/dneg/orgs","repos_url":"https://api.github.com/users/dneg/repos","events_url":"https://api.github.com/users/dneg/events{/privacy}","received_events_url":"https://api.github.com/users/dneg/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dneg/openvdb_points_dev","description":"OpenVDB Points Development Repository","fork":false,"url":"https://api.github.com/repos/dneg/openvdb_points_dev","forks_url":"https://api.github.com/repos/dneg/openvdb_points_dev/forks","keys_url":"https://api.github.com/repos/dneg/openvdb_points_dev/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dneg/openvdb_points_dev/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dneg/openvdb_points_dev/teams","hooks_url":"https://api.github.com/repos/dneg/openvdb_points_dev/hooks","issue_events_url":"https://api.github.com/repos/dneg/openvdb_points_dev/issues/events{/number}","events_url":"https://api.github.com/repos/dneg/openvdb_points_dev/events","assignees_url":"https://api.github.com/repos/dneg/openvdb_points_dev/assignees{/user}","branches_url":"https://api.github.com/repos/dneg/openvdb_points_dev/branches{/branch}","tags_url":"https://api.github.com/repos/dneg/openvdb_points_dev/tags","blobs_url":"https://api.github.com/repos/dneg/openvdb_points_dev/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dneg/openvdb_points_dev/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dneg/openvdb_points_dev/git/refs{/sha}","trees_url":"https://api.github.com/repos/dneg/openvdb_points_dev/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dneg/openvdb_points_dev/statuses/{sha}","languages_url":"https://api.github.com/repos/dneg/openvdb_points_dev/languages","stargazers_url":"https://api.github.com/repos/dneg/openvdb_points_dev/stargazers","contributors_url":"https://api.github.com/repos/dneg/openvdb_points_dev/contributors","subscribers_url":"https://api.github.com/repos/dneg/openvdb_points_dev/subscribers","subscription_url":"https://api.github.com/repos/dneg/openvdb_points_dev/subscription","commits_url":"https://api.github.com/repos/dneg/openvdb_points_dev/commits{/sha}","git_commits_url":"https://api.github.com/repos/dneg/openvdb_points_dev/git/commits{/sha}","comments_url":"https://api.github.com/repos/dneg/openvdb_points_dev/comments{/number}","issue_comment_url":"https://api.github.com/repos/dneg/openvdb_points_dev/issues/comments{/number}","contents_url":"https://api.github.com/repos/dneg/openvdb_points_dev/contents/{+path}","compare_url":"https://api.github.com/repos/dneg/openvdb_points_dev/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dneg/openvdb_points_dev/merges","archive_url":"https://api.github.com/repos/dneg/openvdb_points_dev/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dneg/openvdb_points_dev/downloads","issues_url":"https://api.github.com/repos/dneg/openvdb_points_dev/issues{/number}","pulls_url":"https://api.github.com/repos/dneg/openvdb_points_dev/pulls{/number}","milestones_url":"https://api.github.com/repos/dneg/openvdb_points_dev/milestones{/number}","notifications_url":"https://api.github.com/repos/dneg/openvdb_points_dev/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dneg/openvdb_points_dev/labels{/name}","releases_url":"https://api.github.com/repos/dneg/openvdb_points_dev/releases{/id}","deployments_url":"https://api.github.com/repos/dneg/openvdb_points_dev/deployments","created_at":"2015-05-14T15:38:43Z","updated_at":"2016-05-20T21:38:35Z","pushed_at":"2016-05-18T02:41:31Z","git_url":"git://github.com/dneg/openvdb_points_dev.git","ssh_url":"git@github.com:dneg/openvdb_points_dev.git","clone_url":"https://github.com/dneg/openvdb_points_dev.git","svn_url":"https://github.com/dneg/openvdb_points_dev","homepage":"","size":1572,"stargazers_count":28,"watchers_count":28,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":11,"mirror_url":null,"open_issues_count":1,"forks":11,"open_issues":1,"watchers":28,"default_branch":"master"}},"base":{"label":"dneg:master","ref":"master","sha":"34a095394f0a83694e5464d52bb81f9d2abff9c3","user":{"login":"dneg","id":5524887,"avatar_url":"https://avatars.githubusercontent.com/u/5524887?v=3","gravatar_id":"","url":"https://api.github.com/users/dneg","html_url":"https://github.com/dneg","followers_url":"https://api.github.com/users/dneg/followers","following_url":"https://api.github.com/users/dneg/following{/other_user}","gists_url":"https://api.github.com/users/dneg/gists{/gist_id}","starred_url":"https://api.github.com/users/dneg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dneg/subscriptions","organizations_url":"https://api.github.com/users/dneg/orgs","repos_url":"https://api.github.com/users/dneg/repos","events_url":"https://api.github.com/users/dneg/events{/privacy}","received_events_url":"https://api.github.com/users/dneg/received_events","type":"Organization","site_admin":false},"repo":{"id":35619792,"name":"openvdb_points_dev","full_name":"dneg/openvdb_points_dev","owner":{"login":"dneg","id":5524887,"avatar_url":"https://avatars.githubusercontent.com/u/5524887?v=3","gravatar_id":"","url":"https://api.github.com/users/dneg","html_url":"https://github.com/dneg","followers_url":"https://api.github.com/users/dneg/followers","following_url":"https://api.github.com/users/dneg/following{/other_user}","gists_url":"https://api.github.com/users/dneg/gists{/gist_id}","starred_url":"https://api.github.com/users/dneg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dneg/subscriptions","organizations_url":"https://api.github.com/users/dneg/orgs","repos_url":"https://api.github.com/users/dneg/repos","events_url":"https://api.github.com/users/dneg/events{/privacy}","received_events_url":"https://api.github.com/users/dneg/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dneg/openvdb_points_dev","description":"OpenVDB Points Development Repository","fork":false,"url":"https://api.github.com/repos/dneg/openvdb_points_dev","forks_url":"https://api.github.com/repos/dneg/openvdb_points_dev/forks","keys_url":"https://api.github.com/repos/dneg/openvdb_points_dev/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dneg/openvdb_points_dev/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dneg/openvdb_points_dev/teams","hooks_url":"https://api.github.com/repos/dneg/openvdb_points_dev/hooks","issue_events_url":"https://api.github.com/repos/dneg/openvdb_points_dev/issues/events{/number}","events_url":"https://api.github.com/repos/dneg/openvdb_points_dev/events","assignees_url":"https://api.github.com/repos/dneg/openvdb_points_dev/assignees{/user}","branches_url":"https://api.github.com/repos/dneg/openvdb_points_dev/branches{/branch}","tags_url":"https://api.github.com/repos/dneg/openvdb_points_dev/tags","blobs_url":"https://api.github.com/repos/dneg/openvdb_points_dev/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dneg/openvdb_points_dev/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dneg/openvdb_points_dev/git/refs{/sha}","trees_url":"https://api.github.com/repos/dneg/openvdb_points_dev/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dneg/openvdb_points_dev/statuses/{sha}","languages_url":"https://api.github.com/repos/dneg/openvdb_points_dev/languages","stargazers_url":"https://api.github.com/repos/dneg/openvdb_points_dev/stargazers","contributors_url":"https://api.github.com/repos/dneg/openvdb_points_dev/contributors","subscribers_url":"https://api.github.com/repos/dneg/openvdb_points_dev/subscribers","subscription_url":"https://api.github.com/repos/dneg/openvdb_points_dev/subscription","commits_url":"https://api.github.com/repos/dneg/openvdb_points_dev/commits{/sha}","git_commits_url":"https://api.github.com/repos/dneg/openvdb_points_dev/git/commits{/sha}","comments_url":"https://api.github.com/repos/dneg/openvdb_points_dev/comments{/number}","issue_comment_url":"https://api.github.com/repos/dneg/openvdb_points_dev/issues/comments{/number}","contents_url":"https://api.github.com/repos/dneg/openvdb_points_dev/contents/{+path}","compare_url":"https://api.github.com/repos/dneg/openvdb_points_dev/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dneg/openvdb_points_dev/merges","archive_url":"https://api.github.com/repos/dneg/openvdb_points_dev/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dneg/openvdb_points_dev/downloads","issues_url":"https://api.github.com/repos/dneg/openvdb_points_dev/issues{/number}","pulls_url":"https://api.github.com/repos/dneg/openvdb_points_dev/pulls{/number}","milestones_url":"https://api.github.com/repos/dneg/openvdb_points_dev/milestones{/number}","notifications_url":"https://api.github.com/repos/dneg/openvdb_points_dev/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dneg/openvdb_points_dev/labels{/name}","releases_url":"https://api.github.com/repos/dneg/openvdb_points_dev/releases{/id}","deployments_url":"https://api.github.com/repos/dneg/openvdb_points_dev/deployments","created_at":"2015-05-14T15:38:43Z","updated_at":"2016-05-20T21:38:35Z","pushed_at":"2016-05-18T02:41:31Z","git_url":"git://github.com/dneg/openvdb_points_dev.git","ssh_url":"git@github.com:dneg/openvdb_points_dev.git","clone_url":"https://github.com/dneg/openvdb_points_dev.git","svn_url":"https://github.com/dneg/openvdb_points_dev","homepage":"","size":1572,"stargazers_count":28,"watchers_count":28,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":11,"mirror_url":null,"open_issues_count":1,"forks":11,"open_issues":1,"watchers":28,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dneg/openvdb_points_dev/pulls/33"},"html":{"href":"https://github.com/dneg/openvdb_points_dev/pull/33"},"issue":{"href":"https://api.github.com/repos/dneg/openvdb_points_dev/issues/33"},"comments":{"href":"https://api.github.com/repos/dneg/openvdb_points_dev/issues/33/comments"},"review_comments":{"href":"https://api.github.com/repos/dneg/openvdb_points_dev/pulls/33/comments"},"review_comment":{"href":"https://api.github.com/repos/dneg/openvdb_points_dev/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dneg/openvdb_points_dev/pulls/33/commits"},"statuses":{"href":"https://api.github.com/repos/dneg/openvdb_points_dev/statuses/eb43a8d20695ac7c1592d20022a29b649619603c"}}}}
{"actor":{"display_login":"danrbailey"}}