unsigned int MxPropSlim::check_local_validity(unsigned int v, const float* vnew) { const MxFaceList& N = m->neighbors(v); unsigned int nfailed = 0; unsigned int i; for(i=0; i<(unsigned int)N.length(); i++){ if( m->face_mark(N[i]) == 1 ){ MxFace& f = m->face(N[i]); unsigned int k = f.find_vertex(v); unsigned int x = f[(k+1)%3]; unsigned int y = f[(k+2)%3]; float d_yx[3], d_vx[3], d_vnew[3], f_n[3], n[3]; mxv_sub(d_yx, m->vertex(y), m->vertex(x), 3); // d_yx = y-x mxv_sub(d_vx, m->vertex(v), m->vertex(x), 3); // d_vx = v-x mxv_sub(d_vnew, vnew, m->vertex(x), 3); // d_vnew = vnew-x mxv_cross3(f_n, d_yx, d_vx); mxv_cross3(n, f_n, d_yx); // n = ((y-x)^(v-x))^(y-x) mxv_unitize(n, 3); // assert( mxv_dot(d_vx, n, 3) > -FEQ_EPS ); if(mxv_dot(d_vnew,n,3)<local_validity_threshold*mxv_dot(d_vx,n,3)) nfailed++; } } return nfailed; }
MxBool optimize2v( const MxQuadric3 *q, Vec3 *v, const Vec3 *v1, const Vec3 *v2) { Vec3 Av2, Ad, d; Mat3 A; double denom; double a, f1, f2, f3, f4; Vec3 vtemp; Vec3 temp; mxv_sub( d.elt, v1->elt, v2->elt, 3 ); quad_tensor( q, &A ); vecmul33( &Av2, &A, v2 ); vecmul33( &Ad, &A, &d ); denom = 2*( mxv_dot( d.elt, Ad.elt, 3 ) ); if( MxFEQ(denom, 0.0, 1e-12f) ) return 0; quad_vector( &vtemp, q ); f1 = mxv_dot( vtemp.elt, d.elt, 3 ); f2 = mxv_dot( Av2.elt, d.elt, 3 ); f3 = mxv_dot( v2->elt, Ad.elt, 3 ); f4 = mxv_dot( Ad.elt, d.elt, 3 ); a = ( -2*f1 - f2 - f3 ) / ( 2*f4 ); if( a<0.0 ) a=0.0; else if( a>1.0 ) a=1.0; mxv_mul( temp.elt, d.elt, a, 3 ); mxv_add( v->elt, temp.elt, v2->elt, 3 ); /* MX_ASSERT( quad_evaluatev( q, v->elt ) >= 0 ); */ return 1; }
void vecmul44( Vec4 *out, const Mat4 *m1, const Vec4 *v) { out->elt[0] = mxv_dot( m1->row[0].elt, v->elt, 4 ); out->elt[1] = mxv_dot( m1->row[1].elt, v->elt, 4 ); out->elt[2] = mxv_dot( m1->row[2].elt, v->elt, 4 ); out->elt[3] = mxv_dot( m1->row[3].elt, v->elt, 4 ); }
void triangle_raw_plane( Vec4 *out, const Vec3 *v1, const Vec3 *v2, const Vec3 *v3 ) { Vec3 n; triangle_raw_normal( &n, v1, v2, v3); out->elt[0] = n.elt[0]; out->elt[1] = n.elt[1]; out->elt[2] = n.elt[2]; out->elt[3] = -( mxv_dot( n.elt, v1->elt, 3 ) ); } /* end function triangle_raw_plane */
void matmul44(Mat4 *out, const Mat4 *m1, const Mat4 *m2) { Mat4 temp, temp2; int i,j; transpose44( &temp, m1 ); copy44( &temp2, m2 ); for(i = 0 ; i < 4 ; i++ ) for(j=0;j<4;j++) out->row[i].elt[j] = mxv_dot(temp2.row[i].elt, temp.row[j].elt, 4); }
int triangle_plane( Vec4 *out, const Vec3 *v1, const Vec3 *v2, const Vec3 *v3 ) { Vec3 n; if( !triangle_normal( &n, v1, v2, v3 ) ) return 0; out->elt[0] = n.elt[0]; out->elt[1] = n.elt[1]; out->elt[2] = n.elt[2]; out->elt[3] = -( mxv_dot(n.elt, v1->elt, 3) ); return 1; } /* end function triangle_plane */
/* * invert a 3x3 matrix. returns the determinant. */ double invert33( Mat3 *m_out, const Mat3 *m1 ) { Mat3 temp, A; double d; /* compute the adjoint: adjoint( &A, m1 ); */ mxv_cross( A.row[0].elt, m1->row[1].elt, m1->row[2].elt, 3 ); mxv_cross( A.row[1].elt, m1->row[2].elt, m1->row[0].elt, 3 ); mxv_cross( A.row[2].elt, m1->row[0].elt, m1->row[1].elt, 3 ); d = mxv_dot( A.row[0].elt, m1->row[0].elt, 3 ); if( d==0.0 ) return 0.0; /* compute the transpose: transpose( &temp, &A ); */ col33( &(temp.row[0]), &A, 0 ); col33( &(temp.row[1]), &A, 1 ); col33( &(temp.row[2]), &A, 2 ); mxv_div( m_out->row[0].elt, temp.row[0].elt, d, 3 ); mxv_div( m_out->row[1].elt, temp.row[1].elt, d, 3 ); mxv_div( m_out->row[2].elt, temp.row[2].elt, d, 3 ); return d; }
double mxv_len2(const double *v, int dim) { return mxv_dot(v,v,dim); }
double mxv_len(const double *v, int dim) { return (double) sqrt(mxv_dot(v,v,dim)); }
void vecmul33( Vec3 *v_out, const Mat3 *m1, const Vec3 *v1) { v_out->elt[0] = mxv_dot( m1->row[0].elt, v1->elt, 3 ); v_out->elt[1] = mxv_dot( m1->row[1].elt, v1->elt, 3 ); v_out->elt[2] = mxv_dot( m1->row[2].elt, v1->elt, 3 ); }
static double det( const Mat3 *m1 ) { Vec3 temp; mxv_cross( temp.elt, m1->row[1].elt, m1->row[2].elt, 3 ); return mxv_dot( m1->row[0].elt, temp.elt, 3 ); }
MxBool optimize3v( const MxQuadric3 *q, Vec3 *v, const Vec3 *v1, const Vec3 *v2, const Vec3 *v3) { Mat3 A; Vec3 d13, d23, B; Vec3 temp1, temp2, temp3; double d13_d23, v3_d13, v3_d23, d23Ad23, d13Ad13, denom; double a, b, f1, f2, f3, f4; Vec3 Ad13, Ad23, Av3; mxv_sub( d13.elt, v1->elt, v3->elt, 3 ); mxv_sub( d23.elt, v2->elt, v3->elt, 3 ); quad_tensor( q, &A ); quad_vector( &B, q ); vecmul33( &Ad13, &A, &d13 ); vecmul33( &Ad23, &A, &d23 ); vecmul33( &Av3, &A, v3 ); d13_d23 = (mxv_dot( d13.elt, Ad23.elt, 3 )) + (mxv_dot( d23.elt, Ad13.elt, 3 )); v3_d13 = ( mxv_dot( d13.elt, Av3.elt, 3 )) + ( mxv_dot( v3->elt, Ad13.elt, 3 )); v3_d23 = ( mxv_dot( d23.elt, Av3.elt, 3 )) + ( mxv_dot( v3->elt, Ad23.elt, 3 )); d23Ad23 = mxv_dot( d23.elt, Ad23.elt, 3 ); d13Ad13 = mxv_dot( d13.elt, Ad13.elt, 3 ); denom = d13Ad13 * d23Ad23 - 2 * d13_d23; if( MxFEQ(denom, 0.0, 1e-12f) ) return 0; f1 = mxv_dot( B.elt, d13.elt, 3 ); f2 = mxv_dot( B.elt, d23.elt, 3 ); f3 = mxv_dot( B.elt, d23.elt, 3 ); f4 = mxv_dot( B.elt, d13.elt, 3 ); a = ( d23Ad23*(2*f1 + v3_d13) - d13_d23*(2*f2 + v3_d23) ) / -denom; b = ( d13Ad13*(2*f3 + v3_d23) - d13_d23*(2*f4 + v3_d13) ) / -denom; if( a<0.0 ) a=0.0; else if( a>1.0 ) a=1.0; if( b<0.0 ) b=0.0; else if( b>1.0 ) b=1.0; /*his original code for the next 4 lines...*/ /*v = a*d13 + b*d23 + v3;*/ mxv_mul( temp1.elt, d13.elt, a, 3 ); mxv_mul( temp2.elt, d23.elt, b, 3 ); mxv_add( temp3.elt, temp1.elt, temp2.elt, 3 ); mxv_add( v->elt, temp3.elt, v3->elt, 3 ); /* MX_ASSERT( quad_evaluatev( q, v->elt ) >= 0 ); */ return 1; }