Esempio n. 1
0
// draw periodic cell, if active
void OpenGLRenderer::drawPeriodicCell(){
	if(!scene->isPeriodic) return;
	glColor3v(cellColor);
	glPushMatrix();
		// Vector3r size=scene->cell->getSize();
		const Matrix3r& hSize=scene->cell->hSize;
		if(dispScale!=Vector3r::Ones()){
			const Matrix3r& refHSize(scene->cell->refHSize);
			Matrix3r scaledHSize;
			for(int i=0; i<3; i++) scaledHSize.col(i)=refHSize.col(i)+dispScale.cwiseProduct(Vector3r(hSize.col(i)-refHSize.col(i)));
			GLUtils::Parallelepiped(scaledHSize.col(0),scaledHSize.col(1),scaledHSize.col(2));
		} else {
			GLUtils::Parallelepiped(hSize.col(0),hSize.col(1),hSize.col(2));
		}
	glPopMatrix();
}
Esempio n. 2
0
// draw periodic cell, if active
void Renderer::drawPeriodicCell(){
	if(!scene->isPeriodic || !cell) return;
	glColor3v(Vector3r(1,1,0));
	glPushMatrix();
		const Matrix3r& hSize=scene->cell->hSize;
		if(scaleOn && dispScale!=Vector3r::Ones()){
			const Matrix3r& refHSize(scene->cell->refHSize);
			Matrix3r scaledHSize;
			for(int i=0; i<3; i++) scaledHSize.col(i)=refHSize.col(i)+((dispScale-Vector3r::Ones()).array()*Vector3r(hSize.col(i)-refHSize.col(i)).array()).matrix();
			GLUtils::Parallelepiped(scaledHSize.col(0),scaledHSize.col(1),scaledHSize.col(2));
		} else 
		{
			GLUtils::Parallelepiped(hSize.col(0),hSize.col(1),hSize.col(2));
		}
	glPopMatrix();
}
Esempio n. 3
0
void Cell::integrateAndUpdate(Real dt){
	//incremental displacement gradient
	_trsfInc=dt*gradV;
	// total transformation; M = (Id+G).M = F.M
	trsf+=_trsfInc*trsf;
	_invTrsf=trsf.inverse();

	if(trsfUpperTriangular) checkTrsfUpperTriangular();

	// hSize contains colums with updated base vectors
	Matrix3r prevHsize=hSize; // remember old value
	if(homoDeform==HOMO_GRADV2) hSize=(Matrix3r::Identity()-gradV*dt/2.).inverse()*(Matrix3r::Identity()+gradV*dt/2.)*hSize;
	else hSize+=_trsfInc*hSize;
	pprevHsize=.5*(prevHsize+hSize); // average of previous and current value

	if(hSize.determinant()==0){ throw std::runtime_error("Cell is degenerate (zero volume)."); }
	// lengths of transformed cell vectors, skew cosines
	Matrix3r Hnorm; // normalized transformed base vectors
	for(int i=0; i<3; i++){
		Vector3r base(hSize.col(i));
		_size[i]=base.norm(); base/=_size[i]; //base is normalized now
		Hnorm(0,i)=base[0]; Hnorm(1,i)=base[1]; Hnorm(2,i)=base[2];
	};
	// skew cosines
	for(int i=0; i<3; i++){
		int i1=(i+1)%3, i2=(i+2)%3;
		// sin between axes is cos of skew
		_cos[i]=(Hnorm.col(i1).cross(Hnorm.col(i2))).squaredNorm();
	}
	// pure shear trsf: ones on diagonal
	_shearTrsf=Hnorm;
	// pure unshear transformation
	_unshearTrsf=_shearTrsf.inverse();
	// some parts can branch depending on presence/absence of shear
	_hasShear=(hSize(0,1)!=0 || hSize(0,2)!=0 || hSize(1,0)!=0 || hSize(1,2)!=0 || hSize(2,0)!=0 || hSize(2,1)!=0);
	// OpenGL shear matrix (used frequently)
	fillGlShearTrsfMatrix(_glShearTrsfMatrix);

	if(!(homoDeform==HOMO_NONE || homoDeform==HOMO_POS || homoDeform==HOMO_VEL || homoDeform==HOMO_VEL_2ND || homoDeform==HOMO_GRADV2)) throw std::invalid_argument("Cell.homoDeform must be in {0,1,2,3,4}.");
}
bool PositionBasedElasticRod::ComputeDarbouxVector(const Matrix3r& dA, const Matrix3r& dB, const float mid_edge_length, Vector3r& darboux_vector)
{

    float factor = 1.0f + dA.col(0).dot(dB.col(0)) + dA.col(1).dot(dB.col(1)) + dA.col(2).dot(dB.col(2));

    factor = 2.0f / (mid_edge_length * factor);

    for (int c = 0; c < 3; ++c)
    {
        const int i = permutation[c][0];
        const int j = permutation[c][1];
        const int k = permutation[c][2];

        darboux_vector[i] = dA.col(j).dot(dB.col(k)) - dA.col(k).dot(dB.col(j));
    }

    darboux_vector *= factor;
    return true;
}
// ----------------------------------------------------------------------------------------------
bool PositionBasedElasticRod::ComputeMaterialFrame(
    const Vector3r& pA,
    const Vector3r& pB,
    const Vector3r& pG,
    Matrix3r& frame)
{

    frame.col(2) = (pB - pA);
    frame.col(2).normalize();

    frame.col(1) = (frame.col(2).cross(pG - pA));
    frame.col(1).normalize();

    frame.col(0) = frame.col(1).cross(frame.col(2));
//	frame.col(0).normalize();
    return true;
}
Esempio n. 6
0
void Membrane::setRefConf(){
	if(!node) node=make_shared<Node>();
	// set initial node position and orientation
	node->pos=this->getCentroid();
	// for orientation, there is a few choices which one to pick
	enum {INI_CS_SIMPLE=0,INI_CS_NODE0_AT_X};
	const int ini_cs=INI_CS_NODE0_AT_X;
	//const int ini_cs=INI_CS_SIMPLE;
	switch(ini_cs){
		case INI_CS_SIMPLE:
			node->ori.setFromTwoVectors(Vector3r::UnitZ(),this->getNormal());
			break;
		case INI_CS_NODE0_AT_X:{
			Matrix3r T;
			T.col(0)=(nodes[0]->pos-node->pos).normalized(); // QQQ: row->col
			T.col(2)=this->getNormal();
			T.col(1)=T.col(2).cross(T.col(0));
			assert(T.col(0).dot(T.col(2))<1e-12);
			node->ori=Quaternionr(T);
			break;
		}
	};
	// reference nodal positions
	for(int i:{0,1,2}){
		// Vector3r nl=node->ori.conjugate()*(nodes[i]->pos-node->pos); // QQQ
		Vector3r nl=node->glob2loc(nodes[i]->pos);
		assert(nl[2]<1e-6*(max(abs(nl[0]),abs(nl[1])))); // z-coord should be zero
		refPos.segment<2>(2*i)=nl.head<2>();
	}
	// reference nodal rotations
	refRot.resize(3);
	for(int i:{0,1,2}){
		// facet node orientation minus vertex node orientation, in local frame (read backwards)
		/// QQQ: refRot[i]=node->ori*nodes[i]->ori.conjugate();
		refRot[i]=nodes[i]->ori.conjugate()*node->ori;
		//LOG_WARN("refRot["<<i<<"]="<<AngleAxisr(refRot[i]).angle()<<"/"<<AngleAxisr(refRot[i]).axis().transpose());
	};
	// set displacements to zero
	uXy=phiXy=Vector6r::Zero();
	#ifdef MEMBRANE_DEBUG_ROT
		drill=Vector3r::Zero();
		currRot.resize(3);
	#endif
	// delete stiffness matrices to force their re-creating
	KKcst.resize(0,0); 
	KKdkt.resize(0,0);
};
bool PositionBasedElasticRod::ComputeDarbouxGradient(
    const Vector3r& darboux_vector, const float length,
    const Matrix3r& da, const Matrix3r& db,
    //const Matrix3r(*dajpi)[3], const Matrix3r(*dbjpi)[3],
    const Matrix3r dajpi[3][3], const Matrix3r dbjpi[3][3],
    const Vector3r& bendAndTwistKs,
    Matrix3r& omega_pa, Matrix3r& omega_pb, Matrix3r& omega_pc, Matrix3r& omega_pd, Matrix3r& omega_pe
)
{


    //float x = 1.0f + da[0] * db[0] + da[1] * db[1] + da[2] * db[2];
    float x = 1.0f + da.col(0).dot(db.col(0)) + da.col(1).dot(db.col(1)) + da.col(2).dot(db.col(2));
    x = 2.0f / (length * x);

    for (int c = 0; c < 3; ++c)
    {
        const int i = permutation[c][0];
        const int j = permutation[c][1];
        const int k = permutation[c][2];
        // pa
        {
            Vector3r term1(0,0,0);
            Vector3r term2(0,0,0);
            Vector3r tmp(0,0,0);
            // first term
            //dj::MulVecMatrix3x3<real>(db[k](), (real(*)[3]) &dajpi[j][0], term1());
            //dj::MulVecMatrix3x3<real>(db[j](), (real(*)[3]) &dajpi[k][0], tmp());

            //DOUBLE CHECK !!!
            term1 = dajpi[j][0].transpose() * db.col(k);
            tmp =   dajpi[k][0].transpose() * db.col(j);
            term1 = term1 - tmp;
            // second term
            for (int n = 0; n < 3; ++n)
            {
                //dj::MulVecMatrix3x3<real>(db[n](), (real(*)[3]) &dajpi[n][0], tmp());

                //DOUBLE CHECK !!!
                tmp = dajpi[n][0].transpose() * db.col(n);
                term2 = term2 + tmp;
            }
            omega_pa.col(i) = (term1)-(0.5f * darboux_vector[i] * length) * (term2);
            omega_pa.col(i) *= (x * bendAndTwistKs[i]);
        }
        // pb
        {
            Vector3r term1(0, 0, 0);
            Vector3r term2(0, 0, 0);
            Vector3r tmp(0, 0, 0);
            // first term
            //dj::MulVecMatrix3x3<real>(db[k](), (real(*)[3]) &dajpi[j][1], term1());
            //dj::MulVecMatrix3x3<real>(db[j](), (real(*)[3]) &dajpi[k][1], tmp());
            term1 = dajpi[j][1].transpose() * db.col(k);
            tmp =   dajpi[k][1].transpose() * db.col(j);
            term1 = term1 - tmp;
            // third term
            //dj::MulVecMatrix3x3<real>(da[k](), (real(*)[3]) &dbjpi[j][0], tmp());
            tmp = dbjpi[j][0].transpose() * da.col(k);
            term1 = term1 - tmp;

            //dj::MulVecMatrix3x3<real>(da[j](), (real(*)[3]) &dbjpi[k][0], tmp());
            tmp = dbjpi[k][0].transpose() * da.col(j);
            term1 = term1 + tmp;

            // second term
            for (int n = 0; n < 3; ++n)
            {
                //dj::MulVecMatrix3x3<real>(db[n](), (real(*)[3]) &dajpi[n][1], tmp());
                tmp = dajpi[n][1].transpose() * db.col(n);
                term2 = term2 + tmp;

                //dj::MulVecMatrix3x3<real>(da[n](), (real(*)[3]) &dbjpi[n][0], tmp());
                tmp = dbjpi[n][0].transpose() * da.col(n);
                term2 = term2 + tmp;
            }
            omega_pb.col(i) = (term1)-(0.5f * darboux_vector[i] * length) * (term2);
            omega_pb.col(i) *= (x * bendAndTwistKs[i]);
        }
        // pc
        {
            Vector3r term1(0, 0, 0);
            Vector3r term2(0, 0, 0);
            Vector3r tmp(0, 0, 0);

            // first term
            //dj::MulVecMatrix3x3<real>(da[k](), (real(*)[3]) &dbjpi[j][1], term1());
            //dj::MulVecMatrix3x3<real>(da[j](), (real(*)[3]) &dbjpi[k][1], tmp());
            term1 = dbjpi[j][1].transpose() * da.col(k);
            tmp =   dbjpi[k][1].transpose() * da.col(j);
            term1 = term1 - tmp;

            // second term
            for (int n = 0; n < 3; ++n)
            {
                //dj::MulVecMatrix3x3<real>(da[n](), (real(*)[3]) &dbjpi[n][1], tmp());
                tmp = dbjpi[n][1].transpose() * da.col(n);
                term2 = term2 + tmp;
            }
            omega_pc.col(i) = (term1)+(0.5f * darboux_vector[i] * length) * (term2);
            omega_pc.col(i) *= (-x * bendAndTwistKs[i]);
        }
        // pd
        {
            Vector3r term1(0, 0, 0);
            Vector3r term2(0, 0, 0);
            Vector3r tmp(0, 0, 0);
            // first term
            //dj::MulVecMatrix3x3<real>(db[k](), (real(*)[3]) &dajpi[j][2], term1());
            //dj::MulVecMatrix3x3<real>(db[j](), (real(*)[3]) &dajpi[k][2], tmp());
            term1 = dajpi[j][2].transpose() * db.col(k);
            tmp =   dajpi[k][2].transpose() * db.col(j);
            term1 = term1 - tmp;
            // second term
            for (int n = 0; n < 3; ++n) {
                //dj::MulVecMatrix3x3<real>(db[n](), (real(*)[3]) &dajpi[n][2], tmp());
                tmp = dajpi[n][2].transpose() * db.col(n);
                term2 = term2 + tmp;
            }
            omega_pd.col(i) = (term1)-(0.5f * darboux_vector[i] * length) * (term2);
            omega_pd.col(i) *= (x * bendAndTwistKs[i]);
        }
        // pe
        {
            Vector3r term1(0, 0, 0);
            Vector3r term2(0, 0, 0);
            Vector3r tmp(0, 0, 0);
            // first term

            //dj::MulVecMatrix3x3<real>(da[k](), (real(*)[3]) &dbjpi[j][2], term1());
            //dj::MulVecMatrix3x3<real>(da[j](), (real(*)[3]) &dbjpi[k][2], tmp());
            term1 = dbjpi[j][2].transpose() * da.col(k);
            tmp = dbjpi[k][2].transpose() * da.col(j);
            term1 -= tmp;

            // second term
            for (int n = 0; n < 3; ++n)
            {   //WARNING!!! &dbjpi[n][2][0][0] ???
                //dj::MulVecMatrix3x3<real>(da[n](), (real(*)[3]) &dbjpi[n][2][0][0], tmp());
                tmp = dbjpi[n][2].transpose() * da.col(n);
                term2 += tmp;
            }

            omega_pe.col(i) = (term1)+(0.5f * darboux_vector[i] * length) * (term2);
            omega_pe.col(i) *= (-x * bendAndTwistKs[i]);
        }
    }
    return true;
}
bool PositionBasedElasticRod::ComputeMaterialFrameDerivative(
    const Vector3r& p0, const Vector3r& p1, const Vector3r& p2, const Matrix3r& d,
    Matrix3r& d1p0, Matrix3r& d1p1, Matrix3r& d1p2,
    Matrix3r& d2p0, Matrix3r& d2p1, Matrix3r& d2p2,
    Matrix3r& d3p0, Matrix3r& d3p1, Matrix3r& d3p2)
{

    // d3pi
    Vector3r p01 = p1 - p0;
    float length_p01 = p01.norm();

    d3p0.col(0) = d.col(2)[0] * d.col(2);
    d3p0.col(1) = d.col(2)[1] * d.col(2);
    d3p0.col(2) = d.col(2)[2] * d.col(2);

    d3p0.col(0)[0] -= 1.0f;
    d3p0.col(1)[1] -= 1.0f;
    d3p0.col(2)[2] -= 1.0f;

    d3p0.col(0) *= (1.0f / length_p01);
    d3p0.col(1) *= (1.0f / length_p01);
    d3p0.col(2) *= (1.0f / length_p01);

    d3p1.col(0) = -d3p0.col(0);
    d3p1.col(1) = -d3p0.col(1);
    d3p1.col(2) = -d3p0.col(2);

    d3p2.col(0).setZero();
    d3p2.col(1).setZero();
    d3p2.col(2).setZero();

    ////>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    //// d2pi
    Vector3r p02 = p2 - p0;
    Vector3r p01_cross_p02 = p01.cross(p02);

    float length_cross = p01_cross_p02.norm();

    Matrix3r mat;
    mat.col(0) = d.col(1)[0] * d.col(1);
    mat.col(1) = d.col(1)[1] * d.col(1);
    mat.col(2) = d.col(1)[2] * d.col(1);

    mat.col(0)[0] -= 1.0f;
    mat.col(1)[1] -= 1.0f;
    mat.col(2)[2] -= 1.0f;

    mat.col(0) *= (-1.0f / length_cross);
    mat.col(1) *= (-1.0f / length_cross);
    mat.col(2) *= (-1.0f / length_cross);

    Matrix3r product_matrix;
    MathFunctions::crossProductMatrix(p2 - p1, product_matrix);
    d2p0 = mat * product_matrix;

    MathFunctions::crossProductMatrix(p0 - p2, product_matrix);
    d2p1 = mat * product_matrix;

    MathFunctions::crossProductMatrix(p1 - p0, product_matrix);
    d2p2 = mat * product_matrix;

    ////>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    //// d1pi
    Matrix3r product_mat_d3;
    Matrix3r product_mat_d2;
    Matrix3r m1, m2;

    MathFunctions::crossProductMatrix(d.col(2), product_mat_d3);
    MathFunctions::crossProductMatrix(d.col(1), product_mat_d2);

    //dj::MulMatrix3x3<real>(&product_mat_d3[0][0], &d2p0[0][0], &m1[0][0]);
    //dj::MulMatrix3x3<real>(&product_mat_d2[0][0], &d3p0[0][0], &m2[0][0]);
    d1p0 = product_mat_d2 * d3p0 - product_mat_d3 * d2p0;

    //dj::MulMatrix3x3<real>(&product_mat_d3[0][0], &d2p1[0][0], &m1[0][0]);
    //dj::MulMatrix3x3<real>(&product_mat_d2[0][0], &d3p1[0][0], &m2[0][0]);
    d1p1 = product_mat_d2 * d3p1 - product_mat_d3 * d2p1;

    /*dj::MulMatrix3x3<real>(&product_mat_d3[0][0], &d2p2[0][0], &d1p2[0][0]);*/
    d1p2 = product_mat_d3 * d2p2;
    d1p2.col(0) *= -1.0f;
    d1p2.col(1) *= -1.0f;
    d1p2.col(2) *= -1.0f;
    return true;
}