/*
Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved.
*/
/*--------------------------------------------------------------------*\
Pro/DEVELOP includes
\*--------------------------------------------------------------------*/
#include <ProToolkit.h>
#include <ProAssembly.h>
#include <ProGeomitemdata.h>
#include <ProMdl.h>
#include <ProSolid.h>
#include <ProSelection.h>
/*--------------------------------------------------------------------*\
C System includes
\*--------------------------------------------------------------------*/
#include <math.h>
/*--------------------------------------------------------------------*\
Application includes
\*--------------------------------------------------------------------*/
#include "UtilMath.h"
#include "UtilMatrix.h"
#include "TestError.h"
/*--------------------------------------------------------------------*\
Application global/external data
\*--------------------------------------------------------------------*/
static double identity_matrix[4][4] = { {1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0} };
/*====================================================================*\
FUNCTION : ProUtilMatrixCopy()
PURPOSE : Copy one matrix to another, or initialize a matrix to
be the unitary matrix
\*====================================================================*/
void ProUtilMatrixCopy(
double input[4][4],
double output[4][4])
{
int i,j;
if(input == NULL)
{
for(i=0;i<4;i++)
for(j=0;j<4;j++)
output[i][j] = identity_matrix[i][j];
}
else
{
for(i=0;i<4;i++)
for(j=0;j<4;j++)
output[i][j] = input[i][j];
}
}
/*====================================================================*\
FUNCTION : ProUtilPointTrans()
PURPOSE : Transform a 3d point by a matrix
\*====================================================================*/
void ProUtilPointTrans(
double m[4][4],
double p[3],
double output[3])
{
double buff[4];
ProError status;
if(m == NULL)
{
ProUtilVectorCopy(p, output);
return;
}
status = ProPntTrfEval(p, m, buff);
TEST_CALL_REPORT("ProPntTrfEval()", "ProUtilPointTrans()",
status, status!=PRO_TK_NO_ERROR);
ProUtilVectorCopy(buff, output);
}
/*====================================================================*\
FUNCTION : ProUtilVectorTrans()
PURPOSE : Transform a 3d vector by a matrix
\*====================================================================*/
void ProUtilVectorTrans(
double m[4][4],
double v[3],
double output[3])
{
ProError status;
if(m == NULL)
{
ProUtilVectorCopy(v, output);
return;
}
status = ProVectorTrfEval(v, m, output);
TEST_CALL_REPORT("ProVectorTrfEval()", "ProUtilPointTrans()",
status, status!=PRO_TK_NO_ERROR);
}
/*====================================================================*\
FUNCTION : ProUtilMatrixProduct()
PURPOSE : Multiply two transformation matrices
\*====================================================================*/
void ProUtilMatrixProduct(
double m1[4][4],
double m2[4][4],
double output[4][4])
{
int i,j,k;
/*--------------------------------------------------------------------*\
If the first matrix is zero, just copy the second
(So, if the second is zero, copy the identity matrix.)
\*--------------------------------------------------------------------*/
if(m1 == NULL)
{
ProUtilMatrixCopy(m2, output);
return;
}
/*--------------------------------------------------------------------*\
If the second matrix is zero, just copy the first
\*--------------------------------------------------------------------*/
if(m2 == NULL)
{
ProUtilMatrixCopy(m1, output);
return;
}
/*--------------------------------------------------------------------*\
Do the multiplication
\*--------------------------------------------------------------------*/
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
output[i][j] = 0.0;
for(k=0;k<4;k++)
output[i][j] += m1[i][k] * m2[k][j];
}
}
}
/*====================================================================*\
FUNCTION : ProUtilMatrixInvert()
PURPOSE : Find the inverse of a transformation matrix
\*====================================================================*/
int ProUtilMatrixInvert(
double m[4][4],
double output[4][4])
{
double vec[3], scale_sq, inv_sq_scale;
int i,j;
/*--------------------------------------------------------------------*\
If the matrix is null, return the identity matrix
\*--------------------------------------------------------------------*/
if(m == NULL)
{
ProUtilMatrixCopy(NULL, output);
return(1);
}
/*--------------------------------------------------------------------*\
Obtain the matrix scale
\*--------------------------------------------------------------------*/
vec[0] = m[0][0];
vec[1] = m[0][1];
vec[2] = m[0][2];
scale_sq = vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2];
/*--------------------------------------------------------------------*\
Check whether there is an inverse, and if not, return 0
\*--------------------------------------------------------------------*/
if(scale_sq < (.000000001 * .000000001))
return(0);
/*--------------------------------------------------------------------*\
Need the inverse scale squared
\*--------------------------------------------------------------------*/
inv_sq_scale = 1.0 / scale_sq;
/*--------------------------------------------------------------------*\
The orientation vectors
\*--------------------------------------------------------------------*/
for(j=0;j<3;j++)
{
for(i=0;i<3;i++)
output[j][i] = m[i][j] * inv_sq_scale;
output[j][3] = 0.0;
}
/*--------------------------------------------------------------------*\
The shift vectors
\*--------------------------------------------------------------------*/
for(i=0;i<3;i++)
{
output[3][i] = 0.0;
for(j=0;j<3;j++)
output[3][i] -= m[i][j] * m[3][j] * inv_sq_scale;
}
output[3][3] = 1.0;
return(1);
}
/*=============================================================*\
FUNCTION: ProUtilInvertCsysMatrix()
PURPOSE: Develop the inverted selection csys transform
\*=============================================================*/
ProError ProUtilInvertCsysMatrix(
ProSelection sel, ProGeomitemdata *p_data, ProMatrix tmatrix )
{
ProError err;
ProMatrix matrix, csysmat;
ProAsmcomppath path;
/* Get the "Asmcomppath transform" */
err = ProSelectionAsmcomppathGet(sel, &path);
err = ProAsmcomppathTrfGet(&path, PRO_B_TRUE, matrix);
/* Create the csys transform */
ProUtilMatrixCopy( NULL, csysmat );
ProUtilVectorCopy(p_data->data.p_csys_data->x_vector, csysmat[0]);
ProUtilVectorCopy(p_data->data.p_csys_data->y_vector, csysmat[1]);
ProUtilVectorCopy(p_data->data.p_csys_data->z_vector, csysmat[2]);
ProUtilVectorCopy(p_data->data.p_csys_data->origin, csysmat[3]);
/* Transform the csys 'vectors' by the "Asmcomppath" transform */
ProUtilMatrixProduct( csysmat, matrix, tmatrix );
ProUtilMatrixCopy ( tmatrix, matrix );
/* Invert the "selection csys" transform */
ProUtilMatrixInvert( matrix, tmatrix );
return (PRO_TK_NO_ERROR);
}