void
      OctreeLowMemBase<DataT, LeafT>::deserializeLeafCallback (
                                                         OctreeLeaf& leaf_arg,
                                                         const OctreeKey& key_arg,
                                                         typename std::vector<DataT>::const_iterator& dataVectorIterator_arg,
                                                         typename std::vector<DataT>::const_iterator& dataVectorEndIterator_arg)
      {
        OctreeKey dataKey;
        bool bKeyBasedEncoding = false;

        // add DataT objects to octree leaf as long as their key fit to voxel
        while ((dataVectorIterator_arg != dataVectorEndIterator_arg)
            && (this->genOctreeKeyForDataT (*dataVectorIterator_arg, dataKey) && (dataKey == key_arg)))
        {
          leaf_arg.setData (*dataVectorIterator_arg);
          dataVectorIterator_arg++;
          bKeyBasedEncoding = true;
        }

        // add single DataT object to octree if key-based encoding is disabled
        if (!bKeyBasedEncoding)
        {
          leaf_arg.setData (*dataVectorIterator_arg);
          dataVectorIterator_arg++;
        }
      }
      void
      OctreeLowMemBase<DataT, LeafT>::deserializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg)
      {

        DataT newDataT;

        // initialize new leaf child
        if (genDataTByOctreeKey (key_arg, newDataT))
        {
          leaf_arg.setData (newDataT);
        }

      }
      void
      OctreeLowMemBase<DataT, LeafT>::deserializeTreeAndSerializeLeafCallback (OctreeLeaf& leaf_arg,
                                                                         const OctreeKey& key_arg,
                                                                         std::vector<DataT>& dataVector_arg)
      {

        DataT newDataT;

        // initialize new leaf child
        if (genDataTByOctreeKey (key_arg, newDataT))
        {
          leaf_arg.setData (newDataT);
          dataVector_arg.push_back (newDataT);
        }
      }
