package edu.stanford.rsl.conrad.geometry.motion; import java.util.ArrayList; import edu.stanford.rsl.conrad.geometry.shapes.simple.PointND; import edu.stanford.rsl.conrad.geometry.splines.SurfaceBSpline; import edu.stanford.rsl.conrad.geometry.splines.TimeVariantSurfaceBSpline; import edu.stanford.rsl.conrad.geometry.transforms.Translation; import edu.stanford.rsl.conrad.numerics.SimpleVector; import edu.stanford.rsl.conrad.phantom.xcat.CombinedBreathingHeartScene; import edu.stanford.rsl.conrad.utils.TessellationUtil; public class CombinedBreathingHeartMotionField extends ParzenWindowMotionField { /** * */ private static final long serialVersionUID = 4787248458841471038L; private CombinedBreathingHeartScene breathingHeartScene; public CombinedBreathingHeartMotionField(CombinedBreathingHeartScene scene, double sigma){ super(sigma); this.breathingHeartScene = scene; } @Override PointND[] getRasterPoints(double time) { PointND[] result = timePointMap.get(time); if (result == null){ ArrayList<PointND[]> allPoints= new ArrayList<PointND[]>(); int sizes = 0; // Deformation caused by the breathing splines ArrayList<TimeVariantSurfaceBSpline> variants = breathingHeartScene.getBreathing().getVariants(); for(int i=0; i< variants.size(); i++){ PointND [] current = variants.get(i).getRasterPoints( TessellationUtil.getSamplingU(variants.get(i)), TessellationUtil.getSamplingV(variants.get(i)), breathingHeartScene.getBreathing().getTimeWarper().warpTime(time)); allPoints.add(current); sizes += current.length; } // fixed points that are time invariant in the breathing scene ArrayList<SurfaceBSpline> invariants = breathingHeartScene.getBreathing().getSplines(); for(int i=0; i< invariants.size(); i++){ PointND [] current = invariants.get(i).getRasterPoints( TessellationUtil.getSamplingU(invariants.get(i)), TessellationUtil.getSamplingV(invariants.get(i))); allPoints.add(current); sizes += current.length; } SimpleVector diaphragmMotion =(breathingHeartScene.getBreathing().getDiaphragmMotionVector(0, time)); // Deformation caused by the motion of the heart. variants = breathingHeartScene.getHeart().getVariants(); for(int i=0; i< variants.size(); i++){ PointND [] current = variants.get(i).getRasterPoints( TessellationUtil.getSamplingU(variants.get(i)), TessellationUtil.getSamplingV(variants.get(i)), breathingHeartScene.getHeart().getTimeWarper().warpTime(time)); for (int j =0;j<current.length;j++){ current[j].applyTransform(breathingHeartScene.getHeartTranslation()); current[j].applyTransform(new Translation(diaphragmMotion)); } allPoints.add(current); sizes += current.length; } result = new PointND[sizes]; sizes = 0; for(int i=0; i< allPoints.size(); i++){ PointND[] current = allPoints.get(i); for (int j=0;j<current.length;j++){ result[j+sizes] = current[j]; } sizes += current.length; } timePointMap.put(time, result); } return result; } /** * @param breathingHeartScene the breathingHeartScene to set */ public void setBreathingHeartScene(CombinedBreathingHeartScene breathingHeartScene) { this.breathingHeartScene = breathingHeartScene; } /** * @return the breathingHeartScene */ public CombinedBreathingHeartScene getBreathingHeartScene() { return breathingHeartScene; } } /* * Copyright (C) 2010-2014 Andreas Maier * CONRAD is developed as an Open Source project under the GNU General Public License (GPL). */