This file is indexed.

/usr/include/SurgSim/Math/Vector.h is in libopensurgsim-dev 0.7.0-5.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
// This file is a part of the OpenSurgSim project.
// Copyright 2012-2015, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// \file
/// Definitions of small fixed-size vector types.

#ifndef SURGSIM_MATH_VECTOR_H
#define SURGSIM_MATH_VECTOR_H

#include <array>
#include <vector>

#include <Eigen/Core>
#include <Eigen/Geometry>

#include "SurgSim/Framework/Assert.h"

namespace SurgSim
{
namespace Math
{

/// A 2D vector of floats.
/// This type (and any structs that contain it) can be safely allocated via new.
typedef Eigen::Matrix<float,  2, 1>  Vector2f;

/// A 3D vector of floats.
/// This type (and any structs that contain it) can be safely allocated via new.
typedef Eigen::Matrix<float,  3, 1>  Vector3f;

/// A 4D vector of floats.
/// This type (and any structs that contain it) can be safely allocated via new.
typedef Eigen::Matrix<float,  4, 1>  Vector4f;

/// A 6D vector of floats.
/// This type (and any structs that contain it) can be safely allocated via new.
typedef Eigen::Matrix<float,  6, 1>  Vector6f;

/// A 2D vector of doubles.
/// This type (and any structs that contain it) can be safely allocated via new.
typedef Eigen::Matrix<double, 2, 1>  Vector2d;

/// A 3D vector of doubles.
/// This type (and any structs that contain it) can be safely allocated via new.
typedef Eigen::Matrix<double, 3, 1>  Vector3d;

/// A 4D vector of doubles.
/// This type (and any structs that contain it) can be safely allocated via new.
typedef Eigen::Matrix<double, 4, 1>  Vector4d;

/// A 6D matrix of doubles.
/// This type (and any structs that contain it) can be safely allocated via new.
typedef Eigen::Matrix<double, 6, 1> Vector6d;

/// A dynamic size column vector
typedef Eigen::Matrix<double, Eigen::Dynamic, 1> Vector;

/// Helper method to add a sub-vector into a vector, for the sake of clarity
/// \tparam Vector The vector type
/// \tparam SubVector The sub-vector type
/// \param subVector The sub-vector
/// \param blockId The block index in vector
/// \param blockSize The block size
/// \param[out] vector The vector to add the sub-vector into
template <class Vector, class SubVector>
void addSubVector(const SubVector& subVector, size_t blockId, size_t blockSize, Vector* vector)
{
	vector->segment(blockSize * blockId, blockSize) += subVector;
}

/// Helper method to add a sub-vector per block into a vector, for the sake of clarity
/// \tparam Vector The vector type
/// \tparam SubVector The sub-vector type
/// \param subVector The sub-vector (containing all the blocks)
/// \param blockIds Vector of block indices (for accessing vector) corresponding to the blocks in sub-vector
/// \param blockSize The block size
/// \param[out] vector The vector to add the sub-vector blocks into
template <class Vector, class SubVector>
void addSubVector(const SubVector& subVector, const std::vector<size_t> blockIds, size_t blockSize, Vector* vector)
{
	const size_t numBlocks = blockIds.size();

	for (size_t block = 0; block < numBlocks; block++)
	{
		size_t blockId = blockIds[block];

		vector->segment(blockSize * blockId, blockSize) += subVector.segment(blockSize * block, blockSize);
	}
}

/// Helper method to set a sub-vector into a vector, for the sake of clarity
/// \tparam Vector The vector type
/// \tparam SubVector The sub-vector type
/// \param subVector The sub-vector
/// \param blockId The block index in vector
/// \param blockSize The size of the sub-vector
/// \param[out] vector The vector to set the sub-vector into
template <class Vector, class SubVector>
void setSubVector(const SubVector& subVector, size_t blockId, size_t blockSize, Vector* vector)
{
	vector->segment(blockSize * blockId, blockSize) = subVector;
}

/// Helper method to access a sub-vector from a vector, for the sake of clarity
/// \tparam Vector The vector type to get the sub-vector from
/// \param vector The vector to get the sub-vector from
/// \param blockId The block index
/// \param blockSize The block size
/// \return The requested sub-vector
/// \note Disable cpplint warnings for use of non-const reference
/// \note Eigen has a specific type for VectorBlock that we want to return with read/write access
/// \note therefore the Vector from which the VectorBlock is built from must not be const
template <class Vector>
Eigen::VectorBlock<Vector> getSubVector(Vector& vector, size_t blockId, size_t blockSize) // NOLINT
{
	return vector.segment(blockSize * blockId, blockSize);
}

/// Helper method to get a sub-vector per block from a vector, for the sake of clarity
/// \tparam Vector The vector type
/// \tparam SubVector The sub-vector type
/// \param vector The vector (containing the blocks in a sparse manner)
/// \param blockIds Vector of block indices (for accessing vector) corresponding to the blocks in vector
/// \param blockSize The block size
/// \param[out] subVector The sub-vector to store the requested blocks (blockIds) from vector into
template <class Vector, class SubVector>
void getSubVector(const Vector& vector, const std::vector<size_t> blockIds, size_t blockSize, SubVector* subVector)
{
	const size_t numBlocks = blockIds.size();

	for (size_t block = 0; block < numBlocks; block++)
	{
		size_t blockId = blockIds[block];

		subVector->segment(blockSize * block, blockSize) = vector.segment(blockSize * blockId, blockSize);
	}
}

/// Interpolate (slerp) between 2 vectors
/// \tparam T the numeric data type used for arguments and the return value.  Can usually be deduced.
/// \tparam size the size of the vectors.  Can be deduced.
/// \tparam TOpt the option flags (alignment etc.) used for the Vector arguments.  Can be deduced.
/// \param previous The starting vector (at time 0.0).
/// \param next The ending vector (at time 1.0).
/// \param t  The interpolation time requested. Within [0..1], although note bounds are not checked.
/// \returns the transform resulting in the slerp interpolation at time t.
/// \note t=0 => returns vector 'previous'
/// \note t=1 => returns vector 'next'
template <typename T, int size, int TOpt>
Eigen::Matrix<T, size, 1, TOpt> interpolate(
	const Eigen::Matrix<T, size, 1, TOpt>& previous,
	const Eigen::Matrix<T, size, 1, TOpt>& next,
	T t)
{
	return previous + t * (next - previous);
}

/// Helper method to construct an orthonormal basis (i, j, k) given the 1st vector direction
/// \tparam T the numeric data type used for the vector argument. Can usually be deduced.
/// \tparam VOpt the option flags (alignment etc.) used for the vector argument. Can be deduced.
/// \param[in, out] i Should provide the 1st direction on input. The 1st vector of the basis (i, j, k) on output.
/// \param[out] j, k The 2nd and 3rd orthonormal vectors of the basis (i, j, k)
/// \return True if (i, j, k) has been built successfully, False if 'i' is a (or close to a) null vector
/// \note If any of the parameter is a nullptr, an exception will be raised
template <class T, int VOpt>
bool buildOrthonormalBasis(Eigen::Matrix<T, 3, 1, VOpt>* i,
						   Eigen::Matrix<T, 3, 1, VOpt>* j,
						   Eigen::Matrix<T, 3, 1, VOpt>* k)
{
	SURGSIM_ASSERT(i != nullptr) << "Parameter [in, out] 'i' is a nullptr";
	SURGSIM_ASSERT(j != nullptr) << "Parameter [out] 'j' is a nullptr";
	SURGSIM_ASSERT(k != nullptr) << "Parameter [out] 'k' is a nullptr";

	if (i->isZero())
	{
		return false;
	}

	i->normalize();
	*j = i->unitOrthogonal();
	*k = i->cross(*j);

	return true;
}

/// Calculate the best unit normal we can find in the direction of pXq for one of the endpoints of q.
/// Try multiple arrangements of the end points to reduce the artifacts when three of the vertices may
/// be nearly collinear.
/// \param p segment p
/// \param q segment q
/// \param epsilon when the norm of p x q is above epsilon, the cross product is assumed to be valid.
/// return the normalized cross product of p x q
template <class T, int VOpt>
Eigen::Matrix<T, 3, 1, VOpt> robustCrossProduct(const std::array<Eigen::Matrix<T, 3, 1, VOpt>, 2>& p,
		const std::array<Eigen::Matrix<T, 3, 1, VOpt>, 2>& q,
		T epsilon)
{

	auto p0p1 = p[1] - p[0];
	auto p1q0 = q[0] - p[1];
	auto p0q0 = q[0] - p[0];
	auto p1q1 = q[1] - p[1];
	auto pXq = p0p1.cross(p1q0);
	auto norm = pXq.norm();
	if (norm < epsilon)
	{
		pXq = p0p1.cross(p0q0);
		norm = pXq.norm();
	}
	if (norm < epsilon)
	{
		pXq = p0p1.cross(p1q1);
		norm = pXq.norm();
	}
	pXq *= static_cast<T>(1.0 / norm);
	return pXq;
}

};  // namespace Math
};  // namespace SurgSim

#endif  // SURGSIM_MATH_VECTOR_H