/// <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);
        }
        /// <summary>
        /// Because Structure.Margin() has upper limit of 50mm for the margin, this
        /// extension allows larger values.
        /// </summary>
        /// <param name="target"></param>
        /// <param name="ss"></param>
        /// <param name="mm"></param>
        /// <returns></returns>
        public static SegmentVolume LargeMargin(this Structure target, double mm)
        {
            double        mmLeft     = mm;
            SegmentVolume targetLeft = target.SegmentVolume;

            while (mmLeft > 50)
            {
                mmLeft    -= 50;
                targetLeft = targetLeft.Margin(50);
            }
            SegmentVolume result = targetLeft.Margin(mmLeft);

            return(result);
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
 /// <summary>
 /// Crop structure from another structure
 /// </summary>
 /// <param name="structureToCrop"></param>
 /// <param name="StructureToCropFrom"></param>
 /// <param name="cropMargin"></param>
 /// <returns></returns>
 public static SegmentVolume CropStructure(SegmentVolume structureToCrop, SegmentVolume structureToCropFrom, double cropMargin)
 {
     return(structureToCrop.Sub(structureToCropFrom.Margin(cropMargin)));
 }