HxUniformScalarField3* HxMovingLeastSquaresWarp::createOutputDataSet() {
    HxUniformScalarField3* fromImage =
        dynamic_cast<HxUniformScalarField3*>(portFromImage.getSource());
    HxUniformScalarField3* toImage =
        dynamic_cast<HxUniformScalarField3*>(portToImage.getSource());
    HxUniformScalarField3* warpedImage =
        dynamic_cast<HxUniformScalarField3*>(getResult(0));

    if (!fromImage)
        return (0);

    McDim3l dims;
    McBox3f bbox;

    if (toImage) {
        dims = toImage->lattice().getDims();
        bbox = toImage->getBoundingBox();
    }
    if (!warpedImage || warpedImage->lattice().getDims()[0] != dims[0] ||
        warpedImage->lattice().getDims()[1] != dims[1] ||
        warpedImage->lattice().getDims()[2] != dims[2])
        warpedImage = 0;

    if (!warpedImage) {
        if (toImage->isOfType(HxUniformLabelField3::getClassTypeId())) {
            warpedImage = new HxUniformLabelField3(dims);
            ((HxUniformLabelField3*)warpedImage)->parameters =
                ((HxUniformLabelField3*)fromImage)->parameters;
        } else
            warpedImage =
                new HxUniformScalarField3(dims, fromImage->primType());
    }

    warpedImage->setBoundingBox(bbox);
    warpedImage->composeLabel(fromImage->getLabel(), "Warped");
    setResult(0, warpedImage);
    return (warpedImage);
}
void AssignEModulus::assignEModulus( GridType* grid )
{
	if ( !grid ) { return; }

	HxUniformScalarField3* image = dynamic_cast<HxUniformScalarField3*>( portImage.source() );
	if ( !image ) { return; }

	theWorkArea->startWorking( "Assigning Young's moduli to elements..." );
	theWorkArea->setProgressValue( 0.0 );

	OBLelement3D* FEelement = NULL;
	if ( dynamic_cast<HxTetraGrid*>(grid) )
	{
		FEelement = new OBLtetra;
	}
	if ( dynamic_cast<HxHexaGrid*>(grid) )
	{
		FEelement = new OBLhexa;
	}
	if ( !FEelement ) { return; }

	mculong totalElems = AmiraGrid::getNumberOfElements( grid );
	float* moduli = new float[totalElems];

	if ( portAveraging.getValue() == 0 )
	{
		HxLocation3* loc = image->createLocation();
		for ( mculong i = 0; i < totalElems; i++ )
		{
			theWorkArea->setProgressValue( (1.0*i)/totalElems );

			float intensity = 0;
			McDArray<McVec3f> vertices = AmiraGrid::getElementVertices( grid, i );
			McVec3f p = FEelement->getCenter( vertices );
			if ( loc->move( p[0], p[1], p[2] ) == 1 )
			{
				// image is valid for this location
				image->eval( loc, &intensity );
			}

			moduli[i] = this->getElasticityFromHU( intensity );
		}
		delete loc;
	}
	else if ( portAveraging.getValue() == 1 )	// Bonemat V1
	{
		// Create an instance of HxLoc3Regular instead of HxLocation3,
		// because we know we are dealing with a uniform scalar field and
		// we want access to the voxelindices
		//HxLoc3Regular* location = image->coords()->createLocation();
		HxLoc3Regular* location = (HxLoc3Regular*)image->createLocation();
		for ( mculong e = 0; e < totalElems; e++ )
		{
			theWorkArea->setProgressValue( (1.0*e)/totalElems );

			//float sum = 0.0;
			//int count = 0;
			//McVec3f pcoords;
			McDArray<McVec3f> vertices = AmiraGrid::getElementVertices( grid, e );

			//// determine bounding box of voxel indices within element
			//location->set( vertices[0][0], vertices[0][1], vertices[0][2] );
			//int indexbbox[6] = { location->ix, location->ix,
			//					location->iy, location->iy,
			//					location->iz, location->iz };
			//for ( int el = 1; el < 8; el++ )
			//{
			//	location->move( vertices[el][0], vertices[el][1], vertices[el][2] );
			//	if ( location->ix < indexbbox[0] ) { indexbbox[0] = location->ix; }
			//	if ( location->ix > indexbbox[1] ) { indexbbox[1] = location->ix; }
			//	if ( location->iy < indexbbox[2] ) { indexbbox[2] = location->iy; }
			//	if ( location->iy > indexbbox[3] ) { indexbbox[3] = location->iy; }
			//	if ( location->iz < indexbbox[4] ) { indexbbox[4] = location->iz; }
			//	if ( location->iz > indexbbox[5] ) { indexbbox[5] = location->iz; }
			//}

			//for ( int k = indexbbox[4]; k <= indexbbox[5]; k++ )
			//{
			//	for ( int j = indexbbox[2]; j <= indexbbox[3]; j++ )
			//	{
			//		for ( int i = indexbbox[0]; i <= indexbbox[1]; i++ )
			//		{
			//			float point[3];
			//			image->lattice.coords()->pos( i, j, k, point );
			//			int inside = FEelement->getIsoParam( vertices,
			//				McVec3f(point[0],point[1], point[2]), pcoords );
			//			if ( inside == 1 )
			//			{
			//				location->move( point );
			//				float value;
			//				image->eval( location, &value );
			//				sum += value;
			//				count++;
			//			}
			//		}
			//	}
			//}
			//float aveinten = 0.0;
			//if ( count > 0 )
			//{
			//	aveinten = sum/count;
			//}
			float aveinten = this->averageVoxels( FEelement, vertices, image );
			if ( aveinten == 0 )
			{
				McVec3f p = FEelement->getCenter( vertices );
				if ( location->move( p[0], p[1], p[2] ) == 1 )
				{
					// image is valid for this location
					image->eval( location, &aveinten );
				}
			}

			// ... then convert to elasticity
			moduli[e] = this->getElasticityFromHU( aveinten );
		}
		//theMsg->printf("indices range: %d %d %d %d %d %d", xmin, xmax, ymin, ymax, zmin, zmax );
		delete location;
	}
	else if ( portAveraging.getValue() == 2 )	// Bonemat V2
	{
		// determine boundary elements if requested
		McDArray<mclong> surface;
		if ( portBoundary.getValue() == 1 )
		{
			AmiraGrid::getSurfaceElements( grid, &surface );
		}

		for ( mclong i = 0; i < totalElems; i++ )
		{
			theWorkArea->setProgressValue( (1.0*i)/totalElems );

			// first determine average hounsfield unit for element...
			McDArray<McVec3f> vertices = AmiraGrid::getElementVertices( grid, i );
			float intensity = 0.0;
			if ( index( surface, i ) != -1 )
			{
				intensity = this->averageVoxels( FEelement, vertices, image );
			}
			else
			{
				intensity = this->sampleField( FEelement, vertices, image );
			}

			// ... then convert to elasticity
			moduli[i] = this->getElasticityFromHU( intensity );
		}
	}
	else if ( portAveraging.getValue() == 3 )	// Bonemat V3
	{
		// determine boundary elements if requested
		McDArray<mclong> surface;
		if ( portBoundary.getValue() == 1 )
		{
			AmiraGrid::getSurfaceElements( grid, &surface );
		}

		// first create temporarily image with hounsfield units converted into elasticity...
		//int size[3];
		//image->lattice.getSize( size[0], size[1], size[2] );
		//float bbox[6];
		//image->coords()->getBoundingBox( bbox );
		//mculong buffersize = size[0]*size[1]*size[2];
		//float* elasbuffer = new float[buffersize];
		//float HU = 0.0;
		//for ( int i = 0; i < buffersize; i++ )
		//{
		//	theWorkArea->setProgressValue( (0.3*i)/buffersize );

		//	image->lattice.eval( i, &HU );
		//	elasbuffer[i] = myParams[0] * pow((myParams[1]*(HU + myParams[2])
		//		+ myParams[3]), myParams[4]) + myParams[5];
		//}
		//HxUniformScalarField3* elasfield = new HxUniformScalarField3( size, McPrimType::mc_float, elasbuffer );
		//elasfield->lattice.setBoundingBox( bbox );

		HxUniformScalarField3* elasfield = this->convertHUtoElasField( image );

		// ... then determine the average of the field for each element
		int count = 0;
		for ( mclong i = 0; i < totalElems; i++ )
		{
			theWorkArea->setProgressValue( 0.3 + (0.7*i)/totalElems );

			McDArray<McVec3f> vertices = AmiraGrid::getElementVertices( grid, i );
			float intensity = 0.0;
			if ( index( surface, i ) != -1 )
			{
				moduli[i] = this->averageVoxels( FEelement, vertices, elasfield );
				if (moduli[i]==0)
				{
					//theMsg->printf("averageVoxels is zero for %d", i);
					count++;
				}
			}
			else
			{
				moduli[i] = this->sampleField( FEelement, vertices, elasfield );
				if (moduli[i]==0)
				{
					theMsg->printf("sampleField is zero for %d", i);
				}
			}
		}

		// create elasticity image if requested
		if ( portElasImage.getValue() == 1 )
		{
			setResult( numResults++, elasfield );
			elasfield->composeLabel( grid->getName(), "_elasticity" );
		}
		else
		{
			delete elasfield;
		}
	}

	if ( !FEelement ) { delete FEelement; FEelement = NULL; }

	this->createBins( portBins.getValue( 0 ), moduli, grid );

	// create data field if requested
	if ( portDataField.getValue() == 1 )
	{
		if ( HxTetraGrid* tetgrid = dynamic_cast<HxTetraGrid*>(grid) )
		{
			HxTetraScalarField3* scalardata = new HxTetraScalarField3( tetgrid,HxTetraData::PER_TETRA, moduli );
			setResult( numResults++, scalardata );
			scalardata->composeLabel( grid->getName(), "_youngs" );
		}
		if ( HxHexaGrid* hexgrid = dynamic_cast<HxHexaGrid*>(grid) )
		{
			HxHexaScalarField3* scalardata = new HxHexaScalarField3( hexgrid, HxHexaData::PER_HEXA, moduli );
			setResult( numResults++, scalardata );
			scalardata->composeLabel( grid->getName(), "_youngs" );
		}
	}
	else
	{
		delete [] moduli;
	}
}