30 void CGeneralizedCylinder::TQuadrilateral::calculateNormal()
38 normal[0] = az *
by - ay *
bz;
39 normal[1] = ax *
bz - az * bx;
40 normal[2] = ay * bx - ax *
by;
42 for (
size_t i = 0; i < 3; i++)
s += normal[i] * normal[i];
44 for (
size_t i = 0; i < 3; i++) normal[i] /=
s;
47 #if MRPT_HAS_OPENGL_GLUT
48 class FQuadrilateralRenderer
57 for (
int i = 0; i < 4; i++)
61 ~FQuadrilateralRenderer() {}
65 void CGeneralizedCylinder::getMeshIterators(
66 const vector<TQuadrilateral>& m,
78 m.size() / getNumberOfSections();
79 begin = m.begin() + qps * firstSection;
80 end = m.begin() + qps * lastSection;
84 void CGeneralizedCylinder::render_dl()
const
86 #if MRPT_HAS_OPENGL_GLUT
87 if (!meshUpToDate) updateMesh();
93 glColor4ub(m_color.R, m_color.G, m_color.B, m_color.A);
96 for_each(
begin,
end, FQuadrilateralRenderer(m_color));
105 vector<CGeneralizedCylinder::TQuadrilateral>& mesh)
108 for (
size_t i = 0; i <
R; i++)
109 for (
size_t j = 0; j < C; j++)
112 pointsMesh(i, j), pointsMesh(i, j + 1),
113 pointsMesh(i + 1, j + 1), pointsMesh(i + 1, j)));
130 if (!meshUpToDate || !polysUpToDate) updatePolys();
134 void CGeneralizedCylinder::updateMesh()
const
136 CRenderizableDisplayList::notifyChange();
138 size_t A = axis.size();
139 vector<TPoint3D> genX = generatrix;
140 if (closed && genX.size() > 2) genX.push_back(genX[0]);
141 size_t G = genX.size();
146 for (
size_t i = 0; i < A; i++)
147 for (
size_t j = 0; j <
G; j++)
148 axis[i].composePoint(genX[j], pointsMesh.get_unsafe(i, j));
152 polysUpToDate =
false;
155 uint8_t CGeneralizedCylinder::serializeGetVersion()
const {
return 1; }
158 writeToStreamRender(out);
159 out << axis << generatrix;
163 void CGeneralizedCylinder::serializeFrom(
170 readFromStreamRender(
in);
172 in >>
a >> generatrix;
173 generatePoses(
a, axis);
174 meshUpToDate =
false;
175 polysUpToDate =
false;
179 readFromStreamRender(
in);
181 in >> axis >> generatrix;
182 meshUpToDate =
false;
183 polysUpToDate =
false;
188 CRenderizableDisplayList::notifyChange();
196 for (
size_t i = 0; i < profile.size(); i++)
198 profile[i].x, profile[i].y, profile[i].z,
p[i].x,
p[i].y,
p[i].z);
199 vector<math::TPolygon3D> convexPolys;
201 convexPolys.push_back(
p);
202 poly = mrpt::make_aligned_shared<CPolyhedron>(convexPolys);
207 if (!meshUpToDate) updateMesh();
208 if (axis.size() < 2 || generatrix.size() < 3)
209 throw std::logic_error(
"Not enough points.");
210 size_t i = fullyVisible ? 0 : firstSection;
212 poly->setPose(this->m_pose);
213 poly->setColor(getColor());
218 if (!meshUpToDate) updateMesh();
219 if (axis.size() < 2 || generatrix.size() < 3)
220 throw std::logic_error(
"Not enough points.");
221 size_t i = (fullyVisible ? axis.size() : lastSection) - 1;
223 poly->setPose(this->m_pose);
224 poly->setColor(getColor());
227 void CGeneralizedCylinder::generateSetOfPolygons(
228 std::vector<TPolygon3D>&
res)
const
230 if (!meshUpToDate || !polysUpToDate) updatePolys();
231 size_t N = polys.size();
233 for (
size_t i = 0; i < N; i++)
res[i] = polys[i].poly;
236 void CGeneralizedCylinder::getClosedSection(
239 if (index1 > index2) swap(index1, index2);
240 if (index2 >= axis.size() - 1)
throw std::logic_error(
"Out of range");
242 if (!meshUpToDate) updateMesh();
243 pointsMesh.extractRows(index1, index2 + 1, ROIpoints);
249 vector<TPoint3D> vec;
253 vector<TPoint3D> vertices;
255 size_t nr = ROIpoints.
rows() - 1;
256 size_t nc = ROIpoints.
cols() - 1;
257 vector<vector<uint32_t>> faces;
258 faces.reserve(nr * nc + 2);
259 vector<uint32_t> tmp(4);
260 for (
size_t i = 0; i < nr; i++)
261 for (
size_t j = 0; j < nc; j++)
263 size_t base = (nc + 1) * i + j;
266 tmp[2] = base + nc + 2;
267 tmp[3] = base + nc + 1;
268 faces.push_back(tmp);
271 for (
size_t i = 0; i < nr + 1; i++) tmp[i] = i * (nc + 1);
272 faces.push_back(tmp);
273 for (
size_t i = 0; i < nr + 1; i++) tmp[i] = i * (nc + 2) - 1;
274 poly = mrpt::make_aligned_shared<CPolyhedron>(vertices, faces);
277 void CGeneralizedCylinder::removeVisibleSectionAtStart()
279 CRenderizableDisplayList::notifyChange();
282 if (!getNumberOfSections())
throw std::logic_error(
"No more sections");
283 fullyVisible =
false;
285 lastSection = getNumberOfSections();
287 else if (firstSection >= lastSection)
288 throw std::logic_error(
"No more sections");
292 void CGeneralizedCylinder::removeVisibleSectionAtEnd()
294 CRenderizableDisplayList::notifyChange();
297 if (!getNumberOfSections())
throw std::logic_error(
"No more sections");
298 fullyVisible =
false;
300 lastSection = getNumberOfSections() - 1;
302 else if (firstSection >= lastSection)
303 throw std::logic_error(
"No more sections");
308 void CGeneralizedCylinder::updatePolys()
const
310 CRenderizableDisplayList::notifyChange();
312 if (!meshUpToDate) updateMesh();
313 size_t N = mesh.size();
316 for (
size_t i = 0; i < N; i++)
318 for (
size_t j = 0; j < 4; j++) tmp[j] = mesh[i].
points[j];
321 polysUpToDate =
true;
324 void CGeneralizedCylinder::generatePoses(
325 const vector<TPoint3D>& pIn,
328 size_t N = pIn.size();
338 if ((it2 = it1 + 1) == pIn.end())
342 yaws.push_back(atan2(it2->y - it1->y, it2->x - it1->x));
345 yaws.push_back(*yaws.rbegin());
347 for (
size_t i = 0; i < N; i++)
350 pOut[i] =
CPose3D(
p.x,
p.y,
p.z, yaws[i], 0, 0);
354 bool CGeneralizedCylinder::getFirstSectionPose(
CPose3D&
p)
356 if (axis.size() <= 0)
return false;
361 bool CGeneralizedCylinder::getLastSectionPose(
CPose3D&
p)
363 if (axis.size() <= 0)
return false;
368 bool CGeneralizedCylinder::getFirstVisibleSectionPose(
CPose3D&
p)
370 if (fullyVisible)
return getFirstSectionPose(
p);
371 if (getVisibleSections() <= 0)
return false;
372 p = axis[firstSection];
376 bool CGeneralizedCylinder::getLastVisibleSectionPose(
CPose3D&
p)
378 if (fullyVisible)
return getLastSectionPose(
p);
379 if (getVisibleSections() <= 0)
return false;
380 p = axis[lastSection];
384 void CGeneralizedCylinder::getBoundingBox(
391 m_pose.composePoint(bb_min, bb_min);
392 m_pose.composePoint(bb_max, bb_max);