Exemple #4
0
    int
    pcl::octree::OctreePointCloudSearch<PointT, LeafT, OctreeT>::getIntersectedVoxelIndicesRecursive (
        double minX, double minY, double minZ, double maxX, double maxY, double maxZ, unsigned char a,
        const OctreeNode* node, const OctreeKey& key, std::vector<int> &k_indices) const
    {
      if (maxX < 0.0 || maxY < 0.0 || maxZ < 0.0)
        return (0);

      // If leaf node, get voxel center and increment intersection count
      if (node->getNodeType () == LEAF_NODE)
      {
        OctreeLeaf* leaf = (OctreeLeaf*)node;
        vector<int> indices;

        // decode leaf node into decodedPointVector
        leaf->getData (indices);
        for (size_t i = 0; i < indices.size (); i++)
        {
          k_indices.push_back (indices[i]);
        }

        return (1);
      }

      // Voxel intersection count for branches children
      int voxelCount = 0;

      // Voxel mid lines
      double midX = 0.5 * (minX + maxX);
      double midY = 0.5 * (minY + maxY);
      double midZ = 0.5 * (minZ + maxZ);

      // First voxel node ray will intersect
      int currNode = getFirstIntersectedNode (minX, minY, minZ, midX, midY, midZ);

      // Child index, node and key
      unsigned char childIdx;
      const OctreeNode *childNode;
      OctreeKey childKey;
      do
      {
        if (currNode != 0)
          childIdx = currNode ^ a;
        else
          childIdx = a;

        // childNode == 0 if childNode doesn't exist
        childNode = this->getBranchChild ((OctreeBranch&)*node, childIdx);
        // Generate new key for current branch voxel
        childKey.x = (key.x << 1) | (!!(childIdx & (1 << 2)));
        childKey.y = (key.y << 1) | (!!(childIdx & (1 << 1)));
        childKey.z = (key.z << 1) | (!!(childIdx & (1 << 0)));

        // Recursively call each intersected child node, selecting the next
        //   node intersected by the ray.  Children that do not intersect will
        //   not be traversed.
        switch (currNode)
        {
          case 0:
            if (childNode)
              voxelCount += getIntersectedVoxelIndicesRecursive (minX, minY, minZ, midX, midY, midZ, a, childNode,
                                                                 childKey, k_indices);
            currNode = getNextIntersectedNode (midX, midY, midZ, 4, 2, 1);
            break;

          case 1:
            if (childNode)
              voxelCount += getIntersectedVoxelIndicesRecursive (minX, minY, midZ, midX, midY, maxZ, a, childNode,
                                                                 childKey, k_indices);
            currNode = getNextIntersectedNode (midX, midY, maxZ, 5, 3, 8);
            break;

          case 2:
            if (childNode)
              voxelCount += getIntersectedVoxelIndicesRecursive (minX, midY, minZ, midX, maxY, midZ, a, childNode,
                                                                 childKey, k_indices);
            currNode = getNextIntersectedNode (midX, maxY, midZ, 6, 8, 3);
            break;

          case 3:
            if (childNode)
              voxelCount += getIntersectedVoxelIndicesRecursive (minX, midY, midZ, midX, maxY, maxZ, a, childNode,
                                                                 childKey, k_indices);
            currNode = getNextIntersectedNode (midX, maxY, maxZ, 7, 8, 8);
            break;

          case 4:
            if (childNode)
              voxelCount += getIntersectedVoxelIndicesRecursive (midX, minY, minZ, maxX, midY, midZ, a, childNode,
                                                                 childKey, k_indices);
            currNode = getNextIntersectedNode (maxX, midY, midZ, 8, 6, 5);
            break;

          case 5:
            if (childNode)
              voxelCount += getIntersectedVoxelIndicesRecursive (midX, minY, midZ, maxX, midY, maxZ, a, childNode,
                                                                 childKey, k_indices);
            currNode = getNextIntersectedNode (maxX, midY, maxZ, 8, 7, 8);
            break;

          case 6:
            if (childNode)
              voxelCount += getIntersectedVoxelIndicesRecursive (midX, midY, minZ, maxX, maxY, midZ, a, childNode,
                                                                 childKey, k_indices);
            currNode = getNextIntersectedNode (maxX, maxY, midZ, 8, 8, 7);
            break;

          case 7:
            if (childNode)
              voxelCount += getIntersectedVoxelIndicesRecursive (midX, midY, midZ, maxX, maxY, maxZ, a, childNode,
                                                                 childKey, k_indices);
            currNode = 8;
            break;
        }
      } while (currNode < 8);

      return (voxelCount);
    }
