Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpMbtPolygon.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * See the file LICENSE.txt at the root directory of this source
10 * distribution for additional information about the GNU GPL.
11 *
12 * For using ViSP with software that can not be combined with the GNU
13 * GPL, please contact Inria about acquiring a ViSP Professional
14 * Edition License.
15 *
16 * See https://visp.inria.fr for more information.
17 *
18 * This software was developed at:
19 * Inria Rennes - Bretagne Atlantique
20 * Campus Universitaire de Beaulieu
21 * 35042 Rennes Cedex
22 * France
23 *
24 * If you have questions regarding the use of this file, please contact
25 * Inria at visp@inria.fr
26 *
27 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29 *
30 * Description:
31 * Make the complete tracking of an object by using its CAD model
32 *
33 * Authors:
34 * Romain Tallonneau
35 * Aurelien Yol
36 */
37
38#include <limits.h>
39
40#include <visp3/core/vpConfig.h>
45
46#include <visp3/core/vpPolygon.h>
47#include <visp3/mbt/vpMbtPolygon.h>
48
54 : index(-1), isvisible(false), isappearing(false), useLod(false), minLineLengthThresh(50.0),
55 minPolygonAreaThresh(2500.0), name(""), hasOrientation(true)
56{ }
57
59 : vpPolygon3D(mbtp), index(mbtp.index), isvisible(mbtp.isvisible), isappearing(mbtp.isappearing), useLod(mbtp.useLod),
62{
63 //*this = mbtp; // Should not be called by copy constructor to avoid multiple assignments.
64}
65
80
98bool vpMbtPolygon::isVisible(const vpHomogeneousMatrix &cMo, double alpha, const bool &modulo,
99 const vpCameraParameters &cam, unsigned int width, unsigned int height)
100{
101 // std::cout << "Computing angle from MBT Face (cMo, alpha)" << std::endl;
102
103 changeFrame(cMo);
104
105 if (nbpt <= 2) {
106 // Level of detail (LOD)
107 if (useLod) {
108 vpCameraParameters c = cam;
109 if (clippingFlag > 3) { // Contains at least one FOV constraint
110 c.computeFov(width, height);
111 }
113 std::vector<vpImagePoint> roiImagePoints;
114 getRoiClipped(c, roiImagePoints);
115
116 if (roiImagePoints.size() == 2) {
117 double x1 = roiImagePoints[0].get_u();
118 double y1 = roiImagePoints[0].get_v();
119 double x2 = roiImagePoints[1].get_u();
120 double y2 = roiImagePoints[1].get_v();
121 double length = std::sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
122 // std::cout << "Index=" << index << " ; Line length=" <<
123 // length << " ; clippingFlag=" << clippingFlag << std::endl;
124 // vpTRACE("index=%d length=%f minLineLengthThresh=%f", index,
125 // length, minLineLengthThresh);
126
127 if (length < minLineLengthThresh) {
128 isvisible = false;
129 isappearing = false;
130 return false;
131 }
132 }
133 }
134
135 /* a line is always visible when LOD is not used */
136 isvisible = true;
137 isappearing = false;
138 return true;
139 }
140
141 // If the polygon has no orientation, the angle check visibility is always
142 // valid. Feature mainly used for cylinders.
143 if (!hasOrientation) {
144 isvisible = true;
145 isappearing = false;
146 return true;
147 }
148
149 // Check visibility from normal
150 // Newell's Method for calculating the normal of an arbitrary 3D polygon
151 // https://www.opengl.org/wiki/Calculating_a_Surface_Normal
152 vpColVector faceNormal(3);
153 vpColVector currentVertex, nextVertex;
154 for (unsigned int i = 0; i < nbpt; i++) {
155 currentVertex = p[i].cP;
156 nextVertex = p[(i + 1) % nbpt].cP;
157
158 faceNormal[0] += (currentVertex[1] - nextVertex[1]) * (currentVertex[2] + nextVertex[2]);
159 faceNormal[1] += (currentVertex[2] - nextVertex[2]) * (currentVertex[0] + nextVertex[0]);
160 faceNormal[2] += (currentVertex[0] - nextVertex[0]) * (currentVertex[1] + nextVertex[1]);
161 }
162 faceNormal.normalize();
163
164 vpColVector e4(3);
165 vpPoint pt;
166 for (unsigned int i = 0; i < nbpt; i += 1) {
167 pt.set_X(pt.get_X() + p[i].get_X());
168 pt.set_Y(pt.get_Y() + p[i].get_Y());
169 pt.set_Z(pt.get_Z() + p[i].get_Z());
170 }
171 e4[0] = -pt.get_X() / static_cast<double>(nbpt);
172 e4[1] = -pt.get_Y() / static_cast<double>(nbpt);
173 e4[2] = -pt.get_Z() / static_cast<double>(nbpt);
174 e4.normalize();
175
176 double angle = acos(vpColVector::dotProd(e4, faceNormal));
177
178 // vpCTRACE << angle << "/" << vpMath::deg(angle) << "/" <<
179 // vpMath::deg(alpha) << std::endl;
180
181 if (angle < alpha || (modulo && (M_PI - angle) < alpha)) {
182 isvisible = true;
183 isappearing = false;
184
185 if (useLod) {
186 vpCameraParameters c = cam;
187 if (clippingFlag > 3) { // Contains at least one FOV constraint
188 c.computeFov(width, height);
189 }
191 std::vector<vpImagePoint> roiImagePoints;
192 getRoiClipped(c, roiImagePoints);
193
194 vpPolygon roiPolygon(roiImagePoints);
195 double area = roiPolygon.getArea();
196 // std::cout << "After normal test ; Index=" << index << " ; area="
197 // << area << " ; clippingFlag="
198 // << clippingFlag << std::endl;
199 if (area < minPolygonAreaThresh) {
200 isappearing = false;
201 isvisible = false;
202 return false;
203 }
204 }
205
206 return true;
207 }
208
209 if (angle < alpha + vpMath::rad(1)) {
210 isappearing = true;
211 }
212 else if (modulo && (M_PI - angle) < alpha + vpMath::rad(1)) {
213 isappearing = true;
214 }
215 else {
216 isappearing = false;
217 }
218
219 isvisible = false;
220 return false;
221}
222
223//###################################
224// Static functions
225//###################################
226
274void vpMbtPolygon::setLod(bool use_lod) { this->useLod = use_lod; }
275END_VISP_NAMESPACE
Generic class defining intrinsic camera parameters.
void computeFov(const unsigned int &w, const unsigned int &h)
Implementation of column vector and the associated operations.
static double dotProd(const vpColVector &a, const vpColVector &b)
vpColVector & normalize()
Implementation of an homogeneous matrix and operations on such kind of matrices.
static double rad(double deg)
Definition vpMath.h:129
bool isvisible
flag to specify whether the face is visible or not
bool hasOrientation
double minLineLengthThresh
void setLod(bool use_lod)
double minPolygonAreaThresh
bool isappearing
flag to specify whether the face is appearing or not
std::string name
Name of the polygon.
bool isVisible() const
vpMbtPolygon & operator=(const vpMbtPolygon &mbtp)
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition vpPoint.h:79
double get_Y() const
Get the point cY coordinate in the camera frame.
Definition vpPoint.cpp:411
void set_X(double cX)
Set the point cX coordinate in the camera frame.
Definition vpPoint.cpp:453
void set_Y(double cY)
Set the point cY coordinate in the camera frame.
Definition vpPoint.cpp:455
double get_Z() const
Get the point cZ coordinate in the camera frame.
Definition vpPoint.cpp:413
void set_Z(double cZ)
Set the point cZ coordinate in the camera frame.
Definition vpPoint.cpp:457
double get_X() const
Get the point cX coordinate in the camera frame.
Definition vpPoint.cpp:409
void changeFrame(const vpHomogeneousMatrix &cMo)
unsigned int nbpt
Number of points used to define the polygon.
Definition vpPolygon3D.h:74
vpPoint * p
corners in the object frame
Definition vpPolygon3D.h:79
void computePolygonClipped(const vpCameraParameters &cam=vpCameraParameters())
unsigned int clippingFlag
Clipping flag.
Definition vpPolygon3D.h:83
void getRoiClipped(const vpCameraParameters &cam, std::vector< vpImagePoint > &roi)
vpPolygon3D & operator=(const vpPolygon3D &mbtp)
Defines a generic 2D polygon.
Definition vpPolygon.h:103
double getArea() const
Definition vpPolygon.h:148