ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
ecvSphere.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #include "ecvSphere.h"
9 
10 // Local
11 #include "ecvDisplayTools.h"
12 #include "ecvPointCloud.h"
13 
15  const ccGLMatrix* transMat /*=0*/,
16  QString name /*=QString("Sphere")*/,
17  unsigned precision /*=DEFAULT_DRAWING_PRECISION*/)
18  : ccGenericPrimitive(name, transMat), m_radius(radius) {
19  setDrawingPrecision(std::max<unsigned>(
20  precision, MIN_DRAWING_PRECISION)); // automatically calls
21  // updateRepresentation
22 }
23 
24 ccSphere::ccSphere(QString name /*=QString("Sphere")*/)
25  : ccGenericPrimitive(name), m_radius(0) {}
26 
30 }
31 
33  if (m_drawPrecision < MIN_DRAWING_PRECISION) return false;
34 
35  const unsigned steps = m_drawPrecision;
36 
37  // vertices
38  ccPointCloud* verts = vertices();
39  assert(verts);
40 
41  // vertices
42  unsigned count = steps * (steps - 1) + 2;
43  // faces
44  unsigned faces = steps * ((steps - 2) * 2 + 2);
45 
46  if (!init(count, true, faces, 0)) {
47  CVLog::Error("[ccSphere::buildUp] Not enough memory");
48  return false;
49  }
50 
51  // 2 first points: poles
52  verts->addPoint(CCVector3(0, 0, m_radius));
53  verts->addNorm(CCVector3(0, 0, 1));
54 
55  verts->addPoint(CCVector3(0, 0, -m_radius));
56  verts->addNorm(CCVector3(0, 0, -1));
57 
58  // then, angular sweep
59  PointCoordinateType angle_rad_step =
60  static_cast<PointCoordinateType>(M_PI) /
61  static_cast<PointCoordinateType>(steps);
62  CCVector3 N0, N, P;
63  {
64  for (unsigned j = 1; j < steps; ++j) {
65  PointCoordinateType theta =
66  static_cast<PointCoordinateType>(j) * angle_rad_step;
67  PointCoordinateType cos_theta = cos(theta);
68  PointCoordinateType sin_theta = sin(theta);
69 
70  N0.x = sin_theta;
71  N0.y = 0;
72  N0.z = cos_theta;
73 
74  for (unsigned i = 0; i < steps; ++i) {
76  static_cast<PointCoordinateType>(2 * i) *
77  angle_rad_step;
78  PointCoordinateType cos_phi = cos(phi);
79  PointCoordinateType sin_phi = sin(phi);
80 
81  N.x = N0.x * cos_phi;
82  N.y = N0.x * sin_phi;
83  N.z = N0.z;
84  N.normalize();
85 
86  P = N * m_radius;
87 
88  verts->addPoint(P);
89  verts->addNorm(N);
90  }
91  }
92  }
93 
94  // faces
95  {
96  assert(m_triVertIndexes);
97 
98  // north pole
99  {
100  for (unsigned i = 0; i < steps; ++i) {
101  unsigned A = 2 + i;
102  unsigned B = (i + 1 < steps ? A + 1 : 2);
103  addTriangle(A, B, 0);
104  }
105  }
106 
107  // slices
108  for (unsigned j = 1; j + 1 < steps; ++j) {
109  unsigned shift = 2 + (j - 1) * steps;
110  for (unsigned i = 0; i < steps; ++i) {
111  unsigned A = shift + i;
112  unsigned B = (i + 1 < steps ? A + 1 : shift);
113  assert(B < count);
114  addTriangle(A, A + steps, B);
115  addTriangle(B + steps, B, A + steps);
116  }
117  }
118 
119  // south pole
120  {
121  unsigned shift = 2 + (steps - 2) * steps;
122  for (unsigned i = 0; i < steps; ++i) {
123  unsigned A = shift + i;
124  unsigned B = (i + 1 < steps ? A + 1 : shift);
125  assert(B < count);
126  addTriangle(A, 1, B);
127  }
128  }
129  }
130 
132  showNormals(true);
133 
134  return true;
135 }
136 
138  if (m_radius == radius) return;
139 
140  assert(radius > 0);
141  m_radius = radius;
142 
143  buildUp();
145 }
146 
147 bool ccSphere::toFile_MeOnly(QFile& out, short dataVersion) const {
148  assert(out.isOpen() && (out.openMode() & QIODevice::WriteOnly));
149  if (dataVersion < 21) {
150  assert(false);
151  return false;
152  }
153 
154  if (!ccGenericPrimitive::toFile_MeOnly(out, dataVersion)) return false;
155 
156  // parameters (dataVersion >= 21)
157  QDataStream outStream(&out);
158  outStream << m_radius;
159 
160  return true;
161 }
162 
164  return std::max(static_cast<short>(21),
166 }
167 
169  short dataVersion,
170  int flags,
171  LoadedIDMap& oldToNewIDMap) {
172  if (!ccGenericPrimitive::fromFile_MeOnly(in, dataVersion, flags,
173  oldToNewIDMap))
174  return false;
175 
176  // parameters (dataVersion >= 21)
177  QDataStream inStream(&in);
179 
180  return true;
181 }
182 
184  // we display it in the 2D layer in fact!
185  ccBBox bBox = getOwnBB();
186  if (!bBox.isValid()) return;
187 
188  ccGLMatrix trans;
190 
191  ccGLCameraParameters camera;
193 
194  CCVector3 C = bBox.getCenter();
195  CCVector3d Q2D;
196  trans.apply(C);
197  camera.project(C, Q2D);
198 
199  // we want to display this name next to the sphere, and not above it!
200  const ecvViewportParameters& params =
202  int dPix =
203  static_cast<int>(ceil(params.zoom * m_radius / params.pixelSize));
204 
205  int bkgBorder =
206  QFontMetrics(ecvDisplayTools::GetTextDisplayFont()).height() / 4 +
207  4;
208  QFont font = ecvDisplayTools::GetTextDisplayFont(); // takes rendering zoom
209  // into account!
211  getName(), static_cast<int>(Q2D.x) + dPix + bkgBorder,
212  static_cast<int>(Q2D.y),
214  0.75f, nullptr, &font);
215 }
constexpr double M_PI
Pi.
Definition: CVConst.h:19
Vector3Tpl< PointCoordinateType > CCVector3
Default 3D Vector.
Definition: CVGeom.h:798
float PointCoordinateType
Type of the coordinates of a (N-D) point.
Definition: CVTypes.h:16
std::string name
int count
static bool Error(const char *format,...)
Display an error dialog with formatted message.
Definition: CVLog.cpp:143
Type y
Definition: CVGeom.h:137
Type x
Definition: CVGeom.h:137
Type z
Definition: CVGeom.h:137
void normalize()
Sets vector norm to unity.
Definition: CVGeom.h:428
Bounding box structure.
Definition: ecvBBox.h:25
void apply(float vec[3]) const
Applies transformation to a 3D vector (in place) - float version.
Float version of ccGLMatrixTpl.
Definition: ecvGLMatrix.h:19
void showNormals(bool state) override
Sets normals visibility.
Generic primitive interface.
void applyTransformationToVertices()
Applies associated transformation to vertices.
bool init(unsigned vertCount, bool vertNormals, unsigned faceCount, unsigned faceNormCount)
Inits internal structures.
virtual bool setDrawingPrecision(unsigned steps)
Sets drawing precision.
ccGenericPrimitive * finishCloneJob(ccGenericPrimitive *primitive) const
Finished 'clone' job (vertices color, etc.)
ccPointCloud * vertices()
Returns vertices.
unsigned m_drawPrecision
Drawing precision (for primitives that support this feature)
static const int MIN_DRAWING_PRECISION
Minimum drawing precision.
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.
ccGLMatrix m_transformation
Associated transformation (applied to vertices)
short minimumFileVersion_MeOnly() const override
virtual void notifyGeometryUpdate()
Definition: ecvHObject.cpp:104
bool getAbsoluteGLTransformation(ccGLMatrix &trans) const
Definition: ecvHObject.cpp:740
void addTriangle(unsigned i1, unsigned i2, unsigned i3)
Adds a triangle to the mesh.
Definition: ecvMesh.cpp:2428
ccBBox getOwnBB(bool withGLFeatures=false) override
Returns the entity's own bounding-box.
Definition: ecvMesh.cpp:2413
triangleIndexesContainer * m_triVertIndexes
Triangles' vertices indexes (3 per triangle)
Definition: ecvMesh.h:1502
virtual QString getName() const
Returns object name.
Definition: ecvObject.h:72
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
void addNorm(const CCVector3 &N)
Pushes a normal vector on stack (shortcut)
QMultiMap< unsigned, unsigned > LoadedIDMap
Map of loaded unique IDs (old ID --> new ID)
static void CoordsFromDataStream(QDataStream &stream, int flags, PointCoordinateType *out, unsigned count=1)
virtual ccGenericPrimitive * clone() const override
Clones primitive.
Definition: ecvSphere.cpp:27
virtual void drawNameIn3D() override
Draws the entity name in 3D.
Definition: ecvSphere.cpp:183
bool toFile_MeOnly(QFile &out, short dataVersion) const override
Save own object data.
Definition: ecvSphere.cpp:147
ccSphere(PointCoordinateType radius, const ccGLMatrix *transMat=0, QString name=QString("Sphere"), unsigned precision=24)
Default constructor.
Definition: ecvSphere.cpp:14
void setRadius(PointCoordinateType radius)
Sets radius.
Definition: ecvSphere.cpp:137
virtual bool buildUp() override
Builds primitive.
Definition: ecvSphere.cpp:32
short minimumFileVersion_MeOnly() const override
Definition: ecvSphere.cpp:163
bool fromFile_MeOnly(QFile &in, short dataVersion, int flags, LoadedIDMap &oldToNewIDMap) override
Loads own object data.
Definition: ecvSphere.cpp:168
PointCoordinateType m_radius
Radius.
Definition: ecvSphere.h:66
Vector3Tpl< T > getCenter() const
Returns center.
Definition: BoundingBox.h:164
bool isValid() const
Returns whether bounding box is valid or not.
Definition: BoundingBox.h:203
void addPoint(const CCVector3 &P)
Adds a 3D point to the database.
static QFont GetTextDisplayFont()
static void GetGLCameraParameters(ccGLCameraParameters &params)
Returns the current OpenGL camera parameters.
static void DisplayText(const QString &text, int x, int y, unsigned char align=ALIGN_DEFAULT, float bkgAlpha=0.0f, const unsigned char *rgbColor=nullptr, const QFont *font=nullptr, const QString &id="")
Displays a string at a given 2D position.
static const ecvViewportParameters & GetViewportParameters()
Standard parameters for GL displays/viewports.
float pixelSize
Current pixel size (in 'current unit'/pixel)
MiniVec< float, N > ceil(const MiniVec< float, N > &a)
Definition: MiniVec.h:89
OpenGL camera parameters.
bool project(const CCVector3d &input3D, CCVector3d &output2D, bool *inFrustum=nullptr) const
Projects a 3D point in 2D (+ normalized 'z' coordinate)