示例#1
0
float QuadDice::scale_factor(SubPatch& sub, EdgeFactors& ef, int Mu, int Mv)
{
	/* estimate area as 4x largest of 4 quads */
	float3 P[3][3];

	for(int i = 0; i < 3; i++)
		for(int j = 0; j < 3; j++)
			P[i][j] = eval_projected(sub, i*0.5f, j*0.5f);

	float A1 = quad_area(P[0][0], P[1][0], P[0][1], P[1][1]);
	float A2 = quad_area(P[1][0], P[2][0], P[1][1], P[2][1]);
	float A3 = quad_area(P[0][1], P[1][1], P[0][2], P[1][2]);
	float A4 = quad_area(P[1][1], P[2][1], P[1][2], P[2][2]);
	float Apatch = max(A1, max(A2, max(A3, A4)))*4.0f;

	/* solve for scaling factor */
	float Atri = dicing_rate*dicing_rate*0.5f;
	float Ntris = Apatch/Atri;

	// XXX does the -sqrt solution matter
	// XXX max(D, 0.0) is highly suspicious, need to test cases
	// where D goes negative
	float N = 0.5f*(Ntris - (ef.tu0 + ef.tu1 + ef.tv0 + ef.tv1));
	float D = 4.0f*N*Mu*Mv + (Mu + Mv)*(Mu + Mv);
	float S = (Mu + Mv + sqrtf(max(D, 0.0f)))/(2*Mu*Mv);

	return S;
}
void CThinshellElementFEM::_initElements(
	const CMeMaterialProperty &mtl, 
	const Vector3d &p0, const Vector3d &p1, const Vector3d &p2, 
	const Vector3d &p3, const Vector3d &p4, const Vector3d &p5, 
	const double& thickness)
{
	//compute volume for each triangle, each truss edge
	m_area0 = fabs(quad_area(p0, p1, p2, p3));
	m_area1 = fabs(quad_area(p0, p4, p5, p1));  //right hand rule
	m_thickness = thickness;

	//construct the world/local transform matrix for the two triangles
	double3x3 rot;
	Vector3d N0, N1;
	const Vector3d q1=p1-p0, q2=p2-p0, q3=p3-p0, q4=p4-p0, q5=p5-p0;
	getReferencePlanesForQuadPair(q1, q2, q3, q4, q5, N0, N1, rot, m_len0);
	const Vector3d qq1(m_len0, 0, 0);
	const Vector3d qq2 = rot*q2;
	const Vector3d qq3 = rot*q3;
	const Vector3d qq4 = rot*q4;
	const Vector3d qq5 = rot*q5;
	m_qq2 = qq2; m_qq3 = qq3;
	m_qq4 = qq4; m_qq5 = qq5;
	const double DELTA = m_len0*HEIGHT_DELTA;
	const Vector3d qq2u = rot*(q2+DELTA*N0);
	const Vector3d qq3u = rot*(q3+DELTA*N0);
	const Vector3d qq4u = rot*(q4+DELTA*N1);
	const Vector3d qq5u = rot*(q5+DELTA*N1);

	//derivitive pF/pX
	copyVectorsToColumns(qq1, qq2, qq2u, m_XInv0);
	copyVectorsToColumns(qq1, qq3, qq3u, m_XInv1);
	copyVectorsToColumns(qq1, qq4, qq4u, m_XInv2);
	copyVectorsToColumns(qq1, qq5, qq5u, m_XInv3);
	m_XInv0.Invert(); m_XInv1.Invert();
	m_XInv2.Invert(); m_XInv3.Invert();

	//stiffness
	const int NSTIFF=12;
	double3x3 jac[NSTIFF], *ppJacobian[NSTIFF];
	for (int i=0; i<NSTIFF; i++) ppJacobian[i]=&jac[i];
	const double E = mtl.getYoung()*m_thickness*0.5;
	computeStiffnessMat(m_XInv0, -E*m_area0, ppJacobian);
	computeStiffnessMat(m_XInv1, -E*m_area0, ppJacobian+3);
	computeStiffnessMat(m_XInv2, -E*m_area1, ppJacobian+6);
	computeStiffnessMat(m_XInv3, -E*m_area1, ppJacobian+9);
	double *pstiff = &m_stiffness[0].x;
	for (int i=0; i<NSTIFF; i++) pstiff[i]=jac[i].x[0];

	//m_strain0.ZeroMatrix();
	//m_strain1.ZeroMatrix();
}
示例#3
0
//==================================================
//-0.5 -0.5 -0.5
//0.5 -0.5 -0.5
//-0.5 0.5 -0.5
//0.5 0.5 -0.5
//-0.5 -0.5 0.5
//0.5 -0.5 0.5
//-0.5 0.5 0.5
//0.5 0.5 0.5
//element node seq: 1 2 4 3 5 6 8 7
//==================================================
void CHexshellElement::init(
	const CMeMaterialProperty& mtl, const int *nodeid, 
	const Vector3d &p0, const Vector3d &p1, const Vector3d &p2, const Vector3d &p3,
	const Vector3d &p4, const Vector3d &p5, const Vector3d &p6, const Vector3d &p7)
{
	for (int i=0; i<8; i++) m_nodeID[i]=nodeid[i];
	//total volume
	Vector3d v[8] = {p0, p1, p2, p3, p4, p5, p6, p7};
	Vector8i hexelm(0,1,2,3,4,5,6,7);
	const double vol = computeHexahedronVolume(v, hexelm);
	//total area
	const double a0 = fabs(quad_area(p0, p1, p2, p3));
	const double a1 = fabs(quad_area(p0, p1, p5, p4));
	const double a2 = fabs(quad_area(p1, p2, p6, p5));
	const double a3 = fabs(quad_area(p2, p3, p7, p6));
	const double a4 = fabs(quad_area(p3, p0, p4, p7));
	const double a5 = fabs(quad_area(p4, p5, p6, p7));
	const double sumarea = a0+a1+a2+a3+a4+a5;
	//
	const double th = vol/sumarea;
	_initElement(mtl, th, p0, p1, p2, p3, p4, p5, p6, p7);
}
void CThinshell2Element::init(const int isstatic, 
		const int nodeid,						//the center vertex id
		const Vector3d *p,						//vertex position buffer
		const Vector3d *wpnorm,					//weighted polygon normal array
		const int *surfpoly,					//buffer of the whole surface polygons
		const int nv_per_elm,					//number of vertices for each surface polygon
		const int *polyfanid,					//the polyfan around the center vertex, input IDs only
		const int n1RingPoly,					//valence of the center vertex, also length of poylfanid
		const double& thickness)
{
	double plyvolume[MAX_NODE_VALENCE+1], edgevolume[MAX_NODE_VALENCE+1];
	int i, k;

	m_n1RingPoly = n1RingPoly;
	m_nCenterID = nodeid;
	for (i=0; i<n1RingPoly; i++) m_n1RingPolyID[i]=polyfanid[i];

	//Find all the fan polygons, store in tri buffer
	set<int> nodeset; nodeset.clear();
	for (i=0; i<n1RingPoly; i++){
		const int plyid = polyfanid[i];
		const int *ppoly = &surfpoly[plyid*nv_per_elm];
		_searchNodeInPolygon(nodeid, ppoly, nv_per_elm, nodeset);
		if (nv_per_elm==3){
			Vector3i tri(ppoly[0], ppoly[1], ppoly[2]);
			plyvolume[i] = triangle_area(p[tri.x], p[tri.y], p[tri.z]);
		}
		else{
			ASSERT0(nv_per_elm==4);
			Vector4i tri(ppoly[0], ppoly[1], ppoly[2], ppoly[3]);
			plyvolume[i] = quad_area(p[tri.x], p[tri.y], p[tri.z], p[tri.w]);
		}
	}

	//use the fan polygons to find the truss vertices
	set<int>::iterator itr = nodeset.begin();
	k = 0;
	while(itr!=nodeset.end()){
		m_nNodeID[k] = *itr;
		itr++, k++;
	}
	m_nRod = k;
	assert(m_nRod>0);
	if (m_nRod>MAX_NODE_VALENCE){
		printf("ALERT: node valence buffer is too small, increase to %d!!\n", m_nRod);
		m_nRod = MAX_NODE_VALENCE;
	}

	//find truss edge volume
	for (i=0; i<m_n1RingPoly; i++) plyvolume[i]*= thickness/nv_per_elm;
	for (i=0; i<m_nRod; i++) edgevolume[i]=0;
	for (i=0; i<m_n1RingPoly; i++){
		const double vol = plyvolume[i];
		const int plyid = polyfanid[i];
		const int *ppoly = &surfpoly[plyid*nv_per_elm];
		for (int j=0; j<nv_per_elm; j++){
			const int id = ppoly[j];
			for (k=0; k<m_nRod; k++){ 
				if (m_nNodeID[k]==id) 
					break;
			}
			if (k<m_nRod)
				edgevolume[k]+=vol;
		}
	}

	_initShearElements(isstatic, p, wpnorm, edgevolume);
}
void CThinshellElementFEM::_initElements(
    const CMeMaterialProperty &mtl,
    const Vector3d &p0, const Vector3d &p1, const Vector3d &p2,
    const Vector3d &p3, const Vector3d &p4, const Vector3d &p5,
    const double& thickness)
{
    //compute volume for each triangle, each truss edge
    m_area0 = fabs(quad_area(p0, p1, p2, p3));
    m_area1 = fabs(quad_area(p0, p4, p5, p1));  //right hand rule
    m_thickness = thickness;

    //construct the world/local transform matrix for the two triangles
    double3x3 rot;
    Vector3d N0, N1;
    const Vector3d p00=(p0+p1)*0.5;
    const Vector3d q1=p1-p00, q2=p2-p00, q3=p3-p00, q4=p4-p00, q5=p5-p00;
    //const Vector3d q1=p1-p0, q2=p2-p0, q3=p3-p0, q4=p4-p0, q5=p5-p0;
    getReferencePlanesForQuadPair(q1, q2, q3, q4, q5, N0, N1, rot, m_len0);
    const Vector3d qq0(-m_len0, 0, 0);
    const Vector3d qq1(m_len0, 0, 0);
    const Vector3d qq2 = rot*q2;
    const Vector3d qq3 = rot*q3;
    const Vector3d qq4 = rot*q4;
    const Vector3d qq5 = rot*q5;
    m_qq2 = qq2;
    m_qq3 = qq3;
    m_qq4 = qq4;
    m_qq5 = qq5;
    const double DELTA = m_len0*HEIGHT_DELTA;
    const Vector3d qq2u = rot*(q2+DELTA*N0);
    const Vector3d qq3u = rot*(q3+DELTA*N0);
    const Vector3d qq4u = rot*(q4+DELTA*N1);
    const Vector3d qq5u = rot*(q5+DELTA*N1);

    //derivitive pF/pX
    Vector3d *derivA = (Vector3d *)(&m_XInv0.x[0]);
    Vector3d *derivB = (Vector3d *)(&m_XInv1.x[0]);
    computeQuadDeriv(qq0, qq1, qq2, qq3, qq2u, qq3u, derivA);
    computeQuadDeriv(qq1, qq1, qq4, qq5, qq4u, qq5u, derivB);

    //stiffness
    const int NSTIFFMAT=20;
    double3x3 jac[NSTIFFMAT], *ppJacobian[NSTIFFMAT];
    for (int i=0; i<NSTIFFMAT; i++) ppJacobian[i]=&jac[i];
    const double E = mtl.getYoung()*m_thickness;
    computeStiffnessMat(derivA, -E*m_area0, ppJacobian);
    computeStiffnessMat(derivB, -E*m_area1, ppJacobian+(NSTIFFMAT>>1));
    m_A11 = jac[0].x[0];
    m_A12 = jac[1].x[0];
    m_A13 = jac[2].x[0];
    m_A14 = jac[3].x[0];
    m_A22 = jac[4].x[0];
    m_A23 = jac[5].x[0];
    m_A24 = jac[6].x[0];
    m_A33 = jac[7].x[0];
    m_A34 = jac[8].x[0];
    m_A44 = jac[9].x[0];
    m_B11 = jac[10].x[0];
    m_B12 = jac[11].x[0];
    m_B13 = jac[12].x[0];
    m_B14 = jac[13].x[0];
    m_B22 = jac[14].x[0];
    m_B23 = jac[15].x[0];
    m_B24 = jac[16].x[0];
    m_B33 = jac[17].x[0];
    m_B34 = jac[18].x[0];
    m_B44 = jac[19].x[0];

    m_strain0.ZeroMatrix();
    m_strain1.ZeroMatrix();
}