void FreeDistortBaseFx::doDryCompute(TRectD &rect, double frame, const TRenderSettings &info) { if (!m_input.isConnected()) return; if (m_deactivate->getValue()) { m_input->dryCompute(rect, frame, info); return; } TRectD rectOnInput; TRenderSettings infoOnInput; TRectD inBBox; safeTransform(frame, 0, rect, info, rectOnInput, infoOnInput, inBBox); rectOnInput *= inBBox; if (!myIsEmpty(rectOnInput)) m_input->dryCompute(rectOnInput, frame, infoOnInput); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { ALLOCATES(); real *X, XX[NN], Xk[NN], XXr[NN], D[N], DS[N], fD[N], V[NN], VS[NN], *O, Ok[NN]; long k1, K1, k2, K2, k3, K3, ii, jj; int ORDER[N]; char STR[100]; enum symmetrize_ { NONE , X_Xt , Xt_X , PLUS }; enum symmetrize_ symmetrize; enum outs_types { ID , INVERSE , EIGVALS , EIGVECS , EIGVALSDIAG , MAXDIFF , SQRT , LOG , EXP , evalFUN , DET , TRACE }; enum outs_types outs[50]; int ndims, Odims[50]; real det; int oid; int D_computed, V_computed, D_sorted, V_sorted, ORDER_computed; int dim1 , dim2; mxArray *mxX; if( nlhs == 0 ){ nlhs = 1; } if( nlhs > nrhs-2 ){ myErrMsgTxt("There are no enough inputs.\n"); } if( mxIsCell( prhs[0] ) ){ mxX = mxGetCell( prhs[0] , 0 ); dim1 = myGetValue( mxGetCell( prhs[0] , 1 ) ); dim2 = myGetValue( mxGetCell( prhs[0] , 2 ) ); } else { mxX = prhs[0]; dim1 = 1; dim2 = 2; } if( ( mySize( mxX , dim1-1 ) != N ) || ( mySize( mxX , dim1-1 ) != N ) ){ myErrMsgTxt("size( X , %d ) and size( X , %d ) have to be equal to three.\n",dim1,dim2); } if( myIsEmpty( prhs[1] ) ){ symmetrize = NONE; } else if( mxIsChar(prhs[1]) ){ mxGetString( prhs[1], STR, 100 ); if( !myStrcmpi(STR,"+") ) { symmetrize = PLUS; } else if( !myStrcmpi(STR,"xt*x") || !myStrcmpi(STR,"xtx") ) { symmetrize = Xt_X; } else if( !myStrcmpi(STR,"x*xt") || !myStrcmpi(STR,"xxt") ) { symmetrize = X_Xt; } else { myErrMsgTxt("Second argument expected: 'xt*x' , 'x*xt' , '+' , or [].\n"); } } else { myErrMsgTxt("Second argument expected: 'xt*x' , 'x*xt' , '+' , or [].\n"); } for( oid = 0 ; oid < nlhs ; oid++ ){ if( ! mxIsChar(prhs[oid+2]) ){ myErrMsgTxt("Valids arguments are: 'id' 'eigval' 'eigvec' 'log' 'sqrt' 'exp' 'error'.\n"); } mxGetString( prhs[oid+2], STR, 100 ); if( !myStrcmpi(STR,"id") ) { outs[oid] = ID; } else if( !myStrcmpi(STR,"inv") || !myStrcmpi(STR,"inverse") ) { outs[oid] = INVERSE; } else if( !myStrcmpi(STR,"det") ) { outs[oid] = DET; } else if( !myStrcmpi(STR,"trace") ) { outs[oid] = TRACE; } else if( !myStrcmpi(STR,"evec") || !myStrcmpi(STR,"v") || !myStrcmpi(STR,"eigenvec") || !myStrcmpi(STR,"eigvec") || !myStrcmpi(STR,"eigenvectors") ) { outs[oid] = EIGVECS; } else if( !myStrcmpi(STR,"eval") || !myStrcmpi(STR,"d") || !myStrcmpi(STR,"eigenval") || !myStrcmpi(STR,"eigval") || !myStrcmpi(STR,"eigenvalues") ) { outs[oid] = EIGVALS; } else if( !myStrcmpi(STR,"diag") || !myStrcmpi(STR,"dd") ) { outs[oid] = EIGVALSDIAG; } else if( !myStrcmpi(STR,"error") ) { outs[oid] = MAXDIFF; } else if( !myStrcmpi(STR,"sqrt") || !myStrcmpi(STR,"sqrtm") ) { outs[oid] = SQRT; } else if( !myStrcmpi(STR,"log") || !myStrcmpi(STR,"logm") ) { outs[oid] = LOG; } else if( !myStrcmpi(STR,"exp") || !myStrcmpi(STR,"expm") ) { outs[oid] = EXP; } else { myErrMsgTxt("Valids arguments are: 'id' 'inv' 'det' 'trace' 'eigval' 'eigvec' 'log' 'sqrt' 'exp' 'error'.\n"); } } X = mxGetPr( mxX ); ndims = myGetSizes( mxX , Odims ); for( oid = 0 ; oid < nlhs ; oid++ ){ switch( outs[oid] ){ case ID: plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); break; case INVERSE: plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); break; case DET: Odims[dim1-1] = 1; Odims[dim2-1] = 1; plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); Odims[dim1-1] = N; Odims[dim2-1] = N; break; case TRACE: Odims[dim1-1] = 1; Odims[dim2-1] = 1; plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); Odims[dim1-1] = N; Odims[dim2-1] = N; break; case EIGVALS: Odims[dim2-1] = 1; plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); Odims[dim2-1] = N; break; case EIGVECS: plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); break; case EIGVALSDIAG: plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); break; case MAXDIFF: Odims[dim1-1] = 1; Odims[dim2-1] = 1; plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); Odims[dim1-1] = N; Odims[dim2-1] = N; break; case EXP: plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); break; case LOG: plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); break; case SQRT: plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); break; case evalFUN: plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); break; } } K1 = 1; for( k1 = 0 ; k1 < dim1-1 ; k1++ ){ K1 *= Odims[k1]; } K2 = 1; for( k2 = dim1 ; k2 < dim2-1 ; k2++ ){ K2 *= Odims[k2]; } K3 = 1; for( k3 = dim2 ; k3 < ndims ; k3++ ){ K3 *= Odims[k3]; } for( k3 = 0 ; k3 < K3 ; k3++ ){ for( k2 = 0 ; k2 < K2 ; k2++ ){ for( k1 = 0 ; k1 < K1 ; k1++ ){ if( K1 == 1 && K2 == 1 ){ memcpy( Xk , X + k3*NN , NN*sizeof( real ) ); } else { for( jj = 0 ; jj < N ; jj++ ){ for( ii = 0 ; ii < N ; ii++ ){ Xk[ ii + N*jj ] = X[ k1 + K1*( ii + N*( k2 + K2*( jj + N*k3 ))) ]; } } } switch( symmetrize ){ case NONE: memcpy( XX , Xk , NN*sizeof( real ) ); break; case X_Xt: XX[0] = Xk[0]*Xk[0] + Xk[2]*Xk[2]; XX[1] = Xk[1]*Xk[0] + Xk[3]*Xk[2]; XX[2] = Xk[0]*Xk[1] + Xk[2]*Xk[3]; XX[3] = Xk[1]*Xk[1] + Xk[3]*Xk[3]; break; case Xt_X: XX[0] = Xk[0]*Xk[0] + Xk[1]*Xk[1]; XX[1] = Xk[2]*Xk[0] + Xk[3]*Xk[1]; XX[2] = Xk[0]*Xk[2] + Xk[1]*Xk[3]; XX[3] = Xk[2]*Xk[2] + Xk[3]*Xk[3]; break; case PLUS: XX[0] = Xk[0]; XX[1] = XX[2] = ( Xk[1] + Xk[2] )/2.0; XX[3] = Xk[3]; break; } D_computed = 0; V_computed = 0; ORDER_computed = 0; D_sorted = 0; V_sorted = 0; for( oid = 0 ; oid < nlhs ; oid++ ){ switch( outs[oid] ){ case ID: memcpy( Ok , XX , NN*sizeof( real ) ); O = mxGetPr( plhs[oid] ); ToOutput2x2; break; case INVERSE: det = XX[0]*XX[3] - XX[1]*XX[2]; det = 1.0/det; Ok[0] = XX[3] *det; Ok[1] = -XX[1] *det; Ok[2] = -XX[2] *det; Ok[3] = XX[0] *det; O = mxGetPr( plhs[oid] ); ToOutput2x2; break; case DET: Ok[0] = XX[0]*XX[3] - XX[1]*XX[2]; O = mxGetPr( plhs[oid] ); ToOutput1x1; break; case TRACE: Ok[0] = XX[0] + XX[3]; O = mxGetPr( plhs[oid] ); ToOutput1x1; break; case EIGVALS: if( !D_computed ){ EigenValues2x2( XX , D ); D_computed = 1; } if( !ORDER_computed ){ GetOrder( D, ORDER ); ORDER_computed = 1; } if( !D_sorted ){ SortEigenValues( D, ORDER , DS ); D_sorted = 1; } memcpy( Ok , DS , N*sizeof( real ) ); O = mxGetPr( plhs[oid] ); ToOutput2x1; break; case EIGVALSDIAG: if( !D_computed ){ EigenValues2x2( XX , D ); D_computed = 1; } if( !ORDER_computed ){ GetOrder( D, ORDER ); ORDER_computed = 1; } if( !D_sorted ){ SortEigenValues( D, ORDER , DS ); D_sorted = 1; } Ok[0] = DS[0]; Ok[3] = DS[1]; Ok[1] = Ok[2] = 0; O = mxGetPr( plhs[oid] ); ToOutput2x2; break; case EIGVECS: if( !D_computed ){ EigenValues2x2( XX , D ); D_computed = 1; } if( !V_computed ){ EigenVectors2x2( XX , D , V); V_computed = 1; } if( !ORDER_computed ){ GetOrder( D, ORDER ); ORDER_computed = 1; } if( !V_sorted ){ SortEigenVectors( V, ORDER , VS); V_sorted = 1; } memcpy( Ok , VS , NN*sizeof( real ) ); O = mxGetPr( plhs[oid] ); ToOutput2x2; break; // case MAXDIFF: // if( !D_computed ){ EigenValuesSym3x3( XX , D ); D_computed = 1; } // if( !V_computed ){ EigenVectorsSym3x3( XX , D , V); V_computed = 1; } // // Ok[0] = V[0]*V[0]*D[0] + V[3]*V[3]*D[1] + V[6]*V[6]*D[2]; // Ok[1] = V[1]*V[0]*D[0] + V[4]*V[3]*D[1] + V[7]*V[6]*D[2]; // Ok[2] = V[2]*V[0]*D[0] + V[5]*V[3]*D[1] + V[8]*V[6]*D[2]; // // Ok[3] = V[0]*V[1]*D[0] + V[3]*V[4]*D[1] + V[6]*V[7]*D[2]; // Ok[4] = V[1]*V[1]*D[0] + V[4]*V[4]*D[1] + V[7]*V[7]*D[2]; // Ok[5] = V[2]*V[1]*D[0] + V[5]*V[4]*D[1] + V[8]*V[7]*D[2]; // // Ok[6] = V[0]*V[2]*D[0] + V[3]*V[5]*D[1] + V[6]*V[8]*D[2]; // Ok[7] = V[1]*V[2]*D[0] + V[4]*V[5]*D[1] + V[7]*V[8]*D[2]; // Ok[8] = V[2]*V[2]*D[0] + V[5]*V[5]*D[1] + V[8]*V[8]*D[2]; // // Ok[0] = MAX9( fabs( Ok[0] - XX[0] ) , // fabs( Ok[1] - XX[1] ) , // fabs( Ok[2] - XX[2] ) , // fabs( Ok[3] - XX[3] ) , // fabs( Ok[4] - XX[4] ) , // fabs( Ok[5] - XX[5] ) , // fabs( Ok[6] - XX[6] ) , // fabs( Ok[7] - XX[7] ) , // fabs( Ok[8] - XX[8] ) ); // // O = mxGetPr( plhs[oid] ); // ToOutput1x1; // break; // // // case SQRT: // if( !D_computed ){ EigenValuesSym3x3( XX , D ); D_computed = 1; } // if( !V_computed ){ EigenVectorsSym3x3( XX , D , V); V_computed = 1; } // // fD[0] = sqrt( D[0] ); // fD[1] = sqrt( D[1] ); // fD[2] = sqrt( D[2] ); // // FillOk; // O = mxGetPr( plhs[oid] ); // ToOutput3x3; // break; // // // case LOG: // if( !D_computed ){ EigenValuesSym3x3( XX , D ); D_computed = 1; } // if( !V_computed ){ EigenVectorsSym3x3( XX , D , V); V_computed = 1; } // // fD[0] = log( D[0] ); // fD[1] = log( D[1] ); // fD[2] = log( D[2] ); // // FillOk; // O = mxGetPr( plhs[oid] ); // ToOutput3x3; // break; #define r eval[0] #define e eval[1] #define er eval[2] case EXP: r = XX[0] - XX[3]; r = 4*XX[1]*XX[2] + r*r; if( r >= 0 ){ r = sqrt(r); e = exp( ( XX[0] + XX[3] - r )/2 )/r/2.0; er = exp(r); Ok[0] = e * ( XX[3] - XX[0] + r + er*(XX[0]-XX[3]+r) ); Ok[1] = e * XX[1] * ( er - 1 ) * 2; Ok[2] = e * XX[2] * ( er - 1 ) * 2; Ok[3] = e * ( XX[0] - XX[3] + r + er*(XX[3]-XX[0]+r) ); } else { r = sqrt( -r ); e = exp( ( XX[0] + XX[3] )/2 )/r; er = sin(r/2); Ok[0] = e * ( r*cos(r/2) + ( XX[0]-XX[3] )*er ); Ok[1] = 2 * XX[1] * e * er; Ok[2] = 2 * XX[2] * e * er; Ok[3] = e * ( r*cos(r/2) + ( XX[3]-XX[0] )*er ); } O = mxGetPr( plhs[oid] ); ToOutput2x2; break; // case evalFUN: // O = mxGetPr( plhs[oid] ) + k*NN; // if( !D_computed ){ EigenValuesSym3x3( XX , D ); D_computed = 1; } // if( !V_computed ){ EigenVectorsSym3x3( XX , D , V); V_computed = 1; } // // fD[0] = exp( D[0] ); // fD[1] = exp( D[1] ); // fD[2] = exp( D[2] ); // // mexCallMATLAB(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[], const char *name) // // FillO // break; } } }}} EXIT: myFreeALLOCATES(); }
void FreeDistortBaseFx::doCompute(TTile &tile, double frame, const TRenderSettings &ri) { if (!m_input.isConnected()) return; //Upon deactivation, this fx does nothing. if (m_deactivate->getValue()) { m_input->compute(tile, frame, ri); return; } //Get the source quad TPointD p00_b = m_p00_b->getValue(frame); TPointD p10_b = m_p10_b->getValue(frame); TPointD p01_b = m_p01_b->getValue(frame); TPointD p11_b = m_p11_b->getValue(frame); //Get destination quad TPointD p00_a = m_p00_a->getValue(frame); TPointD p10_a = m_p10_a->getValue(frame); TPointD p01_a = m_p01_a->getValue(frame); TPointD p11_a = m_p11_a->getValue(frame); if (m_isCastShadow) { //Shadows are mirrored tswap(p00_a, p01_a); tswap(p10_a, p11_a); } //Get requested tile's geometry TRasterP tileRas(tile.getRaster()); TRectD tileRect(convert(tileRas->getBounds()) + tile.m_pos); //Call transform to get the minimal rectOnInput TRectD inRect; TRenderSettings riNew; TRectD inBBox; safeTransform(frame, 0, tileRect, ri, inRect, riNew, inBBox); //Intersect with the bbox inRect *= inBBox; if (myIsEmpty(inRect)) return; double scale = ri.m_affine.a11; double downBlur = m_downBlur->getValue(frame) * scale; double upBlur = m_upBlur->getValue(frame) * scale; int brad = tceil(tmax(downBlur, upBlur)); inRect = inRect.enlarge(brad); TDimension inRectSize(tceil(inRect.getLx()), tceil(inRect.getLy())); TTile inTile; m_input->allocateAndCompute(inTile, inRect.getP00(), inRectSize, tileRas, frame, riNew); TPointD inTilePosRi = inTile.m_pos; //Update quads by the scale factors p00_b = riNew.m_affine * p00_b; p10_b = riNew.m_affine * p10_b; p01_b = riNew.m_affine * p01_b; p11_b = riNew.m_affine * p11_b; p00_a = ri.m_affine * p00_a; p10_a = ri.m_affine * p10_a; p01_a = ri.m_affine * p01_a; p11_a = ri.m_affine * p11_a; PerspectiveDistorter perpDistorter( p00_b - inTile.m_pos, p10_b - inTile.m_pos, p01_b - inTile.m_pos, p11_b - inTile.m_pos, p00_a, p10_a, p01_a, p11_a); BilinearDistorter bilDistorter( p00_b - inTile.m_pos, p10_b - inTile.m_pos, p01_b - inTile.m_pos, p11_b - inTile.m_pos, p00_a, p10_a, p01_a, p11_a); TQuadDistorter *distorter; if (m_distortType->getValue() == PERSPECTIVE) distorter = &perpDistorter; else if (m_distortType->getValue() == BILINEAR) distorter = &bilDistorter; else assert(0); if (m_isCastShadow) { TRaster32P ras32 = inTile.getRaster(); TRaster64P ras64 = inTile.getRaster(); if (ras32) { if (m_fade->getValue(frame) > 0) doFade(ras32, m_color->getValue(frame), m_fade->getValue(frame) / 100.0); if (brad > 0) doBlur(ras32, upBlur, downBlur, m_upTransp->getValue(frame) / 100.0, m_downTransp->getValue(frame) / 100.0, inBBox.y0 - inTile.m_pos.y, inBBox.y1 - inTile.m_pos.y); else if (m_upTransp->getValue(frame) > 0 || m_downTransp->getValue(frame) > 0) doTransparency(ras32, m_upTransp->getValue(frame) / 100.0, m_downTransp->getValue(frame) / 100.0, inBBox.y0 - inTile.m_pos.y, inBBox.y1 - inTile.m_pos.y); } else if (ras64) { if (m_fade->getValue(frame) > 0) doFade(ras64, toPixel64(m_color->getValue(frame)), m_fade->getValue(frame) / 100.0); if (brad > 0) doBlur(ras64, upBlur, downBlur, m_upTransp->getValue(frame) / 100.0, m_downTransp->getValue(frame) / 100.0, inBBox.y0 - inTile.m_pos.y, inBBox.y1 - inTile.m_pos.y); else if (m_upTransp->getValue(frame) > 0 || m_downTransp->getValue(frame) > 0) doTransparency(ras64, m_upTransp->getValue(frame) / 100.0, m_downTransp->getValue(frame) / 100.0, inBBox.y0 - inTile.m_pos.y, inBBox.y1 - inTile.m_pos.y); } else assert(false); } distort(tileRas, inTile.getRaster(), *distorter, convert(tile.m_pos), TRop::Bilinear); }