Example #1
0
std::vector<double> repo::core::RepoBoundingBox::getTransformationMatrix() const
{
    std::vector<double> transformation(16);

    RepoVertex centroid = RepoVertex(max+min);

    transformation[0] = 1;
    transformation[1] = 0;
    transformation[2] = 0;
    transformation[3] = 0;

    transformation[4] = 0;
    transformation[5] = 1;
    transformation[6] = 0;
    transformation[7] = 0;

    transformation[8] = 0;
    transformation[9] = 0;
    transformation[10] = 1;
    transformation[11] = 0;

    transformation[12] = centroid.x/2;
    transformation[13] = centroid.y/2;
    transformation[14] = centroid.z/2;
    transformation[15] = 1;

    return transformation;
}
//------------------------------------------------------------------------------
double repo::core::RepoNodeMesh::getFacesBoundaryLength(
    const unsigned int & faceIndexA,
    const unsigned int & faceIndexB) const
{
    double boundaryLength = 0;
    const aiFace & faceA = faces->at(faceIndexA);
    const aiFace & faceB = faces->at(faceIndexB);

    std::vector<repo::core::RepoVertex> commonVertices;
    for (unsigned int i = 0; i < faceA.mNumIndices; ++i)
    {
        RepoVertex a(vertices->at(faceA.mIndices[i]));
        for (unsigned int j = 0; j < faceB.mNumIndices; ++j)
        {
            if (a == RepoVertex(vertices->at(faceB.mIndices[j])))
                commonVertices.push_back(a);
        }
    }

    if (commonVertices.size() > 1)
    {
        for (unsigned int i = 0; i < commonVertices.size() - 1; ++i)
        {
            boundaryLength += RepoVertex::distancePointToPoint<double>(
                                  commonVertices[i], commonVertices[i+1]);
        }
    }
    return boundaryLength;
}
Example #3
0
repo::core::RepoBoundingBox::RepoBoundingBox(const aiMesh * mesh)
{
	if (mesh->mNumVertices)
	{
        min = RepoVertex(mesh->mVertices[0]);
        max = RepoVertex(mesh->mVertices[0]);
	}

	for (unsigned int i = 0; i < mesh->mNumVertices; ++i)
	{
        RepoVertex tmp = RepoVertex(mesh->mVertices[i]);

		min.x = std::min(min.x,tmp.x);
		min.y = std::min(min.y,tmp.y);
		min.z = std::min(min.z,tmp.z);

		max.x = std::max(max.x,tmp.x);
		max.y = std::max(max.y,tmp.y);
		max.z = std::max(max.z,tmp.z);
	}
}
Example #4
0
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "repo_vertex.h"
#include "../conversion/repo_transcoder_string.h"

//------------------------------------------------------------------------------
const repo::core::RepoVertex repo::core::RepoVertex::X_AXIS = RepoVertex(1,0,0);
const repo::core::RepoVertex repo::core::RepoVertex::Y_AXIS = RepoVertex(0,1,0);
const repo::core::RepoVertex repo::core::RepoVertex::Z_AXIS = RepoVertex(0,0,1);
const unsigned int repo::core::RepoVertex::DIMENSIONALITY = 3;
//------------------------------------------------------------------------------

std::string repo::core::RepoVertex::toString() const
{
    return "[" + repo::core::RepoTranscoderString::toString(x) + ", " + repo::core::RepoTranscoderString::toString(y) + ", " +
            repo::core::RepoTranscoderString::toString(z) + "]";
}

