/// <summary> /// This splits a structure into two. It creates a margin around the target, /// so that it approximately crosses the mass center of the structure, and then /// uses boolean operators to create two new structures. Note: due to the nature /// of the segment model in Eclipse, the new structures do not always perfectly cover /// the whole volume of the original structure. /// </summary> /// <param name="s"></param> /// <param name="ss"></param> /// <returns></returns> bool SplitStructure(StructureSet ss, Structure target, Structure roi) { if (ss.CanAddStructure(roi.DicomType, roi.Id + "_spl1")) { Structure newStr1 = ss.AddStructure(roi.DicomType, roi.Id + "_spl1"); Structure newStr2 = ss.AddStructure(roi.DicomType, roi.Id + "_spl2"); VVector targetCenter = target.CenterPoint; VVector roiCenter = roi.CenterPoint; double dist = (targetCenter - roiCenter).Length; //figure out distance from target center to target surface System.Collections.BitArray buffer = new System.Collections.BitArray(100); SegmentProfile profile = target.GetSegmentProfile(targetCenter, roiCenter, buffer); double distToTargetSurface = 0; foreach (SegmentProfilePoint point in profile) { if (point.Value == false) { //first point outside structure distToTargetSurface = (point.Position - targetCenter).Length; break; } } //SegmentVolume seg = target.Margin(dist - distToTargetSurface); SegmentVolume seg = target.LargeMargin(dist - distToTargetSurface); newStr1.SegmentVolume = seg.And(roi); newStr2.SegmentVolume = roi.Sub(newStr1); return(true); } return(false); }
public static double Structure_Distance(ROI roi, ROI ptv, ScriptContext context) { //Get the minimum distance between two rois. double min_distance = 1000; double total_distance = 0; List <Structure> temp_structures = new List <Structure>(); List <Structure> roi_structures = roi.MatchingStructures; List <Structure> ptv_structures = ptv.MatchingStructures; for (int r = 0; r < roi_structures.Count; r++) { for (int p = 0; p < ptv_structures.Count; p++) { Structure roi_structure = roi_structures[r]; Structure ptv_structure = ptv_structures[p]; //First see if they overlap, and if they do, min distance = 0. //Now keep margining the ptv and finding out when an intersection occurs (to get the minimum distance). This minimum distance will be the margin amount. double margin = 0; SegmentVolume margin_seg_vol = ptv_structure.Margin(margin); SegmentVolume overlap_volume = margin_seg_vol.And(roi_structure); Structure overlap_structure = context.StructureSet.AddStructure("CONTROL", "overlap_struc"); Structure margin_structure = context.StructureSet.AddStructure("CONTROL", "margin_struct"); overlap_structure.SegmentVolume = overlap_volume; margin_structure.SegmentVolume = margin_seg_vol; double overlap = overlap_structure.Volume; if (overlap > 0) { System.Windows.MessageBox.Show(roi_structure.Name + " overlaps with " + ptv_structure.Name); return(0); } double last_no = 0; double last_yes = 1000; //these doubles are the last margins used for which there was not an overlap, and for which there was an overlap while (last_yes == 1000) { margin = 50; total_distance += 50; margin_seg_vol = margin_structure.Margin(margin); overlap_volume = margin_seg_vol.And(roi_structure); overlap_structure.SegmentVolume = overlap_volume; margin_structure.SegmentVolume = margin_seg_vol; overlap = overlap_structure.Volume; if (overlap > 0) { last_yes = total_distance; } else { last_no = total_distance; } } //Now get the last_no margin ptv again to start the final iteration. total_distance -= 50; margin_seg_vol = margin_structure.Margin(-50); margin_structure.SegmentVolume = margin_seg_vol; last_yes = 50; last_no = 0; //Do a maximum of 30 iterations int loop_count = 0; do { loop_count++; margin = 0.5 * (last_yes - last_no); margin_seg_vol = margin_structure.Margin(margin); overlap_volume = margin_seg_vol.And(roi_structure); overlap_structure.SegmentVolume = overlap_volume; margin_structure.SegmentVolume = margin_seg_vol; overlap = overlap_structure.Volume; if (overlap > 0) { last_yes = margin; } else { last_no = margin; } context.StructureSet.RemoveStructure(margin_structure); margin_structure = context.StructureSet.AddStructure("CONTROL", "margin_struc"); if (loop_count > 30) { System.Windows.MessageBox.Show("Maxed out with 30 iterations of overlap checking for " + roi.Name); break; } } while (last_yes - last_no > 1); //look until within 1mm of distance total_distance += margin; if (total_distance < min_distance) { total_distance = margin; } context.StructureSet.RemoveStructure(overlap_structure); } } System.Windows.MessageBox.Show(roi.Name + " distance: " + min_distance); return(min_distance); }