Exemple #5
0
  void
  pcl::octree::OctreePointCloudSearch<PointT, LeafT, OctreeT>::boxSearchRecursive (const Eigen::Vector3f &min_pt,
                                                                                   const Eigen::Vector3f &max_pt,
                                                                                   const OctreeBranch* node,
                                                                                   const OctreeKey& key,
                                                                                   unsigned int treeDepth,
                                                                                   std::vector<int>& k_indices) const
{
  // child iterator
  unsigned char childIdx;

  // iterate over all children
  for (childIdx = 0; childIdx < 8; childIdx++)
  {
    if (!this->branchHasChild (*node, childIdx))
      continue;

    const OctreeNode* childNode;
    childNode = this->getBranchChild (*node, childIdx);

    OctreeKey newKey;
    // generate new key for current branch voxel
    newKey.x = (key.x << 1) + (!!(childIdx & (1 << 2)));
    newKey.y = (key.y << 1) + (!!(childIdx & (1 << 1)));
    newKey.z = (key.z << 1) + (!!(childIdx & (1 << 0)));

    // voxel corners
    Eigen::Vector3f lowerVoxelCorner;
    Eigen::Vector3f upperVoxelCorner;
    // get voxel coordinates
    this->genVoxelBoundsFromOctreeKey (newKey, treeDepth, lowerVoxelCorner, upperVoxelCorner);

    // test if search region overlap with voxel space

    if ( !( (lowerVoxelCorner (0) > max_pt (0)) || (min_pt (0)>upperVoxelCorner(0)) ||
            (lowerVoxelCorner (1) > max_pt (1)) || (min_pt (1)>upperVoxelCorner(1)) ||
            (lowerVoxelCorner (2) > max_pt (2)) || (min_pt (2)>upperVoxelCorner(2)) ) )
    {

      if (treeDepth < this->octreeDepth_)
      {
        // we have not reached maximum tree depth
        boxSearchRecursive (min_pt, max_pt, (OctreeBranch*)childNode, newKey, treeDepth + 1, k_indices);
      }
      else
        {
          // we reached leaf node level
          size_t i;
          vector<int> decodedPointVector;
          bool bInBox;

          OctreeLeaf* childLeaf = (OctreeLeaf*)childNode;

          // decode leaf node into decodedPointVector
          childLeaf->getData (decodedPointVector);

          // Linearly iterate over all decoded (unsorted) points
          for (i = 0; i < decodedPointVector.size (); i++)
          {
            const PointT& candidatePoint = this->getPointByIndex (decodedPointVector[i]);

            // check if point falls within search box
            bInBox = ( (candidatePoint.x > min_pt (0)) && (candidatePoint.x < max_pt (0)) &&
                       (candidatePoint.y > min_pt (1)) && (candidatePoint.y < max_pt (1)) &&
                       (candidatePoint.z > min_pt (2)) && (candidatePoint.z < max_pt (2)) );

            if (bInBox)
                // add to result vector
                k_indices.push_back (decodedPointVector[i]);
           }

        }

      }
  }
}
Exemple #6
0
  void
  pcl::octree::OctreePointCloudSearch<PointT, LeafT, OctreeT>::approxNearestSearchRecursive (const PointT & point,
                                                                                             const OctreeBranch* node,
                                                                                             const OctreeKey& key,
                                                                                             unsigned int treeDepth,
                                                                                             int& result_index,
                                                                                             float& sqr_distance)
  {
    unsigned char childIdx;
    unsigned char minChildIdx;
    double minVoxelCenterDistance;

    OctreeKey minChildKey;
    OctreeKey newKey;

    const OctreeNode* childNode;

    // set minimum voxel distance to maximum value
    minVoxelCenterDistance = numeric_limits<double>::max ();

    minChildIdx = 0xFF;

    // iterate over all children
    for (childIdx = 0; childIdx < 8; childIdx++)
    {
      if (!this->branchHasChild (*node, childIdx))
        continue;

      PointT voxelCenter;
      double voxelPointDist;

      newKey.x = (key.x << 1) + (!!(childIdx & (1 << 2)));
      newKey.y = (key.y << 1) + (!!(childIdx & (1 << 1)));
      newKey.z = (key.z << 1) + (!!(childIdx & (1 << 0)));

      // generate voxel center point for voxel at key
      this->genVoxelCenterFromOctreeKey (newKey, treeDepth, voxelCenter);

      voxelPointDist = pointSquaredDist (voxelCenter, point);

      // search for child voxel with shortest distance to search point
      if (voxelPointDist >= minVoxelCenterDistance)
        continue;

      minVoxelCenterDistance = voxelPointDist;
      minChildIdx = childIdx;
      minChildKey = newKey;
    }

    // make sure we found at least one branch child
    assert(minChildIdx<8);

    childNode = this->getBranchChild (*node, minChildIdx);

    if (treeDepth < this->octreeDepth_)
    {
      // we have not reached maximum tree depth
      approxNearestSearchRecursive (point, (OctreeBranch*)childNode, minChildKey, treeDepth + 1, result_index,
                                    sqr_distance);
    }
    else
    {
      // we reached leaf node level

      double squaredDist;
      double smallestSquaredDist;
      size_t i;
      vector<int> decodedPointVector;

      OctreeLeaf* childLeaf = (OctreeLeaf*)childNode;

      smallestSquaredDist = numeric_limits<double>::max ();

      // decode leaf node into decodedPointVector
      childLeaf->getData (decodedPointVector);

      // Linearly iterate over all decoded (unsorted) points
      for (i = 0; i < decodedPointVector.size (); i++)
      {
        const PointT& candidatePoint = this->getPointByIndex (decodedPointVector[i]);

        // calculate point distance to search point
        squaredDist = pointSquaredDist (candidatePoint, point);

        // check if a closer match is found
        if (squaredDist >= smallestSquaredDist)
          continue;

        result_index = decodedPointVector[i];
        sqr_distance = smallestSquaredDist = squaredDist;
      }
    }
  }