//------------------------------------------------------------------------------
void repo::core::RepoVertex::updateMinMax(RepoVertex& min, RepoVertex& max) const
{
	for (unsigned int i = 0; i < DIMENSIONALITY; ++i)
Example #5
0
void repo::core::RepoPCA::initialize(
        const std::vector<RepoVertex>& xyzVertices)
{
	//std::set<RepoVertex> vertices;
	//for each (const RepoVertex& v in vert)
	//	vertices.insert(v);

    //--------------------------------------------------------------------------
	// Calculate the xyzMean vertex and the midpoint of the dataset
	// See http://en.wikipedia.org/wiki/Sample_mean_and_sample_covariance#Weighted_samples
	// Weighted mean = (sum w_i x_i) / sum w_i
	double sumOfWeights = 0;
    for (unsigned int i = 0; i < xyzVertices.size(); ++i)
    {
        RepoVertex v = xyzVertices[i];
		xyzMean += RepoVertex(v * (float) v.weight);	
		sumOfWeights += v.weight;		
	}
	xyzMean /= (float) sumOfWeights; //(float) vertices.size();	
	
    //--------------------------------------------------------------------------
	// Eigenvalue decomposition of the covariance matrix
	double eigenVectors[3][3];
	double eigenValues[3];
	// Calculated eigenValues (and vectors) are in ascending order.
	// Eigenvectors are in the respective columns.
    aiMatrix3x3 covarianceMatrix = RepoEigen::covarianceMatrix(xyzVertices, xyzMean);
	RepoEigen::eigenvalueDecomposition(covarianceMatrix, eigenVectors, eigenValues);

    //--------------------------------------------------------------------------
	// Store eigenVectors and eigenValues.
	principalComponents.resize(RepoVertex::DIMENSIONALITY);
	for (unsigned int i = 0; i < principalComponents.size(); ++i)
	{
		unsigned int index = RepoVertex::DIMENSIONALITY - i - 1;
		for (unsigned int xyz = 0; xyz < RepoVertex::DIMENSIONALITY; ++ xyz)
			principalComponents[i].vector[xyz] = (float) eigenVectors[xyz][index]; 
		principalComponents[i].vector.Normalize();
		principalComponents[i].value = eigenValues[index];
	}
	
    //--------------------------------------------------------------------------
	// Get the rotation matrix to transform from XYZ to eigenVectors UVW space.
	// See http://ocw.mit.edu/courses/aeronautics-and-astronautics/16-07-dynamics-fall-2009/lecture-notes/MIT16_07F09_Lec03.pdf
	// page 10.
    uvwRotationMatrix.a1 = principalComponents[U].vector.x;// * RepoVertex::X_AXIS;
    uvwRotationMatrix.a2 = principalComponents[U].vector.y;// * RepoVertex::Y_AXIS;
    uvwRotationMatrix.a3 = principalComponents[U].vector.z;// * RepoVertex::Z_AXIS;

    uvwRotationMatrix.b1 = principalComponents[V].vector.x;// * RepoVertex::X_AXIS;
    uvwRotationMatrix.b2 = principalComponents[V].vector.y;// * RepoVertex::Y_AXIS;
    uvwRotationMatrix.b3 = principalComponents[V].vector.z;// * RepoVertex::Z_AXIS;

    uvwRotationMatrix.c1 = principalComponents[W].vector.x;// * RepoVertex::X_AXIS;
    uvwRotationMatrix.c2 = principalComponents[W].vector.y;// * RepoVertex::Y_AXIS;
    uvwRotationMatrix.c3 = principalComponents[W].vector.z;// * RepoVertex::Z_AXIS;

    //--------------------------------------------------------------------------
	// The inverse rotation, in this particular case T^-1 == T'
    xyzRotationMatrix = aiMatrix3x3t<float>(uvwRotationMatrix).Transpose();
	
    //--------------------------------------------------------------------------
	// Rotate the vertices around the xyzMean to the UVW space to get the bbox.
    uvwMin = RepoVertex(RepoVertex::getMaxVertex<float>());
    uvwMax = RepoVertex(RepoVertex::getMinVertex<float>());


    //uvwVertices.reserve(vertices.size());
    sumOfWeights = 0;
    for (unsigned int i = 0; i < xyzVertices.size(); ++i)
    {
        RepoVertex uvwVertex = transformToUVW(xyzVertices[i]);
        uvwVertex.updateMinMax(uvwMin, uvwMax);
        uvwVertices.push_back(uvwVertex);

        uvwMean += RepoVertex(uvwVertex * (float) uvwVertex.weight);
        sumOfWeights += uvwVertex.weight;
    }
    uvwMean /= (float) sumOfWeights; //(float) vertices.size();
	
    //--------------------------------------------------------------------------
	// Store the lengths of the eigenvector oriented bounding box and calculate
	// the new midpoint in UVW.
	for (unsigned int i = 0; i < RepoVertex::DIMENSIONALITY; ++i)
	{
		// Bbox length along one of the UVW axes.
		double length = std::abs(uvwMax[i] - uvwMin[i]);
		principalComponents[i].magnitude = length;
		uvwCentroid[i] = (float) (uvwMin[i] + length/2.0f);
	}
	
    //--------------------------------------------------------------------------
	// Transformed centroid in UVW is the centroid of the PCA bbox in XYZ.
	xyzCentroid = transformToXYZ(uvwCentroid); 
    xyzMin = transformToXYZ(uvwMin);
    xyzMax = transformToXYZ(uvwMax);
}
Example #6
0
repo::core::RepoVertex repo::core::RepoPCA::transformToXYZ(const RepoVertex& v)
	const
{
    return RepoVertex((xyzRotationMatrix * v) + xyzMean);
}
Example #7
0
repo::core::RepoVertex repo::core::RepoPCA::transformToUVW(const RepoVertex& v) 
	const
{
    return RepoVertex(uvwRotationMatrix * (v - xyzMean));
}