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; }
void triangle_raw_normal( Vec3 *out, const Vec3 *v1, const Vec3 *v2, const Vec3 *v3) { Vec3 a, b; mxv_sub( a.elt, v2->elt, v1->elt, 3 ); mxv_sub( b.elt, v3->elt, v1->elt, 3 ); mxv_cross( out->elt, a.elt, b.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; }
double triangle_compactness(const Vec3 *v1, const Vec3 *v2, const Vec3 *v3) { Vec3 temp1, temp2, temp3; double l1, l2, l3; mxv_sub( temp1.elt, v2->elt, v1->elt, 3 ); mxv_sub( temp2.elt, v3->elt, v2->elt, 3 ); mxv_sub( temp3.elt, v1->elt, v3->elt, 3 ); l1 = mxv_len2( temp1.elt, 3 ); l2 = mxv_len2( temp2.elt, 3 ); l3 = mxv_len2( temp3.elt, 3 ); return FOUR_ROOT3 * triangle_area(v1, v2, v3) / (l1+l2+l3); } /* end function triangle_compactness */
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; }