Exemple #7
0
  void
  pcl::octree::OctreePointCloudSearch<PointT, LeafT, OctreeT>::getNeighborsWithinRadiusRecursive (
      const PointT & point, const double radiusSquared, const OctreeBranch* node, const OctreeKey& key,
      unsigned int treeDepth, std::vector<int>& k_indices, std::vector<float>& k_sqr_distances,
      unsigned int max_nn) const
  {
    // child iterator
    unsigned char childIdx;

    // get spatial voxel information
    double voxelSquaredDiameter = this->getVoxelSquaredDiameter (treeDepth);

    // iterate over all children
    for (childIdx = 0; childIdx < 8; childIdx++)
    {
      if (!this->branchHasChild (*node, childIdx))
        continue;

      const OctreeNode* childNode;
      childNode = this->getBranchChild (*node, childIdx);

      OctreeKey newKey;
      PointT voxelCenter;
      double squaredDist;

      // generate new key for current branch voxel
      newKey.x = (key.x << 1) + (!!(childIdx & (1 << 2)));
      newKey.y = (key.y << 1) + (!!(childIdx & (1 << 1)));
      newKey.z = (key.z << 1) + (!!(childIdx & (1 << 0)));

      // generate voxel center point for voxel at key
      this->genVoxelCenterFromOctreeKey (newKey, treeDepth, voxelCenter);

      // calculate distance to search point
      squaredDist = pointSquaredDist ((const PointT &)voxelCenter, point);

      // if distance is smaller than search radius
      if (squaredDist + this->epsilon_
          <= voxelSquaredDiameter / 4.0 + radiusSquared + sqrt (voxelSquaredDiameter * radiusSquared))
      {

        if (treeDepth < this->octreeDepth_)
        {
          // we have not reached maximum tree depth
          getNeighborsWithinRadiusRecursive (point, radiusSquared, (OctreeBranch*)childNode, newKey, treeDepth + 1,
                                             k_indices, k_sqr_distances, max_nn);
          if (max_nn != 0 && k_indices.size () == (unsigned int)max_nn)
            return;
        }
        else
        {
          // we reached leaf node level

          size_t i;
          OctreeLeaf* childLeaf = (OctreeLeaf*)childNode;
          vector<int> decodedPointVector;

          // decode leaf node into decodedPointVector
          childLeaf->getData (decodedPointVector);

          // Linearly iterate over all decoded (unsorted) points
          for (i = 0; i < decodedPointVector.size (); i++)
          {
            const PointT& candidatePoint = this->getPointByIndex (decodedPointVector[i]);

            // calculate point distance to search point
            squaredDist = pointSquaredDist (candidatePoint, point);

            // check if a match is found
            if (squaredDist > radiusSquared)
              continue;

            // add point to result vector
            k_indices.push_back (decodedPointVector[i]);
            k_sqr_distances.push_back (squaredDist);

            if (max_nn != 0 && k_indices.size () == (unsigned int)max_nn)
              return;
          }
        }
      }
    }
  }
