Skip to content

Commit

Permalink
PointBuffer/Schema orientation #209. A PointBuffer may be
Browse files Browse the repository at this point in the history
POINT_INTERLEAVED or DIMENSION_INTERLEAVED with the default being
POINT_INTERLEAVED.
  • Loading branch information
hobu committed Nov 23, 2013
1 parent 3eec6b1 commit eb5b3d6
Show file tree
Hide file tree
Showing 13 changed files with 451 additions and 55 deletions.
81 changes: 68 additions & 13 deletions include/pdal/PointBuffer.hpp
Expand Up @@ -60,13 +60,6 @@ namespace pdal
typedef boost::interprocess::allocator<boost::uint8_t, boost::interprocess::managed_shared_memory::segment_manager> ShmemAllocator;
typedef boost::container::vector<boost::uint8_t, ShmemAllocator> PointBufferVector;

enum Orientation
{
POINT_INTERLEAVED = 1,
DIMENSION_INTERLEAVED = 2,
UNKNOWN_INTERLEAVED = 256
};

} // pointbuffer


Expand Down Expand Up @@ -275,7 +268,23 @@ class PDAL_DLL PointBuffer
/// @param pointIndex position to start accessing
inline boost::uint8_t* getData(boost::uint32_t pointIndex) const
{
return const_cast<boost::uint8_t*>(&(m_data.front())) + m_byteSize * pointIndex;
#if DEBUG
#endif
pointbuffer::PointBufferByteSize position(0);
if (m_orientation == schema::POINT_INTERLEAVED)
{
position = static_cast<pointbuffer::PointBufferByteSize>(m_byteSize) * \
static_cast<pointbuffer::PointBufferByteSize>(pointIndex);

}
else if (m_orientation == schema::DIMENSION_INTERLEAVED)
{
pointbuffer::PointBufferByteSize offset(0);
offset = m_schema.getDimension(pointIndex).getByteOffset();
position = static_cast<pointbuffer::PointBufferByteSize>(m_numPoints) * offset;
}
return const_cast<boost::uint8_t*>(&(m_data.front())) + position;

}

/// copies the raw data into your own byte array and sets the size
Expand Down Expand Up @@ -323,6 +332,9 @@ class PDAL_DLL PointBuffer
/// with the given point size and force a new reallocation of the data buffer.
void resize(boost::uint32_t const& capacity, bool bExact=false);

/// @return a new PointBuffer with all ignored dimensions removed
PointBuffer pack() const;

