예제 #1
0
void AxisViewportRect(ViewExp *vpt, const Matrix3 &tm, float length, Rect *rect)
	{
	Matrix3 tmn = tm;
	float zoom;
	IPoint3 wpt;
	Point3 pt;
	GraphicsWindow *gw = vpt->getGW();

	// Get width of viewport in world units:  --DS
	zoom = vpt->GetScreenScaleFactor(tmn.GetTrans())*ZFACT;
	
	tmn.Scale( Point3(zoom,zoom,zoom) );
	gw->setTransform( tmn );	
	pt = Point3(0.0f, 0.0f, 0.0f);
	gw->wTransPoint( &pt, &wpt );
	rect->left = rect->right  = wpt.x;
	rect->top  = rect->bottom = wpt.y;

	AxisRect( gw, Point3(length,0.0f,0.0f),rect );	
	AxisRect( gw, Point3(0.0f,length,0.0f),rect );	
	AxisRect( gw, Point3(0.0f,0.0f,length),rect );	

	rect->right  += 2;
	rect->bottom += 2;
	rect->left   -= 2;
	rect->top    -= 2;
	}
예제 #2
0
void ProtHelpObject::GetMat(TimeValue t, INode* inode, ViewExp& vpt, Matrix3& tm) 
{
   if ( ! vpt.IsAlive() )
	{
		tm.Zero();
		return;
	}
	 tm = inode->GetObjectTM(t);
   tm.NoScale();
   float scaleFactor = vpt.NonScalingObjectSize() * vpt.GetVPWorldWidth(tm.GetTrans()) / 360.0f;
   tm.Scale(Point3(scaleFactor,scaleFactor,scaleFactor));
}
void VRayCamera::getTM(TimeValue t, INode *node, ViewExp *vpt, Matrix3 &tm) {
  tm=node->GetObjectTM(t);

  AffineParts ap;
  decomp_affine(tm, &ap);
  tm.IdentityMatrix();
  tm.SetRotate(ap.q);
  tm.SetTrans(ap.t);

  float scaleFactor=vpt->NonScalingObjectSize()*vpt->GetVPWorldWidth(tm.GetTrans())/360.0f;
  tm.Scale(Point3(scaleFactor,scaleFactor,scaleFactor));
}
예제 #4
0
void SymmetryMod::MirrorTriObject (Mesh & mesh, int axis, Matrix3 & tm, Matrix3 & itm,  int normalMapChannel) {
	// Create scaling matrix for mirroring on selected axis:
	Point3 scale(1,1,1);
	scale[axis] = -1.0f;
	itm.Scale(scale,TRUE);

	// Hang on to a copy of the incoming face selection:
	BitArray inputFaceSel = mesh.faceSel;

	// Make the mirror copy of the entire mesh:
	int oldnumv = mesh.numVerts;
	int oldnumf = mesh.numFaces;

	int oldNumNormals = 0;
	if (normalMapChannel != INVALID_NORMALMAPCHANNEL)	
	{
		MeshMap& map = mesh.Map(normalMapChannel);
		oldNumNormals = map.vnum;
	}

	BitArray fset;
	fset.SetSize (oldnumf);
	fset.SetAll ();
	mesh.CloneFaces (fset);	// Clears selection on originals, sets it on new faces.

	// Transform the cloned vertices to their mirror images:
	for (int i=oldnumv; i<mesh.numVerts; i++) {
		mesh.verts[i] = (mesh.verts[i]*itm)*tm;
	}

	// Restore selection of input faces:
	for (int i=0; i<oldnumf; i++) mesh.faceSel.Set (i, inputFaceSel[i]);
	// Flip over new faces and select to match input:
	for (int i=oldnumf; i<mesh.numFaces; i++) {
		mesh.FlipNormal (i);
		mesh.faceSel.Set (i, inputFaceSel[i-oldnumf]);
	}

	//flip and specified normals/faces
	if (normalMapChannel != INVALID_NORMALMAPCHANNEL)	
	{
		MeshMap& map = mesh.Map(normalMapChannel);
		int numNormals = map.vnum;
		
		Matrix3 mirrorTM = itm*tm;		
		for (int i = oldNumNormals; i < numNormals; i++)
		{
			Point3 n = map.tv[i];
			n = VectorTransform(n,mirrorTM);
			map.tv[i] = n;
		}
	}
}
예제 #5
0
// Update Strains for this particle
// Velocities for all fields are present on the nodes
// matRef is the material and properties have been loaded, matFld is the material field
void MatPointAS::UpdateStrain(double strainTime,int secondPass,int np,void *props,int matFld)
{
	int i,numnds,nds[maxShapeNodes];
    double fn[maxShapeNodes],xDeriv[maxShapeNodes],yDeriv[maxShapeNodes],zDeriv[maxShapeNodes];
	Vector vel;
    Matrix3 dv;
	
	// don't need to zero zDeriv because always set in axisymmetric shape functions
    
	// find shape functions and derviatives
	const ElementBase *elemRef = theElements[ElemID()];
	elemRef->GetShapeGradients(&numnds,fn,nds,xDeriv,yDeriv,zDeriv,this);
    
    // Find strain rates at particle from current grid velocities
	//   and using the velocity field for that particle and each node and the right material
    // In axisymmetric x->r, y->z, and z->hoop
    for(i=1;i<=numnds;i++)
	{	vel=nd[nds[i]]->GetVelocity((short)vfld[i],matFld);
        dv += Matrix3(vel.x*xDeriv[i],vel.x*yDeriv[i],vel.y*xDeriv[i],vel.y*yDeriv[i],vel.x*zDeriv[i]);
    }
    
    // save velocity gradient (if needed for J integral calculation)
    SetVelocityGradient(dv(0,0),dv(1,0),dv(0,1),dv(1,0),secondPass);
    
    // convert to strain increments
    // e.g., now dvrr = dvr/dr * dt = d/dr(du/dt) * dt = d/dt(du/dr) * dt = du/dr)
    dv.Scale(strainTime);
    
	// find effective particle transport properties from grid results
	ResidualStrains res;
	res.dT = 0;
	res.dC = 0.;
	if(!ConductionTask::active)
	{	res.dT = pTemperature-pPreviousTemperature;
		pPreviousTemperature = pTemperature;
	}
	else
	{	for(i=1;i<=numnds;i++)
		res.dT += conduction->IncrementValueExtrap(nd[nds[i]],fn[i]);
		res.dT = conduction->GetDeltaValue(this,res.dT);
	}
	if(DiffusionTask::active)
	{	for(i=1;i<=numnds;i++)
		res.dC += diffusion->IncrementValueExtrap(nd[nds[i]],fn[i]);
		res.dC = diffusion->GetDeltaValue(this,res.dC);
	}
	
	// pass on to material class to handle
	PerformConstitutiveLaw(dv,strainTime,np,props,&res);
}
예제 #6
0
void SymmetryMod::MirrorPolyObject (MNMesh & mesh, int axis, Matrix3 & tm, Matrix3 & itm) {
	// Create scaling matrix for mirroring on selected axis:
	Point3 scale(1,1,1);
	scale[axis] = -1.0f;
	itm.Scale(scale,TRUE);

	// Make the mirror copy of the entire mesh:
	int oldnumv = mesh.numv;
	for (int i=0; i<mesh.numf; i++) mesh.f[i].SetFlag (MN_USER);
	mesh.CloneFaces (MN_USER, true);

	// Transform the vertices to their mirror images:
	for (int i=oldnumv; i<mesh.numv; i++) mesh.v[i].p = (itm*mesh.v[i].p)*tm;

	// Flip over faces, edges:
	mesh.FlipElementNormals (MN_USER);	// flag should now be set only on clones.

	DbgAssert (mesh.CheckAllData ());
}
예제 #7
0
void DrawAxis(ViewExp *vpt, const Matrix3 &tm, float length, BOOL screenSize)
	{
	Matrix3 tmn = tm;
	float zoom;

	// Get width of viewport in world units:  --DS
	zoom = vpt->GetScreenScaleFactor(tmn.GetTrans())*ZFACT;
	
	if (screenSize) {
		tmn.Scale( Point3(zoom,zoom,zoom) );
		}
	vpt->getGW()->setTransform( tmn );		

	Text( vpt, _T("x"), Point3(length,0.0f,0.0f) ); 
	DrawAnAxis( vpt, Point3(length,0.0f,0.0f) );	
	
	Text( vpt, _T("y"), Point3(0.0f,length,0.0f) ); 
	DrawAnAxis( vpt, Point3(0.0f,length,0.0f) );	
	
	Text( vpt, _T("z"), Point3(0.0f,0.0f,length) ); 
	DrawAnAxis( vpt, Point3(0.0f,0.0f,length) );
	}
