예제 #1
0
//-----------------------------------------------------------
// Subroutine to set block on element end
//-----------------------------------------------------------
short CommonReadHandler::EndBMPInput(char *xName,int exitBlock)
{
    if(strcmp(xName,"BMP")==0)
	{	// make last intensity hole material
		if(currentLevel==NULL)
			throw SAXException(BMPError("No intensity levels for materials were defined for <BMP> file",bmpFileName));
		
		// add level to grab left over intensities
		BMPLevel *newLevel=new BMPLevel(0,0,255);
		currentLevel->SetNextObject(newLevel);

    	TranslateBMPFiles();		// scan file for material points or elements
        block=exitBlock;			// Must have been in MATERIALPOINTS
		
		// delete defined levels
		while(firstLevel!=NULL)
		{	currentLevel=(BMPLevel *)firstLevel->GetNextObject();
			delete firstLevel;
			firstLevel=currentLevel;
		}
		currentLevel=NULL;
    }

    else if(strcmp(xName,"Intensity")==0)
	{	if(currentLevel->concentration<0. || currentLevel->concentration>1.)
			throw SAXException(BMPError("Particle concentration potential for an intensity level must be from 0 to 1",bmpFileName));
        block=BMPBLOCK;
	}
		
    else if(strcmp(xName,"Origin")==0 || strcmp(xName,"Thickness")==0 || strcmp(xName,"Angle")==0
				|| strcmp(xName,"Concentration")==0 || strcmp(xName,"Temperature")==0)
	{	// nothing to do
	}
	
	// not a BMP block element
	else
		return FALSE;
		
	return TRUE;
}
예제 #2
0
//-----------------------------------------------------------
// Subroutine to translate BMP file into material point
//-----------------------------------------------------------
void MPMReadHandler::TranslateBMPFiles(void)
{
	unsigned char **rows,**angleRows;
	BMPInfoHeader info,angleInfo;
	bool setAngles=FALSE;
	int numRotations=strlen(rotationAxes);
	
	// read image file
	char *bmpFullPath=archiver->ExpandOutputPath(bmpFileName);
	ReadBMPFile(bmpFullPath,info,&rows);
	delete [] bmpFullPath;
	
	// angle file name (overrides other angle settings)
	if(bmpAngleFileName[0]>0)
	{	setAngles=TRUE;
		char *bmpFullAnglePath=archiver->ExpandOutputPath(bmpAngleFileName);
		ReadBMPFile(bmpFullAnglePath,angleInfo,&angleRows);
		if(info.height!=angleInfo.height || info.width!=angleInfo.width)
			throw SAXException(BMPError("The image file and angle file sizes do not match.",bmpFileName));
		delete [] bmpFullAnglePath;
	}
	else if(numRotations>0)
	{	int i;
		for(i=0;i<numRotations;i++)
		{	char *expr=new char[strlen(angleExpr[i])+1];
			strcpy(expr,angleExpr[i]);
			if(!CreateFunction(expr,i+1))
				throw SAXException("Invalid angle expression was provided in <RotateX(YZ)> command.");
			delete [] expr;
		}
	}
	
	// bheight and bwidth provided in bmp file
	// <-1.e8 means not provided
	// negative means provided mm per pixel
	// positive is a specified size
	double xpw=-1.,ypw=-1.;
	if(bwidth<-1.e8 && bheight<-1.e8)
	{	if(!info.knowsCellSize)
			throw SAXException(BMPError("<BMP> must specify width and/or height as size or pixels per mm.",bmpFileName));
		bwidth = info.width*info.xcell;
		bheight = info.height*info.ycell;
		xpw = info.xcell;
		ypw = info.ycell;
	}
	else
	{	// provided mm per pixel
		if(bheight<0. && bheight>-1.e8)
		{	ypw = -bheight;
			bheight = ypw*(double)info.height;
		}
		if(bwidth<0. && bwidth>-1.e8)
		{	xpw = -bwidth;
			bwidth = xpw*(double)info.width;
		}
	}
	
	// total dimensions (if only one is known, find the other, never have both unknown)
	if(bheight<0) bheight=bwidth*(double)info.height/(double)info.width;
	if(bwidth<0) bwidth=bheight*(double)info.width/(double)info.height;
	
	// final mm per pixel (if needed)
	if(xpw<0.) xpw=bwidth/(double)info.width;
	if(ypw<0.) ypw=bheight/(double)info.height;
	
	// variables for scanning BMP file
	int matID;
	MPMBase *newMpt;
	int ii,k;
	Vector mpos[MaxElParticles];
	int ptFlag;
	BMPLevel *nextLevel;
	double deltax,deltay,deltaz,semiscale;
	double rmin,rmax,wtr1,wtr2,rweight;
	double cmin,cmax,wtc1,wtc2,weight;
	int r1,r2,c1,c2;
	BMPLevel *maxLevel;
	int row,col;
	ElementBase *elem;
	
	// Length/semiscale is half particle with
	//	(semiscale=4 for 2D w 4 pts per element or 3D with 8 pts per element,
	//		or 2 if 1 particle in the element)
	if(fmobj->IsThreeD())
		semiscale=2.*pow((double)fmobj->ptsPerElement,1./3.);
	else
		semiscale=2.*sqrt((double)fmobj->ptsPerElement);
    
    /* Parallelizing the following loop will speed up check meshes on Mac
        1. Will need copy of levels for each block (or pass copy of weight to BMPLevel methods)
            see BMPLevel methods: ClearWeight(),Material(double,double), MaximumWeight(double)
        2. mpCtrl->AddMaterialPoint() will need critical block
        3. FunctionValue() when setting angles uses globals they are problem for parallel
    */
	
	// scan mesh and assign material points or angles
    try
    {   for(ii=1;ii<=nelems;ii++)
        {	// skip if image not in extent of element box
            elem=theElements[ii-1];
            if(!elem->IntersectsBox(xorig,yorig,bwidth,bheight,zslice))
                continue;
            
            // load point coordinates
            elem->MPMPoints(fmobj->ptsPerElement,mpos);
        
            // half the extent of the volume of a particle
            deltax=(elem->GetDeltaX())/semiscale;
            deltay=(elem->GetDeltaY())/semiscale;
            if(fmobj->IsThreeD())
                deltaz=elem->GetDeltaZ()/semiscale;
            else
                deltaz=1.;
            if(deltaz<0.) deltaz=1.;
            
            for(k=0;k<fmobj->ptsPerElement;k++)
            {	ptFlag=1<<k;
            
                // skip if already filled
                if(elem->filled&ptFlag) continue;
                
                // if point in the view area, then check it
                if((mpos[k].x>=xorig && mpos[k].x<xorig+bwidth)
                        && (mpos[k].y>=yorig && mpos[k].y<yorig+bheight)
                             && (mpos[k].z>=zslice-deltaz && mpos[k].z<zslice+deltaz))
                {	// find range of rows and cols for pixels over this material point
                    if(yflipped)
                    {   rmin=(yorig+bheight-mpos[k].y-deltay)/ypw;
                        rmax=(yorig+bheight-mpos[k].y-deltay)/ypw;
                    }
                    else
                    {   rmin=(mpos[k].y-deltay-yorig)/ypw;
                        rmax=(mpos[k].y+deltay-yorig)/ypw;
                    }
                    r1=BMPIndex(rmin,info.height);
                    r2=BMPIndex(rmax,info.height);
                    if(r2==r1)
                    {	wtr1=wtr2=1.;
                    }
                    else
                    {	// fractional weight for first and last row in case not all within the extent
                        wtr1=(double)(r1+1)-rmin;
                        wtr2=rmax-(double)r2;
                    }
                    cmin=(mpos[k].x-deltax-xorig)/xpw;
                    cmax=(mpos[k].x+deltax-xorig)/xpw;
                    c1=BMPIndex(cmin,info.width);
                    c2=BMPIndex(cmax,info.width);
                    if(c2==c1)
                    {	wtc1=wtc2=1.;
                    }
                    else
                    {	// fractional weight for first and last col in case not all within the extent
                        wtc1=(double)(c1+1)-cmin;
                        wtc2=cmax-(double)c2;
                    }
                    
                    // find material ID or none (a hole)
                    // clear material weights
                    nextLevel=firstLevel;
                    while(nextLevel!=NULL) nextLevel=nextLevel->ClearWeight();

                    // add weights
                    for(row=r1;row<=r2;row++)
                    {	if(row==r1)
                            rweight=wtr1;
                        else if(row==r2)
                            rweight=wtr2;
                        else
                            rweight=1.;
                        for(col=c1;col<=c2;col++)
                        {	if(col==c1)
                                weight=rweight*wtc1;
                            else if(col==c2)
                                weight=rweight*wtc2;
                            else
                                weight=rweight;
                            
                            // find material at this level
                            // (note: last level with matID=0 catches empty space)
                            nextLevel=firstLevel;
                            while(nextLevel!=NULL)
                            {	matID=nextLevel->Material(rows[row][col],weight);
                                if(matID>=0) break;
                                nextLevel=(BMPLevel *)nextLevel->GetNextObject();
                            }
                        }
                    }
                    
                    // find maximum weight (matID=0 means max is empty space)
                    weight=0.;
                    maxLevel=NULL;
                    nextLevel=firstLevel;
                    while(nextLevel!=NULL) nextLevel=nextLevel->MaximumWeight(weight,&maxLevel);
                    if(maxLevel!=NULL)
                    {	matID=maxLevel->mat;
                        nextLevel=maxLevel;
                    }
                    else
                        matID=-1;

                    // create a material point if one at this spot using matID and nextLevel
                    // Note that empty spaced is not marked as filled which allows superposition of
                    // images with different materials. If want to forcefully create a hole that
                    // cannot be filled by subsequent image, will need to define a new material
                    // type that can have matID for a hole. It will not create a point, but will mark
                    // the location as filled
                    if(matID>0)
                    {	if(fmobj->IsThreeD())
                            newMpt=new MatPoint3D(ii,matID,nextLevel->angle);
                        else if(fmobj->IsAxisymmetric())
                            newMpt=new MatPointAS(ii,matID,nextLevel->angle,mpos[k].x);
                        else
                            newMpt=new MatPoint2D(ii,matID,nextLevel->angle,nextLevel->thickness);
                        newMpt->SetPosition(&mpos[k]);
                        newMpt->SetOrigin(&mpos[k]);
                        newMpt->SetVelocity(&nextLevel->vel);
                        mpCtrl->AddMaterialPoint(newMpt,nextLevel->concentration,nextLevel->temperature);
                        
                        // is there an angle image?
                        if(setAngles)
                        {	// weight average of scanned pixels
                            double totalWeight=0.;
                            double totalIntensity=0.;
                            for(row=r1;row<=r2;row++)
                            {	if(row==r1)
                                    rweight=wtr1;
                                else if(row==r2)
                                    rweight=wtr2;
                                else
                                    rweight=1.;
                                for(col=c1;col<=c2;col++)
                                {	if(col==c1)
                                        weight=rweight*wtc1;
                                    else if(col==c2)
                                        weight=rweight*wtc2;
                                    else
                                        weight=rweight;
                                    
                                    totalIntensity+=weight*angleRows[row][col];
                                    totalWeight+=weight;
                                }
                            }
                            totalIntensity/=totalWeight;
                            double matAngle=minAngle+(totalIntensity-minIntensity)*angleScale;
                            newMpt->SetAnglez0InDegrees(matAngle);
                        }
                        else
                        {	// If had Rotate commands then use them
                            SetMptAnglesFromFunctions(numRotations,&mpos[k],newMpt);
                        }
                        elem->filled|=ptFlag;
                    }
                }
            }
        }
    }
    catch(const char *msg)
    {   throw SAXException(msg);
    }
	
	// clean up
	for(row=0;row<info.height;row++)
	{	delete [] rows[row];
		if(setAngles) delete [] angleRows[row];
	}
	delete [] rows;
	if(setAngles) delete [] angleRows;
	
	// angles if allocated
	for(ii=0;ii<numRotations;ii++)
	{	delete [] angleExpr[ii];
	}
	DeleteFunction(-1);
		
}
예제 #3
0
//-----------------------------------------------------------
// Subroutine to translate BMP file into material point
// throws std::bad_alloc, SAXException()
//-----------------------------------------------------------
void FEAReadHandler::TranslateBMPFiles(void)
{
	// file info and data
	unsigned char **rows,**angleRows=NULL;
	XYInfoHeader info,angleInfo;
	
	// read image file
	char *bmpFullPath=archiver->ExpandOutputPath(bmpFileName);
	ReadBMPFile(bmpFullPath,info,&rows);
	delete [] bmpFullPath;
	
	// angle file name
	bool setAngles = false;
	if(bmpAngleFileName[0]>0)
	{	setAngles=true;
		char *bmpFullAnglePath=archiver->ExpandOutputPath(bmpAngleFileName);
		ReadBMPFile(bmpFullAnglePath,angleInfo,&angleRows);
		if(info.height!=angleInfo.height || info.width!=angleInfo.width)
			throw SAXException(BMPError("The image file and angle file sizes do not match.",bmpFileName));
		delete [] bmpFullAnglePath;
	}
	
	// get final image width, height, and size per pixel
	Vector pw;
	const char *msg = CommonReadHandler::DecodeBMPWidthAndHeight(info,bwidth,bheight,orig.z,pw,false);
	if(msg != NULL) throw SAXException(BMPError(msg,bmpFileName));
	pw.z = yflipped ? -1. : 1. ;
	
	// scan all elements - fill those that are in the area and have no material yet
	DomainMap map;
	ElementBase *elem;
	Vector center,del;
	for(int i=0;i<nelems;i++)
	{	elem=theElements[i]; 
        
		// skip if element already has a material
        if(elem->material!=NO_MATERIAL) continue;
		
		// get center (will skip unless the center of extent of the element is in the image)
		elem->GetXYZCentroid(&center);
		
		// half the extent of the element (z means 2D)
		del = MakeVector((elem->GetDeltaX())/2.,(elem->GetDeltaY())/2.,-1.);
		
		// Get range of rows and columns and their weights (or skip if not in the image)
		if(!MapDomainToImage(info,center,orig,del,pw,bwidth,bheight,map)) continue;
		
		// find maximum level and its material ID or none (a hole)
		int matID=-1;
		BMPLevel *nextLevel = FindBMPLevel(firstLevel,map,rows);
		if(nextLevel!=NULL) matID = nextLevel->Material();
		
		// set material ID if found a match
		if(matID>0)
		{	// set it
			elem->material=matID;
			
			// is there an angle image too?
			if(setAngles)
			{	double totalIntensity = FindAverageValue(map,rows);
				if(totalIntensity>0.)
				{	double matAngle=minAngle+(totalIntensity-minIntensity)*angleScale;
					elem->SetAngleInDegrees(matAngle);
				}
			}
		}
	}

	// clean up
	for(int row=0;row<info.height;row++)
	{	delete [] rows[row];
		if(setAngles) delete [] angleRows[row];
	}
	delete [] rows;
	if(setAngles) delete [] angleRows;
}
예제 #4
0
//-----------------------------------------------------------
// Subroutine to read BMP file
//-----------------------------------------------------------
void CommonReadHandler::ReadBMPFile(char *bmpFullPath,BMPInfoHeader &info,unsigned char ***theData)
{
	short mustReverse=FALSE,status=TRUE;
	BMPHeader header;
	FILE *fp;
	unsigned int i,ncolors;
	unsigned char blueByte,greenByte,redByte,junkByte,dataByte,mask;
	int row,col,colByte;
	
	// decide what computer I am on
    // byte order marker
    int test=1;
    char *testPtr=(char *)&test;
    if(*testPtr==0) mustReverse=TRUE;
	
	// open the file
	if((fp=fopen(bmpFullPath,"r"))==NULL)
		throw SAXException(BMPError("The <BMP> file could not be opened.",bmpFullPath));
	
	// read and check the header (individual reads due to Windows alignment issues)
	if(fread(header.type,2,1,fp)<1) status=FALSE;
	if(fread(&header.size,4,1,fp)<1) status=FALSE;
	if(fread(&header.reserved1,2,1,fp)<1) status=FALSE;
	if(fread(&header.reserved2,2,1,fp)<1) status=FALSE;
	if(fread(&header.offset,4,1,fp)<1) status=FALSE;
	if(!status)
	{	fclose(fp);
		throw SAXException(BMPError("Error reading the specified <BMP> file.",bmpFileName));
	}
	if(mustReverse)
	{	Reverse((char *)&header.size,sizeof(int));
		Reverse((char *)&header.offset,sizeof(int));
	}
	
	// precalculate number of colors from header data
	ncolors=(header.offset-14-40)>>2;
	
	// exit if does not look like BMP file
	if(header.type[0]!='B' || header.type[1]!='M')
	{	fclose(fp);
		throw SAXException(BMPError("<BMP> file is not a valid bit map file.",bmpFileName));
	}
	
	// read information
	if(fread(&info.size,4,1,fp)<1) status=FALSE;
	if(fread(&info.width,4,1,fp)<1) status=FALSE;
	if(fread(&info.height,4,1,fp)<1) status=FALSE;
	if(fread(&info.planes,2,1,fp)<1) status=FALSE;
	if(fread(&info.bits,2,1,fp)<1) status=FALSE;
	if(fread(&info.compression,4,1,fp)<1) status=FALSE;
	if(fread(&info.imagesize,4,1,fp)<1) status=FALSE;
	if(fread(&info.xresolution,4,1,fp)<1) status=FALSE;
	if(fread(&info.yresolution,4,1,fp)<1) status=FALSE;
	if(fread(&info.ncolors,4,1,fp)<1) status=FALSE;
	if(fread(&info.importantcolors,4,1,fp)<1) status=FALSE;
	if(!status)
	{	fclose(fp);
		throw SAXException(BMPError("Error reading the specified <BMP> file.",bmpFileName));
	}
	if(mustReverse)
	{	Reverse((char *)&info.size,sizeof(int));
		Reverse((char *)&info.width,sizeof(int));
		Reverse((char *)&info.height,sizeof(int));
		Reverse((char *)&info.planes,2);
		Reverse((char *)&info.bits,2);
		Reverse((char *)&info.compression,sizeof(int));
		Reverse((char *)&info.imagesize,sizeof(int));
		Reverse((char *)&info.xresolution,sizeof(int));
		Reverse((char *)&info.yresolution,sizeof(int));
		Reverse((char *)&info.ncolors,sizeof(int));
		Reverse((char *)&info.importantcolors,sizeof(int));
	}
	
	// correct for Photoshop lack of information
	if(info.imagesize==0)
		info.imagesize=header.size-header.offset;
	if(info.ncolors==0)
		info.ncolors=ncolors;
	
	// can I read this BMP file
	if(info.planes!=1)
	{	fclose(fp);
		throw SAXException(BMPError("Cannot read <BMP> files with more than 1 color plane.",bmpFileName));
	}
	if(info.compression!=0)
	{	fclose(fp);
		throw SAXException(BMPError("Cannot read compressed <BMP> files.",bmpFileName));
	}
	if(info.ncolors!=ncolors || (ncolors!=2 && ncolors!=16 && ncolors!=256))
	{	fclose(fp);
		throw SAXException(BMPError("<BMP> files does not appear to be 1, 4, or 8 bit grayscale image.",bmpFileName));
	}
	
	// read the 2, 16, or 256 colors
	for(i=0;i<ncolors;i++)
	{	if(fread(&blueByte,1,1,fp)<1) status=FALSE;
		if(fread(&greenByte,1,1,fp)<1) status=FALSE;
		if(fread(&redByte,1,1,fp)<1) status=FALSE;
		if(fread(&junkByte,1,1,fp)<1) status=FALSE;
		if(!status)
		{	fclose(fp);
			throw SAXException(BMPError("<BMP> color table is corrupted.",bmpFileName));
		}
		intensity[i]=((int)blueByte+(int)greenByte+(int)blueByte)/3;
	}
	
	// buffer to read the file
	unsigned char **rows=new unsigned char *[info.height];
	*theData=rows;
	if(rows==NULL)
	{	fclose(fp);
		throw SAXException(BMPError("Out of memory reading <BMP> file.",bmpFileName));
	}
	for(row=0;row<info.height;row++)
	{	rows[row]=new unsigned char[info.width];
		if(rows[row]==NULL)
		{	fclose(fp);
			throw SAXException(BMPError("Out of memory reading <BMP> file.",bmpFileName));
		}
	}
	
	// read one byte at a time (which might have multiple points) but each
	//	row is multiple of 4 bytes
	int colorsPerByte=1;
	if(ncolors==16)
		colorsPerByte=2;
	else if(ncolors==2)
		colorsPerByte=8;
	int rowBytes=info.width/colorsPerByte;
	if(rowBytes%4!=0)
		rowBytes+=4-(rowBytes % 4);
	
	// check size
	unsigned int expectSize=(unsigned int)(info.height*rowBytes);
	if(info.imagesize<expectSize)
	{	fclose(fp);
		throw SAXException(BMPError("<BMP> file appears to be missing some data.",bmpFileName));
	}
	
	// scan each row
	for(row=0;row<info.height;row++)
	{	col=0;
		for(colByte=0;colByte<rowBytes;colByte++)
		{	// read next byte
			if(fread(&dataByte,1,1,fp)<1)
			{	fclose(fp);
				throw SAXException(BMPError("Error reading image date of <BMP> file.",bmpFileName));
			}
			if(col>=info.width) continue;
			switch(ncolors)
			{	case 256:		// each byte is an index
					rows[row][col]=intensity[dataByte];
					col++;
					break;
				case 16:		// each byte has two indices
					rows[row][col]=intensity[(dataByte&0xF0)>>4];
					col++;
					if(col>=info.width) break;
					rows[row][col]=intensity[dataByte&0x0F];
					col++;
					break;
				case 2:
					mask=0x80;
					for(i=1;i<=8;i++)
					{	rows[row][col]=intensity[(dataByte&mask)>>(8-i)];
						col++;
						if(col>=info.width) break;
						mask>>=1;
					}
					break;
				default:
					break;
			}
		}
	}
	fclose(fp);
}
예제 #5
0
//-----------------------------------------------------------
// Check for bmp element, return false if not
//-----------------------------------------------------------
short CommonReadHandler::BMPFileCommonInput(char *xName,const Attributes& attrs,int expectedBlock)
{
    char *aName,*value;
    int i,numAttr;
	double aScaling;

    //-----------------------------------------------------------
    // Read BMP file name and resolution
    //-----------------------------------------------------------
    if(strcmp(xName,"BMP")==0)
	{	ValidateCommand(xName,expectedBlock,ANY_DIM);
        block=BMPBLOCK;
		bwidth=bheight=-1.e9;		// < -1.e8 means dimension was not specified
		bmpFileName[0]=0;
		bmpAngleFileName[0]=0;
		xorig=yorig=0.;
        yflipped=FALSE;
		zslice=0.;
		aScaling=ReadUnits(attrs,LENGTH_UNITS);
        numAttr=attrs.getLength();
#ifdef MPM_CODE
		rotationAxes[0]=0;				// no rotations yet
#endif
        for(i=0;i<numAttr;i++)
		{	aName=XMLString::transcode(attrs.getLocalName(i));
            value=XMLString::transcode(attrs.getValue(i));
            if(strcmp(aName,"width")==0)
                sscanf(value,"%lf",&bwidth);
            else if(strcmp(aName,"height")==0)
                sscanf(value,"%lf",&bheight);
            else if(strcmp(aName,"name")==0)
				strcpy(bmpFileName,value);
            else if(strcmp(aName,"angles")==0)
				strcpy(bmpAngleFileName,value);
            delete [] aName;
            delete [] value;
        }
		if(bwidth<-1.e8 && bheight<-1.e8)
            throw SAXException(BMPError("<BMP> must specify width and/or height as size or pixels per mm.",bmpFileName));
		bwidth*=aScaling;
		bheight*=aScaling;
		if(bmpFileName[0]==0)
            throw SAXException("<BMP> must specify the file in a name attribute.");
	}
	
    //-----------------------------------------------------------
    // Set origin on input data
    //-----------------------------------------------------------
    else if(strcmp(xName,"Origin")==0)
	{	ValidateCommand(xName,BMPBLOCK,ANY_DIM);
		aScaling=ReadUnits(attrs,LENGTH_UNITS);
        numAttr=attrs.getLength();
        for(i=0;i<numAttr;i++)
		{	aName=XMLString::transcode(attrs.getLocalName(i));
            value=XMLString::transcode(attrs.getValue(i));
            if(strcmp(aName,"x")==0)
			{	sscanf(value,"%lf",&xorig);
				xorig*=aScaling;
			}
            else if(strcmp(aName,"y")==0)
			{	sscanf(value,"%lf",&yorig);
				yorig*=aScaling;
			}
            else if(strcmp(aName,"z")==0)
			{	sscanf(value,"%lf",&zslice);
				zslice*=aScaling;
			}
            else if(strcmp(aName,"flipped")==0)
			{	if(strcmp(value,"yes")==0 || strcmp(value,"Yes")==0 || strcmp(value,"YES")==0 || strcmp(value,"1")==0 )
                    yflipped=TRUE;
                else
                    yflipped=FALSE;
			}
            delete [] aName;
            delete [] value;
        }
	}
	
    //-----------------------------------------------------------
    // Assign intensity to some material properties
    //-----------------------------------------------------------
    else if(strcmp(xName,"Intensity")==0)
	{	ValidateCommand(xName,BMPBLOCK,ANY_DIM);
        numAttr=attrs.getLength();
		int mat=-1;
		int imin=-1;
		int imax=-1;
		minAngle=0.;
		double maxAngle=0.;
		char matname[200];
		matname[0]=0;
        for(i=0;i<numAttr;i++)
		{	aName=XMLString::transcode(attrs.getLocalName(i));
            value=XMLString::transcode(attrs.getValue(i));
            if(strcmp(aName,"mat")==0)
				sscanf(value,"%d",&mat);
			else if(strcmp(aName,"matname")==0)
			{	if(strlen(value)>199) value[200]=0;
				strcpy(matname,value);
			}
            else if(strcmp(aName,"imin")==0)
                sscanf(value,"%d",&imin);
            else if(strcmp(aName,"imax")==0)
                sscanf(value,"%d",&imax);
            else if(strcmp(aName,"minAngle")==0)
                sscanf(value,"%lf",&minAngle);
            else if(strcmp(aName,"maxAngle")==0)
                sscanf(value,"%lf",&maxAngle);
            delete [] aName;
            delete [] value;
        }
		// if gave a matname, it takes precedence over mat number
		if(strlen(matname)>0)
			mat = matCtrl->GetIDFromNewName(matname);
		if(imin<0 || imax<0)
			throw SAXException(BMPError("<Intensity> has incomplete set of attributes.",bmpFileName));
		if(imin>=imax)
			throw SAXException(BMPError("<Intensity> range is not valid.",bmpFileName));
		if(mat>=0)
		{	BMPLevel *newLevel=new BMPLevel(mat,imin,imax);
			if(newLevel==NULL)
				throw SAXException(BMPError("<Intensity> failed due to memory error.",bmpFileName));
			if(currentLevel==NULL)
				firstLevel=newLevel;
			else
				currentLevel->SetNextObject(newLevel);
			currentLevel=newLevel;
			block=INTENSITYBLOCK;
		}
		else
		{	angleScale=(maxAngle-minAngle)/((double)imax-(double)imin);
			minIntensity=(double)imin;
		}
	}
	
	//-----------------------------------------------------------
    // Intensity properties for both MPM and FEA
    //-----------------------------------------------------------
	
	// thickness
    else if(strcmp(xName,"Thickness")==0)
	{	ValidateCommand(xName,INTENSITYBLOCK,MUST_BE_2D);
    	input=DOUBLE_NUM;
        inputPtr=(char *)&currentLevel->thickness;
        gScaling=ReadUnits(attrs,LENGTH_UNITS);
    }
	
	// angle
    else if(strcmp(xName,"Angle")==0)
	{	ValidateCommand(xName,INTENSITYBLOCK,ANY_DIM);
    	input=DOUBLE_NUM;
        inputPtr=(char *)&currentLevel->angle;
    }
	
	// temperature
    else if(strcmp(xName,"Temperature")==0)
	{
#ifdef FEA_CODE
		if(block==THERMAL) return FALSE;
#endif
		ValidateCommand(xName,INTENSITYBLOCK,ANY_DIM);
    	input=DOUBLE_NUM;
        inputPtr=(char *)&currentLevel->temperature;
    }
	
	else
		return FALSE;
	
	return TRUE;
}