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; } }