예제 #8
0
bool Exporter::splitMesh(INode *node, Mesh& mesh, FaceGroups &grps, TimeValue t, vector<Color4>& vertColors, bool noSplit)
{
	Mtl* nodeMtl = node->GetMtl();
	Matrix3 tm = node->GetObjTMAfterWSM(t);

	// Order of the vertices. Get 'em counter clockwise if the objects is
	// negatively scaled.
	int vi[3];
	if (TMNegParity(tm)) {
		vi[0] = 2; vi[1] = 1; vi[2] = 0;
	} else {
		vi[0] = 0; vi[1] = 1; vi[2] = 2;
	}

	Matrix3 flip;
	flip.IdentityMatrix();
	flip.Scale(Point3(1, -1, 1));

   int nv = mesh.getNumVerts();
   int nf = mesh.getNumFaces();

	if (noSplit)
	{
		int nv = mesh.getNumVerts();
		int nf = mesh.getNumFaces();
		// Dont split the mesh at all.  For debugging purposes.
		FaceGroup& grp = grps[0];
		grp.vidx.resize(nv, -1);
		grp.verts.resize(nv);
		grp.faces.resize(nf);
		grp.uvs.resize(nv);
		grp.vnorms.resize(nv);
      grp.fidx.resize(nf);

		Matrix3 texm;
		getTextureMatrix(texm, getMaterial(node, 0));
		texm *= flip;

		for (int face=0; face<nf; ++face) {
         grp.fidx[face] = face;
			for (int vi=0; vi<3; ++vi) {
				int idx = mesh.faces[face].getVert(vi);
				grp.faces[face][vi] = idx;

				// Calculate normal
				Point3 norm;
#if VERSION_3DSMAX <= ((5000<<16)+(15<<8)+0) // Version 5
				norm = getVertexNormal(&mesh, face, mesh.getRVertPtr(idx));
#else
				MeshNormalSpec *specNorms = mesh.GetSpecifiedNormals ();
				if (NULL != specNorms && specNorms->GetNumNormals() != 0)
					norm = specNorms->GetNormal(face, vi);
				else
					norm = getVertexNormal(&mesh, face, mesh.getRVertPtr(idx));
#endif
				Point3 uv;
				if (mesh.tVerts && mesh.tvFace) {
					uv = mesh.tVerts[ mesh.tvFace[ face ].t[ vi ]] * texm;
					uv.y += 1.0f;
				}

				if (grp.vidx[idx] == idx){
					ASSERT(grp.verts[idx] == TOVECTOR3(mesh.getVert(idx)));
					//ASSERT(vg.norm == norm);
					//Point3 uv = mesh.getTVert(idx);
					//if (mesh.getNumTVerts() > 0)
					//{
					//	ASSERT(grp.uvs[idx].u == uv.x && grp.uvs[idx].v == uv.y);
					//}
				} else {
					grp.vidx[idx] = idx;
					grp.verts[idx] = TOVECTOR3(mesh.getVert(idx));
					//grp.uvs[idx].u = uv.x;
					//grp.uvs[idx].v = uv.y;
					grp.vnorms[idx] = TOVECTOR3(norm);
				}
			}
		}
		for (int i=0; i<nv; ++i) {
			ASSERT(grp.vidx[i] != -1);
		}
	}
	else
	{
		int face, numSubMtls = nodeMtl?nodeMtl->NumSubMtls():0;
		for (face=0; face<mesh.getNumFaces(); face++) 
		{
			int mtlID = (numSubMtls!=0) ? (mesh.faces[face].getMatID() % numSubMtls) : 0;
         Mtl *mtl = getMaterial(node, mtlID);
			Matrix3 texm;
			getTextureMatrix(texm, mtl);
			texm *= flip;

         FaceGroup& grp = grps[mtlID];

		 if (grp.uvMapping.size() == 0) // Only needs to be done once per face group
		 {
			 int nmaps = 0;
			 int nmapsStart = max(1, mesh.getNumMaps() - (mesh.mapSupport(0) ? 1 : 0)); // Omit vertex color map.
			 for (int ii = 1; ii <= nmapsStart; ii++) // Winnow out the unsupported maps.
			 {
				 if (!mesh.mapSupport(ii)) continue;
				 grp.uvMapping[ii] = nmaps++;
			 }
			 grp.uvs.resize(nmaps == 0 ? 1 : nmaps);
		 }
         if (nv > int(grp.verts.capacity()))
         {
            grp.vgrp.reserve(nv);
            grp.verts.reserve(nv);
            grp.vnorms.reserve(nv);
            for (int i=0; i<grp.uvs.size(); ++i)
               grp.uvs[i].reserve(nv);
            grp.vcolors.reserve(nv);
            grp.vidx.reserve(nv);
         }
         if (nf > int(grp.faces.capacity()))
         {
            grp.faces.reserve(nf);
            grp.fidx.reserve(nf);
         }

         Triangle tri;
         for (int i=0; i<3; i++)
            tri[i] = addVertex(grp, face, vi[i], &mesh, texm, vertColors);
         grp.faces.push_back(tri);

         if (grp.fidx.size() < nf)
            grp.fidx.resize(nf,-1);
         grp.fidx[face] = grp.faces.size() - 1;
		}
	}

	return true;
}
예제 #9
0
// Apply Constitutive law, check np to know what type
void TaitLiquid::MPMConstitutiveLaw(MPMBase *mptr,Matrix3 du,double delTime,int np,void *properties,
									ResidualStrains *res,int historyOffset) const
{
#ifdef NO_SHEAR_MODEL
    // get incremental deformation gradient
	const Matrix3 dF = du.Exponential(incrementalDefGradTerms);
    
    // decompose dF into dR and dU
    Matrix3 dR;
    Matrix3 dU = dF.RightDecompose(&dR,NULL);
	
	// current deformation gradient
    double detdF = dF.determinant();
	Matrix3 pF = mptr->GetDeformationGradientMatrix();
    Matrix3 F = dR*pF;
    if(np==THREED_MPM)
        F.Scale(pow(detdF,1./3.));
    else
        F.Scale2D(sqrt(detdF));
	
	// new deformation matrix with volume change onle
    mptr->SetDeformationGradientMatrix(F);

#else
#ifdef ELASTIC_B_MODEL
    // get incremental deformation gradient
	const Matrix3 dF = du.Exponential(incrementalDefGradTerms);
	double detdF = dF.determinant();
	
	// current deformation gradient
	Matrix3 pF = mptr->GetDeformationGradientMatrix();
	
	// new deformation matrix
	const Matrix3 F = dF*pF;
    mptr->SetDeformationGradientMatrix(F);
#else

	// Update total deformation gradient, and calculate trial B
	double detdF = IncrementDeformation(mptr,du,NULL,np);
#endif
#endif
    
    // Get new J and save result on the particle
	double J = detdF * mptr->GetHistoryDble(J_History,historyOffset);
    mptr->SetHistoryDble(J_History,J,historyOffset);

#ifdef ELASTIC_B_MODEL
	// store pressure strain as elastic B
    Tensor *pB = mptr->GetAltStrainTensor() ;
    if(np==THREED_MPM || np==AXISYMMETRIC_MPM)
	{	double J23 = pow(J,2./3.);
		pB->xx = J23;
		pB->yy = J23;
		pB->zz = J23;
	}
	else
	{	pB->xx = J;
		pB->yy = J;
	}
#endif
    
    // account for residual stresses
	double dJres = GetIncrementalResJ(mptr,res);
	double Jres = dJres * mptr->GetHistoryDble(J_History+1,historyOffset);
	mptr->SetHistoryDble(J_History+1,Jres,historyOffset);
    double Jeff = J/Jres;

    // new Kirchhoff pressure (over rho0) from Tait equation
	double p0=mptr->GetPressure();
    double pressure = J*TAIT_C*Ksp*(exp((1.-Jeff)/TAIT_C)-1.);
    mptr->SetPressure(pressure);
    
	// incremental energy per unit mass - dilational part
    double avgP = 0.5*(p0+pressure);
    double delV = 1. - 1./detdF;
    double workEnergy = -avgP*delV;
    
	// incremental residual energy per unit mass
	double delVres = 1. - 1./dJres;
	double resEnergy = -avgP*delVres;
	
    // viscosity term = 2 eta (0.5(grad v) + 0.5*(grad V)^T - (1/3) tr(grad v) I) = 2 eta dev(grad v)
    // (i.e., deviatoric part of the symmetric strain tensor, 2 is for conversion to engineering shear strain)
	// simple shear rate = |2 dev(grad v)|
    Matrix3 shear;
    double c[3][3];
	double shearRate;
    c[0][0] = (2.*du(0,0)-du(1,1)-du(2,2))/3.;
    c[1][1] = (2.*du(1,1)-du(0,0)-du(2,2))/3.;
    c[2][2] = (2.*du(2,2)-du(0,0)-du(1,1))/3.;
    c[0][1] = 0.5*(du(0,1)+du(1,0));
    c[1][0] = c[0][1];
	shearRate = c[0][0]*c[0][0] + c[1][1]*c[1][1] + c[2][2]*c[2][2]
	+ 2.*c[0][1]*c[0][1];
    if(np==THREED_MPM)
    {   c[0][2] = 0.5*(du(0,2)+du(2,0));
        c[2][0] = c[0][2];
        c[1][2] = 0.5*(du(1,2)+du(2,1));
        c[2][1] = c[1][2];
		shearRate += 2.*(c[0][2]*c[0][2] + c[1][2]*c[1][2]);
        shear.set(c);
    }
    else
        shear.set(c[0][0],c[0][1],c[1][0],c[1][1],c[2][2]);
	shearRate = 2.*sqrt(shearRate)/delTime;
	
	// Store shear rate
	mptr->SetHistoryDble(J_History+2,shearRate,historyOffset);
	
	// Get effective visocisy
	double twoetaspRate = 0.;
	if(numViscosity==1)
	{	twoetaspRate = TwoEtasp[0];
	}
	else
	{	shearRate = log10(shearRate);
		if(shearRate < logShearRate[0])
			twoetaspRate = TwoEtasp[0];
		else if(shearRate > logShearRate[numViscosity-1])
			twoetaspRate = TwoEtasp[numViscosity-1];
		else
		{	// interpolate
			for(int i=1;i<numViscosity;i++)
			{	if(shearRate <= logShearRate[i])
				{	// between i-1 and i
					double fract = (logShearRate[i]-shearRate)/(logShearRate[i]-logShearRate[i-1]);
					twoetaspRate = fract*TwoEtasp[i-1] + (1.-fract)*TwoEtasp[i];
					break;
				}
			}
		}
	}
    
    // Get Kirchoff shear stress (over rho0)
    shear.Scale(J*twoetaspRate/delTime);
    
    // update deviatoric stress
	Tensor *sp=mptr->GetStressTensor();
    sp->xx = shear(0,0);
    sp->yy = shear(1,1);
    sp->zz = shear(2,2);
    sp->xy = shear(0,1);
    if(np==THREED_MPM)
    {   sp->xz = shear(0,2);
        sp->yz = shear(1,2);
    }
    
    // shear work per unit mass = tau.du = tau.tau*delTime/twoetaspRate
    double shearWork = sp->xx*sp->xx + sp->yy*sp->yy + sp->zz*sp->zz + 2.*sp->xy*sp->xy;
    if(np==THREED_MPM) shearWork += 2.*(sp->xz*sp->xz + sp->yz*sp->yz);
    shearWork *= delTime/twoetaspRate;
    mptr->AddWorkEnergyAndResidualEnergy(workEnergy+shearWork,resEnergy);
    
    // particle isentropic temperature increment dT/T = - J (K/K0) gamma0 Delta(V)/V
    // Delta(V)/V = 1. - 1/detdF (total volume)
	double Kratio = Jeff*(1.+pressure/(TAIT_C*Ksp));
	double dTq0 = -J*Kratio*gamma0*mptr->pPreviousTemperature*delV;
    
    // heat energy is Cv (dT - dTq0) -dPhi
	// Here do Cv (dT - dTq0)
    // dPhi = shearWork is lost due to shear term
    IncrementHeatEnergy(mptr,res->dT,dTq0,shearWork);
}
예제 #10
0
void TorusObject::BuildMesh(TimeValue t)
	{
	Point3 p;
	int ix,na,nb,nc,nd,jx,kx;
	int nf=0,nv=0;
	float delta,ang;
	float delta2,ang2;
	int sides,segs,smooth;
	float radius,radius2, rotation;
	float sinang,cosang, sinang2,cosang2,rt;
	float twist, pie1, pie2, totalPie, startAng = 0.0f;
	int doPie  = TRUE;	
	int genUVs = TRUE;	

	// Start the validity interval at forever and widdle it down.
	ivalid = FOREVER;	
	pblock->GetValue(PB_RADIUS,t,radius,ivalid);
	pblock->GetValue(PB_RADIUS2,t,radius2,ivalid);
	pblock->GetValue(PB_ROTATION,t,rotation,ivalid);
	pblock->GetValue(PB_TWIST,t,twist,ivalid);
	pblock->GetValue(PB_SEGMENTS,t,segs,ivalid);
	pblock->GetValue(PB_SIDES,t,sides,ivalid);
	pblock->GetValue(PB_SMOOTH,t,smooth,ivalid);
	pblock->GetValue(PB_PIESLICE1,t,pie1,ivalid);
	pblock->GetValue(PB_PIESLICE2,t,pie2,ivalid);	
	pblock->GetValue(PB_SLICEON,t,doPie,ivalid);
	pblock->GetValue(PB_GENUVS,t,genUVs,ivalid);
	LimitValue( radius, MIN_RADIUS, MAX_RADIUS );
	LimitValue( radius2, MIN_RADIUS, MAX_RADIUS );
	LimitValue( segs, MIN_SEGMENTS, MAX_SEGMENTS );
	LimitValue( sides, MIN_SIDES, MAX_SIDES );	

    // Convert doPie to a 0 or 1 value since it is used in arithmetic below
    // Controllers can give it non- 0 or 1 values
    doPie = doPie ? 1 : 0;

	// We do the torus backwards from the cylinder
	pie1 = -pie1;
	pie2 = -pie2;

	// Make pie2 < pie1 and pie1-pie2 < TWOPI
	while (pie1 < pie2) pie1 += TWOPI;
	while (pie1 > pie2+TWOPI) pie1 -= TWOPI;
	if (pie1==pie2) totalPie = TWOPI;
	else totalPie = pie1-pie2;	
	
	if (doPie) {
		segs++; //*** O.Z. fix for bug 240436 
		delta    = totalPie/(float)(segs-1);
		startAng = pie2;
	} else {
		delta = (float)2.0*PI/(float)segs;
		}
	
	delta2 = (float)2.0*PI/(float)sides;
	
	if (TestAFlag(A_PLUGIN1)) startAng -= HALFPI;

	int nverts;
	int nfaces;
	if (doPie) {
		nverts = sides*segs + 2;
		nfaces = 2*sides*segs;
	} else {
		nverts = sides*segs;
		nfaces = 2*sides*segs;
		}
	mesh.setNumVerts(nverts);
	mesh.setNumFaces(nfaces);
	mesh.setSmoothFlags(smooth);
	if (genUVs) {
		if (doPie) {
			mesh.setNumTVerts((sides+1)*segs+2);
			mesh.setNumTVFaces(2*sides*segs);
		} else {
			mesh.setNumTVerts((sides+1)*(segs+1));
			mesh.setNumTVFaces(2*sides*segs);
			}
	} else {
		mesh.setNumTVerts(0);
		mesh.setNumTVFaces(0);
		}

	ang = startAng;

	// make verts
	for(ix=0; ix<segs; ix++) {
		sinang = (float)sin(ang);
		cosang = (float)cos(ang);
		ang2 = rotation + twist * float(ix+1)/float(segs);
		for (jx = 0; jx<sides; jx++) {
			sinang2 = (float)sin(ang2);
			cosang2 = (float)cos(ang2);
			rt = radius+radius2*cosang2;
			p.x = rt*cosang;
			p.y = -rt*sinang;
			p.z = radius2*sinang2;	
			mesh.setVert(nv++, p);
			ang2 += delta2;
			}	
		ang += delta;
		}
	
	if (doPie) {
		p.x = radius * (float)cos(startAng);
		p.y = -radius * (float)sin(startAng);
		p.z = 0.0f;
		mesh.setVert(nv++, p);

		ang -= delta;
		p.x = radius * (float)cos(ang);
		p.y = -radius * (float)sin(ang);
		p.z = 0.0f;
		mesh.setVert(nv++, p);
		}
	
	// Make faces

    BOOL usePhysUVs = GetUsePhysicalScaleUVs();
    BitArray startSliceFaces;
    BitArray endSliceFaces;

    if (usePhysUVs) {
        startSliceFaces.SetSize(mesh.numFaces);
        endSliceFaces.SetSize(mesh.numFaces);
    }

	/* Make midsection */
	for(ix=0; ix<segs-doPie; ++ix) {
		jx=ix*sides;
		for (kx=0; kx<sides; ++kx) {
			na = jx+kx;
			nb = (ix==(segs-1))?kx:na+sides;
			nd = (kx==(sides-1))? jx : na+1;
			nc = nb+nd-na;

			DWORD grp = 0;
			if (smooth==SMOOTH_SIDES) {
				if (kx==sides-1 && (sides&1)) {
					grp = (1<<2);
				} else {
					grp = (kx&1) ? (1<<0) : (1<<1);
					}
			} else 
			if (smooth==SMOOTH_STRIPES) {
				if (ix==segs-1 && (segs&1)) {
					grp = (1<<2);
				} else {
					grp = (ix&1) ? (1<<0) : (1<<1);
					}
			} else 
			if (smooth > 0) {
				grp = 1;
				}

			mesh.faces[nf].setEdgeVisFlags(0,1,1);
			mesh.faces[nf].setSmGroup(grp);
			mesh.faces[nf].setMatID(0);
			mesh.faces[nf++].setVerts( na,nc,nb);

			mesh.faces[nf].setEdgeVisFlags(1,1,0);
			mesh.faces[nf].setSmGroup(grp);
			mesh.faces[nf].setMatID(0);
			mesh.faces[nf++].setVerts(na,nd,nc);
			}
	 	}

	if (doPie) {		
		na = nv -2;
		for(ix=0; ix<sides; ++ix) {
			nb = ix;
			nc = (ix==(sides-1))?0:ix+1;
			mesh.faces[nf].setEdgeVisFlags(0,1,0);
			mesh.faces[nf].setSmGroup((1<<3));
			mesh.faces[nf].setMatID(1);
            if (usePhysUVs)
                startSliceFaces.Set(nf);
			mesh.faces[nf++].setVerts(na,nc,nb);
			}
		
		na = nv -1;
		jx = sides*(segs-1);
		for(ix=0; ix<sides; ++ix) {
			nb = jx+ix;
			nc = (ix==(sides-1))?jx:nb+1;
			mesh.faces[nf].setEdgeVisFlags(0,1,0);
			mesh.faces[nf].setSmGroup((1<<3));
			mesh.faces[nf].setMatID(2);
            if (usePhysUVs)
                endSliceFaces.Set(nf);
			mesh.faces[nf++].setVerts(na,nb,nc);
			}
		}

	
	// UVWs -------------------
	
	if (genUVs) {
        float uScale = usePhysUVs ? ((float) 2.0f * PI * radius) : 1.0f;
        float vScale = usePhysUVs ? ((float) 2.0f * PI * radius2) : 1.0f;
        if (doPie) {
            float pieScale = float(totalPie/(2.0*PI));
            uScale *= float(pieScale);
        }

		nv=0;
		for(ix=0; ix<=segs-doPie; ix++) {
			for (jx=0; jx<=sides; jx++) {
                if (usePhysUVs)
                    mesh.setTVert(nv++,uScale*(1.0f - float(ix)/float(segs-doPie)),vScale*float(jx)/float(sides),0.0f);
                else
				mesh.setTVert(nv++,float(jx)/float(sides),float(ix)/float(segs),0.0f);
				}
			}
		int pie1 = 0;
		int pie2 = 0;
		if (doPie) {
			pie1 = nv;
            if (usePhysUVs)
                mesh.setTVert(nv++,0.0f,vScale*0.5f,0.0f);
            else
			mesh.setTVert(nv++,0.5f,1.0f,0.0f);
			pie2 = nv;
            if (usePhysUVs)
                mesh.setTVert(nv++,uScale*0.5f,vScale*0.0f,0.0f);
            else
                mesh.setTVert(nv++,1.0f,0.5f,0.0f);
			}				
		
		nf=0;
		for(ix=0; ix<segs-doPie; ix++) {
			na = ix*(sides+1);
			nb = (ix+1)*(sides+1);
			for (jx=0; jx<sides; jx++) {
				mesh.tvFace[nf++].setTVerts(na,nb+1,nb);
				mesh.tvFace[nf++].setTVerts(na,na+1,nb+1);
				na++;
				nb++;
				}
			}
		if (doPie) {						
            if (usePhysUVs) {
                Matrix3 tm = RotateZMatrix(startAng) * RotateXMatrix(float(-PI/2.0));
                tm.Scale(Point3(-1.0f, 1.0f, 1.0f));
                MakeMeshCapTexture(mesh, tm, startSliceFaces, usePhysUVs);
                tm = RotateZMatrix(ang) * RotateXMatrix(float(-PI/2.0));
                MakeMeshCapTexture(mesh, tm, endSliceFaces, usePhysUVs);
            } else {
			for (jx=0; jx<sides; jx++) {
				mesh.tvFace[nf++].setTVerts(pie1,jx+1,jx);				
				}			
			nb = (sides+1)*(segs-1);
			for (jx=0; jx<sides; jx++) {
				mesh.tvFace[nf++].setTVerts(pie2,nb,nb+1);
				nb++;
				}
			}
		}
		}

	mesh.InvalidateTopologyCache();
	}
