37 : Polyline(associatedCloud.cloneThis(nullptr)),
52 if (this->
reserve(verticesCount)) {
99 "[ccPolyline::initWith] Not enough memory to duplicate "
181 unsigned vertCount =
size();
182 if (vertCount < 2)
return;
233 cos(s_defaultArrowAngle);
235 sin(s_defaultArrowAngle);
236 CCVector3 A(cost * u.
x - sint * u.
y, sint * u.
x + cost * u.
y,
238 CCVector3 B(cost * u.
x + sint * u.
y, -sint * u.
x + cost * u.
y,
248 QSharedPointer<ccCone>(
new ccCone(0.5, 0.0, 1.0));
285 assert(out.isOpen() && (out.openMode() & QIODevice::WriteOnly));
286 if (dataVersion < 31) {
300 "[ccPolyline::toFile_MeOnly] Polyline vertices is not a "
301 "ccPointCloud structure?!");
304 uint32_t vertUniqueID =
306 if (out.write((
const char*)&vertUniqueID, 4) < 0)
return WriteError();
309 uint32_t pointCount =
size();
310 if (out.write((
const char*)&pointCount, 4) < 0)
return WriteError();
313 for (uint32_t i = 0; i < pointCount; ++i) {
315 if (out.write((
const char*)&pointIndex, 4) < 0)
return WriteError();
321 QDataStream outStream(&out);
344 short minVersion = (
isShifted() ? 39 : 31);
355 if (dataVersion < 28)
return false;
362 uint32_t vertUniqueID = 0;
363 if (in.read((
char*)&vertUniqueID, 4) < 0)
return ReadError();
369 uint32_t pointCount = 0;
370 if (in.read((
char*)&pointCount, 4) < 0)
return ReadError();
371 if (!
reserve(pointCount))
return false;
374 for (uint32_t i = 0; i < pointCount; ++i) {
375 uint32_t pointIndex = 0;
376 if (in.read((
char*)&pointIndex, 4) < 0)
return ReadError();
383 if (dataVersion >= 39) {
389 QDataStream inStream(&in);
407 if (dataVersion >= 31) {
416 std::vector<ccPolyline*>& parts) {
420 unsigned vertCount =
size();
421 if (vertCount <= 2) {
426 unsigned startIndex = 0;
427 unsigned lastIndex = vertCount - 1;
428 while (startIndex <= lastIndex) {
429 unsigned stopIndex = startIndex;
430 while (stopIndex < lastIndex &&
437 unsigned partSize = stopIndex - startIndex + 1;
441 if (startIndex == 0) {
443 unsigned realStartIndex = vertCount;
444 while (realStartIndex > stopIndex &&
446 *
getPoint(realStartIndex % vertCount))
447 .norm() <= maxEdgeLength) {
451 if (realStartIndex == stopIndex) {
455 }
else if (realStartIndex < vertCount) {
456 partSize += (vertCount - realStartIndex);
457 assert(realStartIndex != 0);
458 lastIndex = realStartIndex - 1;
460 startIndex = realStartIndex;
461 stopIndex += vertCount;
463 }
else if (partSize == vertCount) {
479 for (
unsigned i = startIndex; i <= stopIndex; ++i) {
490 parts.push_back(part);
494 startIndex = (stopIndex % vertCount) + 1;
514 "[ccPolyline::add] invalid associated cloud!");
517 unsigned int newCount = cloud.
size();
518 unsigned int currentSize = oldCloud->
size();
519 if (!oldCloud->
reserve(currentSize + newCount)) {
525 for (
unsigned i = 0; i < newCount; ++i) {
536 unsigned vertCount =
size();
538 unsigned lastVert =
isClosed() ? vertCount : vertCount - 1;
539 for (
unsigned i = 0; i < lastVert; ++i) {
545 length += (B - A).norm();
589 double samplingParameter,
591 if (samplingParameter <= 0 ||
size() < 2) {
599 unsigned pointCount = 0;
601 pointCount =
static_cast<unsigned>(
ceil(L * samplingParameter));
603 pointCount =
static_cast<unsigned>(samplingParameter);
606 if (pointCount == 0) {
614 if (!cloud->
reserve(pointCount)) {
620 double samplingStep = L / pointCount;
625 for (
unsigned i = 0; i < pointCount;) {
626 unsigned indexB = ((indexA + 1) %
size());
630 double lAB = AB.
normd();
632 double relativePos = s - sA;
633 if (relativePos >= lAB) {
635 if (i + 1 == pointCount) {
648 double alpha = relativePos / lAB;
649 alpha = std::max(alpha, 0.0);
650 alpha = std::min(alpha, 1.0);
691 std::vector<CCVector3>
points;
703 std::vector<CCVector3>
points;
743 cloud->
Scale(s, center);
749 const Eigen::Vector3d& center) {
762 if (polyline.
IsEmpty())
return (*
this);
765 "[ccPolyline] Cannot find associated cloud in polyline!");
777 if (!cloud || !
add(*cloud)) {
779 "[ccPolyline] adding ccPolyline failed!");
787 if (
this == &polyline) {
803 unsigned iterationCount)
const {
804 if (iterationCount == 0) {
807 "[ccPolyline::smoothChaikin] Invalid input (iteration count)");
811 if (ratio < 0.05f || ratio > 0.45f) {
818 CVLog::Warning(
"[ccPolyline::smoothChaikin] not enough segments");
828 for (
unsigned it = 0; it < iterationCount; ++it) {
830 unsigned vertCount = currentIterationVertices->
size();
831 unsigned segmentCount = (openPoly ? vertCount - 1 : vertCount);
836 delete newStateVertices;
837 newStateVertices =
nullptr;
838 delete currentIterationVertices;
839 currentIterationVertices =
nullptr;
850 unsigned iQ = ((iP + 1) % vertCount);
855 if (!openPoly || i != 0) {
869 currentIterationVertices->
size() - 1));
872 if (currentIterationVertices !=
this) {
873 delete currentIterationVertices;
874 currentIterationVertices =
nullptr;
876 currentIterationVertices = newStateVertices;
879 if (it + 1 == iterationCount) {
880 smoothPoly =
new ccPolyline(newStateVertices);
881 smoothPoly->
addChild(newStateVertices);
883 if (!smoothPoly->
reserve(newStateVertices->
size())) {
893 QString(
".smoothed (ratio=%1)").arg(ratio));
935 std::vector<ccPolyline*>& output) {
940 unsigned vertCount =
size();
945 if (!verticesCloud) {
948 "[ccPolyline::createNewPolylinesFromSelection] Unsupported "
954 if (verticesVisibility.size() < verticesCloud->
size()) {
957 "[ccPolyline::createNewPolylinesFromSelection] No visibility "
958 "table instantiated");
967 unsigned maxIndex = (
m_isClosed ? vertCount : vertCount - 1);
968 for (
unsigned i = 0; i < maxIndex; ++i) {
969 unsigned nextIndex = ((i + 1) % vertCount);
976 verticesVisibility.at(nextPointIndex) ==
985 static const unsigned DefaultPolySizeIncrement = 64;
991 if (!chunkPoly->
reserve(DefaultPolySizeIncrement) ||
992 !chunkCloud->
reserve(DefaultPolySizeIncrement)) {
999 }
else if (chunkPoly->
size() == chunkPoly->
capacity()) {
1001 DefaultPolySizeIncrement) ||
1003 DefaultPolySizeIncrement)) {
1014 if (!kept || i + 1 == maxIndex) {
1019 QString(
".segmented (part %1)")
1020 .arg(output.size() + 1));
1024 output.push_back(chunkPoly);
1025 }
catch (
const std::bad_alloc&) {
1029 chunkPoly =
nullptr;
1037 "[ccPolyline::createNewPolylinesFromSelection] Not enough "
1051 unsigned resolution ) {
1052 if (resolution < 4) {
1059 if (!vertices->
reserve(resolution) || !circle->
reserve(resolution)) {
1065 double angleStep_rad = 2 *
M_PI / resolution;
1066 for (
unsigned i = 0; i < resolution; ++i) {
1068 sin(i * angleStep_rad) * radius, 0);
constexpr unsigned char POINT_VISIBLE
constexpr PointCoordinateType PC_ONE
'1' as a PointCoordinateType value
Vector3Tpl< double > CCVector3d
Double 3D Vector.
Vector3Tpl< PointCoordinateType > CCVector3
Default 3D Vector.
float PointCoordinateType
Type of the coordinates of a (N-D) point.
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
static bool Error(const char *format,...)
Display an error dialog with formatted message.
void normalize()
Sets vector norm to unity.
double normd() const
Returns vector norm (forces double precision output)
static Vector3Tpl fromArray(const int a[3])
Constructor from an int array.
static ccBBox CreateFromPoints(const std::vector< CCVector3 > &points)
virtual bool colorsShown() const
Returns whether colors are shown or not.
virtual bool isVisible() const
Returns whether entity is visible or not.
virtual bool isVisibilityLocked() const
Returns whether visibility is locked or not.
virtual void lockVisibility(bool state)
Locks/unlocks visibility.
virtual void setVisible(bool state)
Sets entity visibility.
virtual bool isColorOverridden() const
virtual void showColors(bool state)
Sets colors visibility.
virtual const ecvColor::Rgb & getTempColor() const
Returns current temporary (unique) color.
static ccGLMatrixTpl< double > FromToRotation(const Vector3Tpl< double > &from, const Vector3Tpl< double > &to)
Creates a transformation matrix that rotates a vector to another.
ccGLMatrixTpl< T > inverse() const
Returns inverse transformation.
Float version of ccGLMatrixTpl.
Double version of ccGLMatrixTpl.
A 3D cloud interface with associated features (color, normals, octree, etc.)
virtual VisibilityTableType & getTheVisibilityArray()
Returns associated visibility array.
std::vector< unsigned char > VisibilityTableType
Array of "visibility" information for each point.
Hierarchical CLOUDVIEWER Object.
virtual const ccGLMatrix & getGLTransformationHistory() const
Returns the transformation 'history' matrix.
void draw(CC_DRAW_CONTEXT &context) override
Draws entity and its children.
virtual short minimumFileVersion_MeOnly() const
virtual bool fromFile_MeOnly(QFile &in, short dataVersion, int flags, LoadedIDMap &oldToNewIDMap)
Loads own object data.
virtual bool toFile_MeOnly(QFile &out, short dataVersion) const
Save own object data.
unsigned getChildrenNumber() const
Returns the number of children.
virtual void setGLTransformationHistory(const ccGLMatrix &mat)
Sets the transformation 'history' matrix (handle with care!)
virtual void applyGLTransformation(const ccGLMatrix &trans)
Applies a GL transformation to the entity.
ccHObject * getParent() const
Returns parent object.
ccHObject * m_parent
Parent.
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
ccHObject * getChild(unsigned childPos) const
Returns the ith child.
const QVariantMap & metaData() const
Returns meta-data map (const only)
virtual QString getName() const
Returns object name.
virtual unsigned getUniqueID() const
Returns object unique ID.
void setMetaData(const QString &key, const QVariant &data)
Sets a meta-data element.
bool isA(CV_CLASS_ENUM type) const
virtual void setName(const QString &name)
Sets object name.
virtual void setEnabled(bool state)
Sets the "enabled" property.
bool isKindOf(CV_CLASS_ENUM type) const
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
ccPointCloud * partialClone(const cloudViewer::ReferenceCloud *selection, int *warnings=nullptr, bool withChildEntities=true) const
Creates a new point cloud object from a ReferenceCloud (selection)
virtual bool IsEmpty() const override
virtual ccPointCloud & Rotate(const Eigen::Matrix3d &R, const Eigen::Vector3d ¢er) override
Apply rotation to the geometry coordinates and normals. Given a rotation matrix , and center ,...
bool reserve(unsigned numberOfPoints) override
Reserves memory for all the active features.
virtual ccPointCloud & Translate(const Eigen::Vector3d &translation, bool relative=true) override
Apply translation to the geometry coordinates.
static ccPointCloud * From(const cloudViewer::GenericIndexedCloud *cloud, const ccGenericPointCloud *sourceCloud=nullptr)
Creates a new point cloud object from a GenericIndexedCloud.
virtual ccPointCloud & Scale(const double s, const Eigen::Vector3d ¢er) override
Apply scaling to the geometry coordinates. Given a scaling factor , and center , a given point is tr...
void shrinkToFit()
Removes unused capacity.
bool setRGBColor(ColorCompType r, ColorCompType g, ColorCompType b)
Set a unique color for the whole cloud (shortcut)
virtual ccPointCloud & Transform(const Eigen::Matrix4d &trans) override
Apply transformation (4x4 matrix) to the geometry coordinates.
static ccPolyline * Circle(const CCVector3 ¢er, PointCoordinateType radius, unsigned resolution=48)
Creates a circle as a polyline.
ccPolyline operator+(const ccPolyline &polyline) const
void setTransformFlag(bool state)
Defines if the polyline is considered as processed polyline.
PointCoordinateType computeLength() const
Computes the polyline length.
short minimumFileVersion_MeOnly() const override
virtual ccPolyline & Translate(const Eigen::Vector3d &translation, bool relative=true) override
Apply translation to the geometry coordinates.
void setForeground(bool state)
Defines if the polyline is drawn in background or foreground.
static bool IsCloudVerticesOfPolyline(ccGenericPointCloud *cloud, ccPolyline **polyline=nullptr)
Helper to determine if the input cloud acts as vertices of a polyline.
bool toFile_MeOnly(QFile &out, short dataVersion) const override
Save own object data.
bool fromFile_MeOnly(QFile &in, short dataVersion, int flags, LoadedIDMap &oldToNewIDMap) override
Loads own object data.
bool verticesShown() const
Whether the polyline vertices should be displayed or not.
unsigned m_arrowIndex
Arrow index.
bool createNewPolylinesFromSelection(std::vector< ccPolyline * > &output)
Creates a polyline mesh with the selected vertices only.
void set2DMode(bool state)
Defines if the polyline is considered as 2D or 3D.
virtual void drawMeOnly(CC_DRAW_CONTEXT &context) override
Draws the entity only (not its children)
virtual void setGlobalScale(double scale) override
virtual ccPolyline & Transform(const Eigen::Matrix4d &transformation) override
Apply transformation (4x4 matrix) to the geometry coordinates.
virtual ccPolyline & Rotate(const Eigen::Matrix3d &R, const Eigen::Vector3d ¢er) override
Apply rotation to the geometry coordinates and normals. Given a rotation matrix , and center ,...
virtual ccBBox GetAxisAlignedBoundingBox() const override
Returns an axis-aligned bounding box of the geometry.
virtual bool hasColors() const override
Returns whether colors are enabled or not.
PointCoordinateType m_width
Width of the line.
ccPointCloud * samplePoints(bool densityBased, double samplingParameter, bool withRGB)
Samples points on the polyline.
bool is2DMode() const
Returns whether the polyline is considered as 2D or 3D.
bool m_showArrow
Whether to show an arrow or not.
ecvColor::Rgb m_rgbColor
Unique RGB color.
virtual void setGlobalShift(const CCVector3d &shift) override
Sets shift applied to original coordinates (information storage only)
void showArrow(bool state, unsigned vertIndex, PointCoordinateType length)
Shows an arrow in place of a given vertex.
ccPolyline & operator+=(const ccPolyline &polyline)
virtual ccPolyline & Scale(const double s, const Eigen::Vector3d ¢er) override
Apply scaling to the geometry coordinates. Given a scaling factor , and center , a given point is tr...
virtual ecvOrientedBBox GetOrientedBoundingBox() const override
ccPolyline(GenericIndexedCloudPersist *associatedCloud)
Default constructor.
void setVertexMarkerWidth(int width)
Sets the width of vertex markers.
void importParametersFrom(const ccPolyline &poly)
Copy the parameters from another polyline.
ccPolyline & operator=(const ccPolyline &polyline)
virtual Eigen::Vector3d GetMaxBound() const override
Returns max bounds for geometry coordinates.
virtual void applyGLTransformation(const ccGLMatrix &trans) override
Applies a GL transformation to the entity.
void showVertices(bool state)
Sets whether to display or hide the polyline vertices.
virtual ccBBox getOwnBB(bool withGLFeatures=false) override
Returns the entity's own bounding-box.
bool add(const ccPointCloud &cloud)
Add another reference cloud.
unsigned segmentCount() const
Returns the number of segments.
virtual bool IsEmpty() const override
PointCoordinateType m_arrowLength
Arrow length.
virtual unsigned getUniqueIDForDisplay() const override
Returns object unqiue ID used for display.
int m_vertMarkWidth
Vertex marker width.
bool m_showVertices
Whether vertices should be displayed or not.
bool initWith(ccPointCloud *vertices, const ccPolyline &poly)
virtual Eigen::Vector3d GetMinBound() const override
Returns min bounds for geometry coordinates.
int getVertexMarkerWidth() const
Returns the width of vertex markers.
virtual Eigen::Vector3d GetCenter() const override
Returns the center of the geometry coordinates.
bool m_mode2D
Whether polyline should be considered as 2D (true) or 3D (false)
bool split(PointCoordinateType maxEdgeLength, std::vector< ccPolyline * > &parts)
Splits the polyline into several parts based on a maximum edge length.
void setColor(const ecvColor::Rgb &col)
Sets the polyline color.
ccPolyline * smoothChaikin(PointCoordinateType ratio, unsigned iterationCount) const
Smoothes the polyline (Chaikin algorithm)
void setWidth(PointCoordinateType width)
Sets the width of the line.
QMultiMap< unsigned, unsigned > LoadedIDMap
Map of loaded unique IDs (old ID --> new ID)
static bool ReadError()
Sends a custom error message (read error) and returns 'false'.
static bool WriteError()
Sends a custom error message (write error) and returns 'false'.
static void CoordsFromDataStream(QDataStream &stream, int flags, PointCoordinateType *out, unsigned count=1)
Shifted entity interface.
double m_globalScale
Global scale (typically applied at loading time)
CCVector3d m_globalShift
Global shift (typically applied at loading time)
bool loadShiftInfoFromFile(QFile &in)
Serialization helper (input)
bool isShifted() const
Returns whether the cloud is shifted or not.
virtual void setGlobalShift(double x, double y, double z)
Sets shift applied to original coordinates (information storage only)
virtual const CCVector3d & getGlobalShift() const
Returns the shift applied to original coordinates.
virtual void setGlobalScale(double scale)
virtual double getGlobalScale() const
Returns the scale applied to original coordinates.
bool saveShiftInfoToFile(QFile &out) const
Serialization helper (output)
Vector3Tpl< T > getCenter() const
Returns center.
const Vector3Tpl< T > & maxCorner() const
Returns max corner (const)
void setValidity(bool state)
Sets bonding box validity.
const Vector3Tpl< T > & minCorner() const
Returns min corner (const)
virtual unsigned size() const =0
Returns the number of points.
A generic 3D point cloud with index-based and presistent access to points.
virtual const CCVector3 * getPoint(unsigned index) const =0
Returns the ith point.
void addPoint(const CCVector3 &P)
Adds a 3D point to the database.
unsigned size() const override
const CCVector3 * getPoint(unsigned index) const override
void setClosed(bool state)
Sets whether the polyline is closed or not.
void clear(bool unusedParam=true) override
Clears the cloud.
bool isClosed() const
Returns whether the polyline is closed or not.
bool m_isClosed
Closing state.
A very simple point cloud (no point duplication)
BoundingBox m_bbox
Bounding-box.
virtual bool addPointIndex(unsigned globalIndex)
Point global index insertion mechanism.
void getBoundingBox(CCVector3 &bbMin, CCVector3 &bbMax) override
Returns the cloud bounding box.
virtual GenericIndexedCloudPersist * getAssociatedCloud()
Returns the associated (source) cloud.
unsigned size() const override
Returns the number of points.
void invalidateBoundingBox()
Invalidates the bounding-box.
ReferencesContainer m_theIndexes
Indexes of (some of) the associated cloud points.
virtual unsigned getPointGlobalIndex(unsigned localIndex) const
GenericIndexedCloudPersist * m_theAssociatedCloud
Associated cloud.
virtual bool resize(unsigned n)
Presets the size of the vector used to store point references.
virtual unsigned capacity() const
Returns max capacity.
bool add(const ReferenceCloud &cloud)
Add another reference cloud.
virtual void setAssociatedCloud(GenericIndexedCloudPersist *cloud)
Sets the associated (source) cloud.
virtual bool reserve(unsigned n)
Reserves some memory for hosting the point references.
const CCVector3 * getPoint(unsigned index) const override
Returns the ith point.
static ecvOrientedBBox CreateFromPoints(const std::vector< Eigen::Vector3d > &points)
#define MACRO_Draw3D(context)
#define MACRO_Foreground(context)
static QSharedPointer< ccCone > c_unitArrow(0)
MiniVec< float, N > ceil(const MiniVec< float, N > &a)
float DegreesToRadians(int degrees)
Convert degrees to radians.
bool LessThanEpsilon(float x)
Test a floating point number against our epsilon (a very small number).
constexpr Rgb white(MAX, MAX, MAX)
int drawingFlags
Drawing options (see below)
TransformInfo transformInfo