Exemple #8
0
  double
  pcl::octree::OctreePointCloudSearch<PointT, LeafT, OctreeT>::getKNearestNeighborRecursive (
      const PointT & point, unsigned int K, const OctreeBranch* node, const OctreeKey& key, unsigned int treeDepth,
      const double squaredSearchRadius, std::vector<prioPointQueueEntry>& pointCandidates) const
  {
    std::vector<prioBranchQueueEntry> searchEntryHeap;
    searchEntryHeap.resize (8);

    unsigned char childIdx;

    OctreeKey newKey;

    double smallestSquaredDist = squaredSearchRadius;

    // get spatial voxel information
    double voxelSquaredDiameter = this->getVoxelSquaredDiameter (treeDepth);

    // iterate over all children
    for (childIdx = 0; childIdx < 8; childIdx++)
    {
      if (this->branchHasChild (*node, childIdx))
      {
        PointT voxelCenter;

        searchEntryHeap[childIdx].key.x = (key.x << 1) + (!!(childIdx & (1 << 2)));
        searchEntryHeap[childIdx].key.y = (key.y << 1) + (!!(childIdx & (1 << 1)));
        searchEntryHeap[childIdx].key.z = (key.z << 1) + (!!(childIdx & (1 << 0)));

        // generate voxel center point for voxel at key
        this->genVoxelCenterFromOctreeKey (searchEntryHeap[childIdx].key, treeDepth, voxelCenter);

        // generate new priority queue element
        searchEntryHeap[childIdx].node = this->getBranchChild (*node, childIdx);
        searchEntryHeap[childIdx].pointDistance = pointSquaredDist (voxelCenter, point);
      }
      else
      {
        searchEntryHeap[childIdx].pointDistance = numeric_limits<double>::infinity ();
      }
    }

    std::sort (searchEntryHeap.begin (), searchEntryHeap.end ());

    // iterate over all children in priority queue
    // check if the distance to seach candidate is smaller than the best point distance (smallestSquaredDist)
    while ((!searchEntryHeap.empty ())
        && (searchEntryHeap.back ().pointDistance
            < smallestSquaredDist + voxelSquaredDiameter / 4.0 + sqrt (smallestSquaredDist * voxelSquaredDiameter)
                - this->epsilon_))
    {
      const OctreeNode* childNode;

      // read from priority queue element
      childNode = searchEntryHeap.back ().node;
      newKey = searchEntryHeap.back ().key;

      if (treeDepth < this->octreeDepth_)
      {
        // we have not reached maximum tree depth
        smallestSquaredDist = getKNearestNeighborRecursive (point, K, (OctreeBranch*)childNode, newKey, treeDepth + 1,
                                                            smallestSquaredDist, pointCandidates);
      }
      else
      {
        // we reached leaf node level

        double squaredDist;
        size_t i;
        vector<int> decodedPointVector;

        OctreeLeaf* childLeaf = (OctreeLeaf*)childNode;

        // decode leaf node into decodedPointVector
        childLeaf->getData (decodedPointVector);

        // Linearly iterate over all decoded (unsorted) points
        for (i = 0; i < decodedPointVector.size (); i++)
        {

          const PointT& candidatePoint = this->getPointByIndex (decodedPointVector[i]);

          // calculate point distance to search point
          squaredDist = pointSquaredDist (candidatePoint, point);

          // check if a closer match is found
          if (squaredDist < smallestSquaredDist)
          {
            prioPointQueueEntry pointEntry;

            pointEntry.pointDistance_ = squaredDist;
            pointEntry.pointIdx_ = decodedPointVector[i];
            pointCandidates.push_back (pointEntry);
          }
        }

        std::sort (pointCandidates.begin (), pointCandidates.end ());

        if (pointCandidates.size () > K)
          pointCandidates.resize (K);

        if (pointCandidates.size () == K)
          smallestSquaredDist = pointCandidates.back ().pointDistance_;
      }
      // pop element from priority queue
      searchEntryHeap.pop_back ();
    }

    return (smallestSquaredDist);
  }
 void
 OctreeLowMemBase<DataT, LeafT>::serializeLeafCallback (OctreeLeaf& leaf_arg, const OctreeKey& key_arg,
                                                  std::vector<DataT>& dataVector_arg)
 {
   leaf_arg.getData (dataVector_arg);
 }