/** @name Serialization
*/
/*! returns a boost::property_tree containing the point records, which is
Expand Down Expand Up @@ -392,6 +404,10 @@ class PDAL_DLL PointBuffer
// We cache m_schema.getByteSize() here because it would end up
// being dereferenced for every point read otherwise.
schema::size_type m_byteSize;

// We cache m_schema.getOrientation() here because it would end
// up being dereferenced for every point read
schema::Orientation m_orientation;

Metadata m_metadata;
boost::interprocess::managed_shared_memory *m_segment;
Expand All @@ -408,12 +424,30 @@ inline void PointBuffer::setField(pdal::Dimension const& dim, boost::uint32_t po
{
if (dim.getPosition() == -1)
{
// this is a little harsh, but we'll keep it for now as we shake things out
throw buffer_error("This dimension has no identified position in a schema. Use the setRawField method to access an arbitrary byte position.");
}

pointbuffer::PointBufferByteSize point_start_byte_position = static_cast<pointbuffer::PointBufferByteSize>(pointIndex) * static_cast<pointbuffer::PointBufferByteSize>(m_byteSize);
pointbuffer::PointBufferByteSize offset = point_start_byte_position + static_cast<pointbuffer::PointBufferByteSize>(dim.getByteOffset());
pointbuffer::PointBufferByteSize point_start_byte_position(0);
pointbuffer::PointBufferByteSize offset(0);

if (m_orientation == schema::POINT_INTERLEAVED)
{
point_start_byte_position = static_cast<pointbuffer::PointBufferByteSize>(pointIndex) * \
static_cast<pointbuffer::PointBufferByteSize>(m_byteSize);
offset = point_start_byte_position + \
static_cast<pointbuffer::PointBufferByteSize>(dim.getByteOffset());
}
else if (m_orientation == schema::DIMENSION_INTERLEAVED)
{
point_start_byte_position = static_cast<pointbuffer::PointBufferByteSize>(m_capacity) * \
static_cast<pointbuffer::PointBufferByteSize>(dim.getByteOffset());
offset = point_start_byte_position + \
static_cast<pointbuffer::PointBufferByteSize>(dim.getByteSize()) * \
static_cast<pointbuffer::PointBufferByteSize>(pointIndex);
} else
{
throw buffer_error("unknown pdal::Schema::m_orientation provided!");
}

#ifdef DEBUG
assert(offset + sizeof(T) <= getBufferByteSize());
Expand Down Expand Up @@ -445,8 +479,29 @@ inline T const& PointBuffer::getField(pdal::Dimension const& dim, boost::uint32
throw buffer_error("This dimension has no identified position in a schema.");
}

pointbuffer::PointBufferByteSize point_start_byte_position = static_cast<pointbuffer::PointBufferByteSize>(pointIndex) * static_cast<pointbuffer::PointBufferByteSize>(m_byteSize);
boost::uint64_t offset = point_start_byte_position + static_cast<pointbuffer::PointBufferByteSize>(dim.getByteOffset());
// pointbuffer::PointBufferByteSize point_start_byte_position = static_cast<pointbuffer::PointBufferByteSize>(pointIndex) * static_cast<pointbuffer::PointBufferByteSize>(m_byteSize);
// boost::uint64_t offset = point_start_byte_position + static_cast<pointbuffer::PointBufferByteSize>(dim.getByteOffset());

pointbuffer::PointBufferByteSize point_start_byte_position(0);
pointbuffer::PointBufferByteSize offset(0);

if (m_orientation == schema::POINT_INTERLEAVED)
{
point_start_byte_position = static_cast<pointbuffer::PointBufferByteSize>(pointIndex) * \
static_cast<pointbuffer::PointBufferByteSize>(m_byteSize);
offset = point_start_byte_position + \
static_cast<pointbuffer::PointBufferByteSize>(dim.getByteOffset());
} else if (m_orientation == schema::DIMENSION_INTERLEAVED)
{
point_start_byte_position = static_cast<pointbuffer::PointBufferByteSize>(m_capacity) * \
static_cast<pointbuffer::PointBufferByteSize>(dim.getByteOffset());
offset = point_start_byte_position + \
static_cast<pointbuffer::PointBufferByteSize>(dim.getByteSize()) * \
static_cast<pointbuffer::PointBufferByteSize>(pointIndex);
} else
{
throw buffer_error("unknown pdal::Schema::m_orientation provided!");
}

#ifdef DEBUG
// This test ends up being somewhat expensive when run for every field
Expand Down
22 changes: 21 additions & 1 deletion include/pdal/Schema.hpp
Expand Up @@ -101,6 +101,13 @@ typedef boost::uint32_t size_type;

typedef std::map<Dimension const*, Dimension const*> DimensionMap;

enum Orientation
{
POINT_INTERLEAVED = 1,
DIMENSION_INTERLEAVED = 2,
UNKNOWN_INTERLEAVED = 256
};

}

/// A pdal::Schema is a composition of pdal::Dimension instances that form
Expand Down Expand Up @@ -216,6 +223,19 @@ class PDAL_DLL Schema
return m_index.get<schema::name>().size();
}

inline schema::Orientation getOrientation() const
{
return m_orientation;
}

inline void setOrientation(schema::Orientation v)
{
m_orientation = v;
}

/// @return a new schema with all ignored fields removed.
Schema pack() const;

/// @name Summary and serialization
/// @return a boost::property_tree representing the Schema
/*!
Expand Down Expand Up @@ -256,8 +276,8 @@ class PDAL_DLL Schema
private:

schema::size_type m_byteSize;

schema::Map m_index;
schema::Orientation m_orientation;

};

Expand Down
3 changes: 2 additions & 1 deletion schemas/8-dimension-schema.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<pc:PointCloudSchema xmlns:pc="http://pointcloud.org/schemas/PC/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<pc:PointCloudSchema xmlns:pc="http://pointcloud.org/schemas/PC/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<pc:dimension>
<pc:position>1</pc:position>
<pc:size>4</pc:size>
Expand Down Expand Up @@ -249,4 +249,5 @@
<Metadata name="a_binary" type="base64Binary">true</Metadata>AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiYw==</Metadata>
</Reader>
</pc:metadata>
<pc:orientation>point</pc:orientation>
</pc:PointCloudSchema>
18 changes: 16 additions & 2 deletions schemas/LAS.xsd
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns:pc="http://pointcloud.org/schemas/PC/1.1" xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://pointcloud.org/schemas/PC/1.1" version="1.1">
<xs:schema xmlns:pc="http://pointcloud.org/schemas/PC/" xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://pointcloud.org/schemas/PC/" version="1.2">

<xs:simpleType name="interpretationType">
<xs:annotation>
Expand Down Expand Up @@ -51,7 +51,7 @@
<xs:annotation>
<xs:documentation>
The dimension's position in the block of point data
(counting from 0)
(counting from 1)
</xs:documentation>
</xs:annotation>
</xs:element>
Expand Down Expand Up @@ -153,12 +153,26 @@

</xs:all>
</xs:complexType>

<xs:simpleType name="orientationType">
<xs:annotation>
<xs:documentation>
Used to describe the storage orientation of the word. The orientation of a dimension might be 'point' oriented or 'dimension' oriented. A 'point' oriented dimension, the default orientation, has its dimensions composed as XYZXYZXYZ. A 'dimension' oriented one has data composed as XXXYYYZZZ.
</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
<xs:enumeration value="point"/>
<xs:enumeration value="dimension"/>
<xs:enumeration value="unknown"/>
</xs:restriction>
</xs:simpleType>

<xs:element name="PointCloudSchema">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="1" name="dimension" type="pc:dimensionType"/>
<xs:element name="metadata" minOccurs="0" maxOccurs="1" type="xs:anyType"/>
<xs:element name="orientation" minOccurs="0" maxOccurs="1" type="pc:orientationType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
Expand Down

0 comments on commit eb5b3d6

Please sign in to comment.