예제 #11
0
Object*
BuildNURBSPyramid(float width, float depth, float height, int genUVs)
{
	int pyramid_faces[5][4] = { {0, 1, 2, 3}, // bottom
							{2, 3, 4, 4}, // back
							{1, 0, 4, 4}, // front
							{3, 1, 4, 4}, // left
							{0, 2, 4, 4}};// right
	Point3 pyramid_verts[5] = { Point3(-0.5, -0.5, 0.0),
							Point3( 0.5, -0.5, 0.0),
							Point3(-0.5,  0.5, 0.0),
							Point3( 0.5,  0.5, 0.0),
							Point3( 0.0,  0.0, 1.0)};

	NURBSSet nset;

	for (int face = 0; face < 5; face++) {
		Point3 bl = pyramid_verts[pyramid_faces[face][0]];
		Point3 br = pyramid_verts[pyramid_faces[face][1]];
		Point3 tl = pyramid_verts[pyramid_faces[face][2]];
		Point3 tr = pyramid_verts[pyramid_faces[face][3]];

		Matrix3 size;
		size.IdentityMatrix();
		Point3 lwh(width, depth, height);
		size.Scale(lwh);

		bl = bl * size;
		br = br * size;
		tl = tl * size;
		tr = tr * size;

		NURBSCVSurface *surf = new NURBSCVSurface();
		nset.AppendObject(surf);
		surf->SetUOrder(4);
		surf->SetVOrder(4);
		surf->SetNumCVs(4, 4);
		surf->SetNumUKnots(8);
		surf->SetNumVKnots(8);

		Point3 top, bot;
		for (int r = 0; r < 4; r++) {
			top = tl + (((float)r/3.0f) * (tr - tl));
			bot = bl + (((float)r/3.0f) * (br - bl));
			for (int c = 0; c < 4; c++) {
				NURBSControlVertex ncv;
				ncv.SetPosition(0, bot + (((float)c/3.0f) * (top - bot)));
				ncv.SetWeight(0, 1.0f);
				surf->SetCV(r, c, ncv);
			}
		}

		for (int k = 0; k < 4; k++) {
			surf->SetUKnot(k, 0.0);
			surf->SetVKnot(k, 0.0);
			surf->SetUKnot(k + 4, 1.0);
			surf->SetVKnot(k + 4, 1.0);
		}

		surf->Renderable(TRUE);
		surf->SetGenerateUVs(genUVs);
		if (height > 0.0f)
			surf->FlipNormals(TRUE);
		else
			surf->FlipNormals(FALSE);

		switch(face) {
		case 0: // bottom
			surf->SetTextureUVs(0, 0, Point2(1.0f, 0.0f));
			surf->SetTextureUVs(0, 1, Point2(0.0f, 0.0f));
			surf->SetTextureUVs(0, 2, Point2(1.0f, 1.0f));
			surf->SetTextureUVs(0, 3, Point2(0.0f, 1.0f));
			break;
		default: // sides
			surf->SetTextureUVs(0, 0, Point2(0.5f, 1.0f));
			surf->SetTextureUVs(0, 1, Point2(0.5f, 1.0f));
			surf->SetTextureUVs(0, 2, Point2(0.0f, 0.0f));
			surf->SetTextureUVs(0, 3, Point2(1.0f, 0.0f));
			break;
		}

		TCHAR bname[80];
		_stprintf(bname, _T("%s%02d"), GetString(IDS_CT_SURF), face);
		surf->SetName(bname);
	}

#define F(s1, s2, s1r, s1c, s2r, s2c) \
	fuse.mSurf1 = (s1); \
	fuse.mSurf2 = (s2); \
	fuse.mRow1 = (s1r); \
	fuse.mCol1 = (s1c); \
	fuse.mRow2 = (s2r); \
	fuse.mCol2 = (s2c); \
	nset.mSurfFuse.Append(1, &fuse);

	NURBSFuseSurfaceCV fuse;
	// Fuse the degenerate peaks
	for (int i = 1; i < 5; i++) {
		for (int j = 1; j < 4; j++) {
			F(i, i, 0, 3, j, 3);
		}
	}

	// Fuse the peaks together
	F(1, 2, 0, 3, 0, 3);
	F(1, 3, 0, 3, 0, 3);
	F(1, 4, 0, 3, 0, 3);

	// Bottom(0) to Back (1)
	F(0, 1, 3, 3, 3, 0);
	F(0, 1, 2, 3, 2, 0);
	F(0, 1, 1, 3, 1, 0);
	F(0, 1, 0, 3, 0, 0);

	// Bottom(0) to Front (2)
	F(0, 2, 0, 0, 3, 0);
	F(0, 2, 1, 0, 2, 0);
	F(0, 2, 2, 0, 1, 0);
	F(0, 2, 3, 0, 0, 0);

	// Bottom(0) to Left (3)
	F(0, 3, 3, 0, 3, 0);
	F(0, 3, 3, 1, 2, 0);
	F(0, 3, 3, 2, 1, 0);
	F(0, 3, 3, 3, 0, 0);

	// Bottom(0) to Right (4)
	F(0, 4, 0, 0, 0, 0);
	F(0, 4, 0, 1, 1, 0);
	F(0, 4, 0, 2, 2, 0);
	F(0, 4, 0, 3, 3, 0);

	// Front (2)  to Right (4)
	F(2, 4, 3, 1, 0, 1);
	F(2, 4, 3, 2, 0, 2);

	// Right (4) to Back (1)
	F(4, 1, 3, 1, 0, 1);
	F(4, 1, 3, 2, 0, 2);

	// Back (1) to Left (3)
	F(1, 3, 3, 1, 0, 1);
	F(1, 3, 3, 2, 0, 2);

	// Left (3) to Front (2)
	F(3, 2, 3, 1, 0, 1);
	F(3, 2, 3, 2, 0, 2);

	Matrix3 mat;
	mat.IdentityMatrix();
	Object *obj = CreateNURBSObject(NULL, &nset, mat);
	return obj;
}
예제 #12
0
// Apply Constitutive law, check np to know what type
void TaitLiquid::MPMConstitutiveLaw(MPMBase *mptr,Matrix3 du,double delTime,int np,void *properties,ResidualStrains *res) const
{
#ifdef NO_SHEAR_MODEL
    // get incremental deformation gradient
	const Matrix3 dF = du.Exponential(incrementalDefGradTerms);
    
    // decompose dF into dR and dU
    Matrix3 dR;
    Matrix3 dU = dF.RightDecompose(&dR,NULL);
	
	// current deformation gradient
    double detdF = dF.determinant();
	Matrix3 pF = mptr->GetDeformationGradientMatrix();
    Matrix3 F = dR*pF;
    if(np==THREED_MPM)
        F.Scale(pow(detdF,1./3.));
    else
        F.Scale2D(sqrt(detdF));
	
	// new deformation matrix with volume change onle
    mptr->SetDeformationGradientMatrix(F);
#else

	// Update total deformation gradient, and calculate trial B
	double detdF = IncrementDeformation(mptr,du,NULL,np);
#endif
    
    // Get new J and save result on the particle
	double J = detdF * mptr->GetHistoryDble(J_history);
    mptr->SetHistoryDble(J_history,J);
    
    // account for residual stresses
	double dresStretch,resStretch = GetResidualStretch(mptr,dresStretch,res);
	double Jres = resStretch*resStretch*resStretch;
    double Jeff = J/Jres;

    // new Kirchhoff pressure (over rho0) from Tait equation
	double p0=mptr->GetPressure();
    double pressure = J*TAIT_C*Ksp*(exp((1.-Jeff)/TAIT_C)-1.);
    mptr->SetPressure(pressure);
    
	// incremental energy per unit mass - dilational part
    double avgP = 0.5*(p0+pressure);
    double delV = 1. - 1./detdF;
    double workEnergy = -avgP*delV;
    
	// incremental residual energy per unit mass
	double delVres = 1. - 1./(dresStretch*dresStretch*dresStretch);
	double resEnergy = -avgP*delVres;
	
    // viscosity term = 2 eta (0.5(grad v) + 0.5*(grad V)^T - (1/3) tr(grad v) I)
    // (i.e., divatoric part of the symmetric strain tensor, 2 is for conversion to engineering shear strain)
    Matrix3 shear;
    double c[3][3];
    c[0][0] = (2.*du(0,0)-du(1,1)-du(2,2))/3.;
    c[1][1] = (2.*du(1,1)-du(0,0)-du(2,2))/3.;
    c[2][2] = (2.*du(2,2)-du(0,0)-du(1,1))/3.;
    c[0][1] = 0.5*(du(0,1)+du(1,0));
    c[1][0] = c[0][1];
    if(np==THREED_MPM)
    {   c[0][2] = 0.5*(du(0,2)+du(2,0));
        c[2][0] = c[0][2];
        c[1][2] = 0.5*(du(1,2)+du(2,1));
        c[2][1] = c[1][2];
        shear.set(c);
    }
    else
        shear.set(c[0][0],c[0][1],c[1][0],c[1][1],c[2][2]);
    
    // Get Kirchoff shear stress (over rho0)
    shear.Scale(J*TwoEtasp/delTime);
    
    // update deviatoric stress
	Tensor *sp=mptr->GetStressTensor();
    sp->xx = shear(0,0);
    sp->yy = shear(1,1);
    sp->zz = shear(2,2);
    sp->xy = shear(0,1);
    if(np==THREED_MPM)
    {   sp->xz = shear(0,2);
        sp->yz = shear(1,2);
    }
    
    // shear work per unit mass = tau.du = tau.tau*delTime/TwoEtasp
    double shearWork = sp->xx*sp->xx + sp->yy*sp->yy + sp->zz*sp->zz + 2.*sp->xy*sp->xy;
    if(np==THREED_MPM) shearWork += 2.*(sp->xz*sp->xz + sp->yz*sp->yz);
    shearWork *= delTime/TwoEtasp;
    mptr->AddWorkEnergyAndResidualEnergy(workEnergy+shearWork,resEnergy);
    
    // particle isentropic temperature increment dT/T = - J (K/K0) gamma0 Delta(V)/V
    // Delta(V)/V = 1. - 1/detdF (total volume)
	double Kratio = Jeff*(1.+pressure/(TAIT_C*Ksp));
	double dTq0 = -J*Kratio*gamma0*mptr->pPreviousTemperature*delV;
    
    // heat energy is Cv (dT - dTq0) -dPhi
	// Here do Cv (dT - dTq0)
    // dPhi = shearWork is lost due to shear term
    IncrementHeatEnergy(mptr,res->dT,dTq0,shearWork);
}