void HxCPDSpatialGraphWarp::preparePoints(McDArray<McVec3f>& p1, McDArray<McVec3f>& p2, SpatialGraphSelection& slice2, const HxSpatialGraph* spatialGraph) { ma::SliceSelector selectionHelper(spatialGraph, "TransformInfo"); ma::EndPointParams params; params.endPointRegion = 30; params.projectionPlane = selectionHelper.computeMidPlane(0, 1); params.projectionType = ma::P_ORTHOGONAL; params.refSliceNum = 0; params.transSliceNum = 1; params.useAbsoluteValueForEndPointRegion = false; params.maxDistForAngle = 2000; params.angleToPlaneFilter = 0.01; SpatialGraphSelection slice1; ma::FacingPointSets pr = ma::projectEndPoints(spatialGraph, slice1, slice2, params); McDArray<McVec3f> refCoords = pr.ref.positions; McDArray<McVec3f> transCoords = pr.trans.positions; mcassert(refCoords.size() == slice1.getNumSelectedVertices()); mcassert(transCoords.size() == slice2.getNumSelectedVertices()); p1.resize(refCoords.size()); for (int i = 0; i < refCoords.size(); i++) { McVec3f coord = refCoords[i]; p1[i] = McVec3f(coord.x, coord.y, 0); } p2.resize(transCoords.size()); for (int i = 0; i < transCoords.size(); i++) { McVec3f coord = transCoords[i]; p2[i] = McVec3f(coord.x, coord.y, 0); } mcassert(p2.size() == slice2.getNumSelectedVertices()); }
void HxCPDSpatialGraphWarp::computeRigidVanMises() { const HxSpatialGraph* inputSG = (HxSpatialGraph*)portData.getSource(); ma::SliceSelector selectionHelper(inputSG, "TransformInfo"); HxSpatialGraph* resultSG = createOutputDataSet(); resultSG->copyFrom(inputSG); McDArray<McVec3f> points1, points2; McDArray<McVec3f> dirs1, dirs2; SpatialGraphSelection slice2; preparePointsAndDirectionsRigid(points1, points2, dirs1, dirs2, slice2, resultSG); mcassert(slice2.getNumSelectedVertices() == points2.size()); ma::CPDLinearAligner cpd; cpd.params.w = portW.getValue(); cpd.params.withScaling = portWithScale.getValue(); cpd.params.maxIterations = portEMParams.getValue(0); cpd.params.sigmaSquareStop = portEMParams.getValue(1); cpd.params.eDiffRelStop = portEMParams.getValue(2); cpd.params.useDirections = portUseDirection.getValue(); cpd.params.usePositions = portUseCoords.getValue(); if (!portUseDirection.getValue()) { dirs1.fill(McVec3f(0, 0, 1)); dirs2.fill(McVec3f(0, 0, 1)); } ma::FacingPointSets points; points.ref.positions = points1; points.ref.directions = dirs1; points.trans.positions = points2; points.trans.directions = dirs2; cpd.setPoints(points); McDMatrix<double> Rc, Rd; McDVector<double> t; double s; const mtalign::AlignInfo info = cpd.align(Rc, s, t, Rd); applyRigidDeformationToSliceVanMises(slice2, resultSG, cpd, Rc, s, t); portCPDResults.setValue(0, info.sigmaSquare); portCPDResults.setValue(1, info.kappa); portCPDResults.setValue(2, s); double rho = mtalign::rotationAngle2d(Rc); portCPDResults.setValue(3, rho); portCPDResults.setValue(4, t[0]); portCPDResults.setValue(5, t[1]); portCPDResults.setValue(6, info.numIterations); resultSG->touch(); resultSG->fire(); }
float AssignEModulus::averageVoxels( const OBLelement3D* FEelement, const McDArray<McVec3f>& vertices, HxUniformScalarField3* field ) { if ( !FEelement ) { return 0; } McVec3f pcoords; // 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*)field->createLocation(); // 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 < vertices.size(); 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; } } float sum = 0.0; int count = 0; 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]; field->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; field->eval( location, &value ); sum += value; count++; } } } } delete location; return ( count > 0 ) ? ( sum/count ) : 0.0; }
void MicrotubuleTransformOperation::undo() { SbMatrix invMat = mMat.inverse(); SpatialGraphSelection::Iterator iter(mSelection); iter.vertices.reset(); int vNum = iter.vertices.nextSelected(); while (vNum != -1) { McVec3f c = graph->getVertexCoords(vNum); SbVec3f t(c.x, c.y, c.z); SbVec3f res; invMat.multVecMatrix(t, res); graph->setVertexCoords(vNum, McVec3f(res[0], res[1], res[2])); vNum = iter.vertices.nextSelected(); } iter.edges.reset(); int eNum = iter.edges.nextSelected(); while (eNum != -1) { McDArray<McVec3f> points = graph->getEdgePoints(eNum); for (int p = 0; p < points.size(); p++) { SbVec3f t(points[p].x, points[p].y, points[p].z); SbVec3f res; invMat.multVecMatrix(t, res); points[p] = McVec3f(res[0], res[1], res[2]); } graph->setEdgePoints(eNum, points); eNum = iter.edges.nextSelected(); } int numPoints = mSelection.getNumSelectedPoints(); for (int i = 0; i < numPoints; ++i) { SpatialGraphPoint p = mSelection.getSelectedPoint(i); McDArray<McVec3f> points = graph->getEdgePoints(p.edgeNum); SbVec3f t(points[p.pointNum].x, points[p.pointNum].y, points[p.pointNum].z); SbVec3f res; invMat.multVecMatrix(t, res); points[p.pointNum] = McVec3f(res[0], res[1], res[2]); graph->setEdgePoints(p.edgeNum, points); } // update the transform parameters for (int i = 0; i < mTransParams.size(); ++i) { appendTransform(mTransParams[i], invMat); } }
void HxMovingLeastSquaresWarp::compute() { if (!portAction.wasHit()) return; HxUniformScalarField3* fromImage = (HxUniformScalarField3*)portFromImage.getSource(); HxLandmarkSet* pointSet = hxconnection_cast<HxLandmarkSet>(portData); if (!fromImage) return; /* It is ok to warp without landmarks, if method is rigid and input has a transformation */ if (!pointSet) { return; } else if (pointSet->getNumSets() < 2) { theMsg->printf( "Error: LandmarkWarp data has to contain at least 2 sets."); return; } HxUniformScalarField3* outputImage; HxUniformVectorField3* outputVectorField = 0; outputImage = createOutputDataSet(); outputVectorField = createOutputVectorDataSet(); float* outputImageData = (float*)outputImage->lattice().dataPtr(); McDArray<McVec2d> landmarks1, landmarks2; prepareLandmarks(landmarks1, landmarks2); MovingLeastSquares mls; mls.setAlpha(portAlpha.getValue()); mls.setLandmarks(landmarks2, landmarks1); const McDim3l& dims = outputImage->lattice().getDims(); McVec3f voxelSizeInOutputImage = outputImage->getVoxelSize(); const McBox3f& bboxOfOutputImage = outputImage->getBoundingBox(); const McBox3f& bboxOfFromImage = fromImage->getBoundingBox(); #ifdef _OPENMP #pragma omp parallel for #endif for (int i = 0; i < dims[0]; i++) { HxLocation3* locationInFromImage = fromImage->createLocation(); std::cout << "\n" << i << " of " << dims[0]; for (int j = 0; j < dims[1]; j++) { McVec2d currentPositionInOutput = McVec2d( bboxOfOutputImage[0] + (float)(i)*voxelSizeInOutputImage.x, bboxOfOutputImage[2] + (float)(j)*voxelSizeInOutputImage.y); McVec2d warpedCoordInFromImage = mls.interpolate(currentPositionInOutput); McVec3f displacement = McVec3f( warpedCoordInFromImage.x - currentPositionInOutput.x, warpedCoordInFromImage.y - currentPositionInOutput.y, 0); displacement = displacement * -1; locationInFromImage->move(McVec3f(warpedCoordInFromImage.x, warpedCoordInFromImage.y, bboxOfFromImage[4])); float resultValue[1]; fromImage->eval(*locationInFromImage, resultValue); unsigned long pos = latticePos(i, j, 0, dims); outputImageData[pos] = resultValue[0]; outputVectorField->lattice().set(i, j, 0, displacement.getValue()); } delete locationInFromImage; } outputImage->touch(); outputImage->fire(); }
void HxCPDSpatialGraphWarp::warpPoint(const McVec3f& source, McVec3f& target, MovingLeastSquares& mlsInterpolator) { McVec2d curPoint = McVec2d(source.x, source.y); McVec2d warpedPoint = mlsInterpolator.interpolate(curPoint); target = McVec3f(warpedPoint.x, warpedPoint.y, source.z); }