Пример #1
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            List <Mesh> bricks      = new List <Mesh>();
            Point3d     center_d    = new Point3f();
            double      mortarth_d  = 8;
            double      tolerence_d = 0.1;

            if (!DA.GetDataList("Bricks", bricks))
            {
                return;
            }
            if (!DA.GetData("Center", ref center_d))
            {
                return;
            }
            if (!DA.GetData("MortarThickness", ref mortarth_d))
            {
                return;
            }
            if (!DA.GetData("zTolerence", ref tolerence_d))
            {
                return;
            }

            if (bricks.Count == 0)
            {
                return;
            }

            if (!bricks[0].IsValid)
            {
                return;
            }
            if (!center_d.IsValid)
            {
                return;
            }

            if (tolerence_d <= 0)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "zTolerence must be positive");
                return;
            }
            if (mortarth_d <= 0)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "MortarThickness must be positive");
                return;
            }

            Point3f center    = GeometryTools.D2F(center_d);
            float   mortarth  = (float)mortarth_d;
            float   tolerence = (float)tolerence_d;

            List <float>     z_list       = new List <float>();
            List <Plane>     planes_list  = new List <Plane>();
            List <string>    types_list   = new List <string>();
            List <Point3f[]> corners_list = new List <Point3f[]>();

            for (int i = 0; i < bricks.Count; i++)
            {
                Mesh           this_brick  = bricks[i];
                List <Point3f> vertices    = new List <Point3f>();
                List <float>   zs          = new List <float>();
                List <Point3f> this_corner = new List <Point3f>();
                Plane          this_plane  = new Plane();

                //读取所有顶点,检测是否为8个
                vertices = this_brick.Vertices.ToList();
                GeometryTools.PurifyPoints(ref vertices, 0.1f);
                if (vertices.Count != 8)
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "For a brick, there must be 8 vertices, now here is" + vertices.Count.ToString());
                    return;
                }

                //将顶点根据高度排序
                for (int j = 0; j < vertices.Count; j++)
                {
                    zs.Add(vertices[j].Z);
                }
                if (!DataTools.Sort(ref zs, ref vertices))
                {
                    return;
                }

                //提取出上顶点并按3241象限顺序排序
                for (int j = 4; j < vertices.Count; j++)
                {
                    this_corner.Add(vertices[j]);
                }
                if (!GeometryTools.Sortby3241Q(ref this_corner, center))
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Has slanted bricks");
                    GeometryTools.Sortby3241D(ref this_corner, center);
                    if (GeometryTools.Distance(this_corner[0], this_corner[2]) > GeometryTools.Distance(this_corner[0], this_corner[3]))
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Geometric error");
                        return;
                    }
                }

                //检验砖块是否存在几何错误
                if (GeometryTools.Distance(this_corner[0], this_corner[2]) > GeometryTools.Distance(this_corner[0], this_corner[3]))
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Geometrical Error.");
                    return;
                }

                //将砖块类型及放砖坐标系加入列表
                if (GeometryTools.Distance(this_corner[0], this_corner[1]) - GeometryTools.Distance(this_corner[0], this_corner[2]) > 50)
                {
                    types_list.Add("Vertical");
                    this_plane = new Plane(GeometryTools.Average(this_corner), GeometryTools.P2P(this_corner[0], this_corner[2]), GeometryTools.P2P(this_corner[0], this_corner[1]));
                }
                else if (GeometryTools.Distance(this_corner[0], this_corner[2]) - GeometryTools.Distance(this_corner[0], this_corner[1]) > 50)
                {
                    types_list.Add("Horizontal");
                    this_plane = new Plane(GeometryTools.Average(this_corner), GeometryTools.P2P(this_corner[0], this_corner[2]), GeometryTools.P2P(this_corner[0], this_corner[1]));
                }
                else
                {
                    types_list.Add("Half");
                    this_plane = new Plane(GeometryTools.Average(new Point3f[] { this_corner[0], this_corner[1] }), GeometryTools.P2P(this_corner[0], this_corner[2]), GeometryTools.P2P(this_corner[0], this_corner[1]));
                }
                planes_list.Add(this_plane);

                //将坐标系原点高度加入列表
                z_list.Add((float)this_plane.Origin.Z);

                //将上顶点加入列表
                corners_list.Add(this_corner.ToArray());
            }

            //将各元素按高度排序
            List <float> z_list_copy1 = new List <float>(z_list);
            List <float> z_list_copy2 = new List <float>(z_list);

            if (!DataTools.Sort(ref z_list_copy1, ref planes_list))
            {
                return;
            }
            if (!DataTools.Sort(ref z_list_copy2, ref types_list))
            {
                return;
            }
            if (!DataTools.Sort(ref z_list, ref corners_list))
            {
                return;
            }

            DataTree <Plane>   planes  = new DataTree <Plane>();
            DataTree <string>  types   = new DataTree <string>();
            DataTree <Point3f> corners = new DataTree <Point3f>();

            int              now_floor   = 0;
            float            now_z       = 0;
            List <Plane>     now_planes  = new List <Plane>();
            List <string>    now_types   = new List <string>();
            List <Point3f[]> now_corners = new List <Point3f[]>();
            GH_Path          now_path1   = new GH_Path();
            GH_Path          now_path2   = new GH_Path();

            for (int i = 0; i < z_list.Count; i++)
            {
                //常执行
                planes_list[i] = GeometryTools.Move(planes_list[i], 0, 0, now_floor * mortarth);
                for (int j = 0; j < 4; j++)
                {
                    corners_list[i][j] = GeometryTools.Move(corners_list[i][j], 0, 0, now_floor * mortarth);
                }

                //第一个元素
                if (i == 0)
                {
                    now_floor = 0;
                    now_z     = z_list[i];

                    now_planes.Clear();
                    now_types.Clear();
                    now_corners.Clear();

                    now_planes.Add(planes_list[i]);
                    now_types.Add(types_list[i]);
                    now_corners.Add(corners_list[i]);
                }

                //最后一个元素
                else if (i == z_list.Count - 1)
                {
                    now_planes.Add(planes_list[i]);
                    now_types.Add(types_list[i]);
                    now_corners.Add(corners_list[i]);

                    List <Plane> now_planes_copy = new List <Plane>(now_planes);
                    GeometryTools.SortbyClock(ref now_planes_copy, ref now_types, center);
                    GeometryTools.SortbyClock(ref now_planes, ref now_corners, center);

                    now_path1 = new GH_Path();
                    now_path1.FromString("{" + now_floor.ToString() + "}");
                    planes.AddRange(now_planes, now_path1);
                    types.AddRange(now_types, now_path1);

                    for (int j = 0; j < now_corners.Count; j++)
                    {
                        now_path2 = new GH_Path();
                        now_path2.FromString("{" + now_floor.ToString() + ";" + j.ToString() + "}");
                        corners.AddRange(now_corners[j].ToList(), now_path2);
                    }
                }

                //没有高度突变
                else if (Math.Abs(z_list[i] - now_z) < tolerence)
                {
                    now_planes.Add(planes_list[i]);
                    now_types.Add(types_list[i]);
                    now_corners.Add(corners_list[i]);
                }

                //高度突变
                else
                {
                    List <Plane> now_planes_copy = new List <Plane>(now_planes);
                    GeometryTools.SortbyClock(ref now_planes_copy, ref now_types, center);
                    GeometryTools.SortbyClock(ref now_planes, ref now_corners, center);

                    now_path1 = new GH_Path();
                    now_path1.FromString("{" + now_floor.ToString() + "}");
                    planes.AddRange(now_planes, now_path1);
                    types.AddRange(now_types, now_path1);

                    for (int j = 0; j < now_corners.Count; j++)
                    {
                        now_path2 = new GH_Path();
                        now_path2.FromString("{" + now_floor.ToString() + ";" + j.ToString() + "}");
                        corners.AddRange(now_corners[j].ToList(), now_path2);
                    }

                    now_planes.Clear();
                    now_types.Clear();
                    now_corners.Clear();

                    planes_list[i] = GeometryTools.Move(planes_list[i], 0, 0, mortarth);
                    for (int j = 0; j < 4; j++)
                    {
                        corners_list[i][j] = GeometryTools.Move(corners_list[i][j], 0, 0, mortarth);
                    }

                    now_planes.Add(planes_list[i]);
                    now_types.Add(types_list[i]);
                    now_corners.Add(corners_list[i]);

                    now_floor++;
                    now_z = z_list[i];
                }
            }

            DA.SetDataTree(0, planes);
            DA.SetDataTree(1, types);
            DA.SetDataTree(2, corners);
        }
Пример #2
0
        /// <summary>
        /// 根据一个中心点(3f)顺时针对一组坐标系和一组对应值进行排序,键值顺序改变
        /// </summary>
        /// <param name="planes"></param>
        /// <param name="center"></param>
        /// <returns></returns>
        public static void SortbyClock <T>(ref List <Plane> planes, ref List <T> values, Point3f center)
        {
            List <Point3f> origins = new List <Point3f>();

            for (int i = 0; i < planes.Count; i++)
            {
                origins.Add(D2F(planes[i].Origin));
            }
            Point3f  average = Average(origins);
            Vector3f vector1 = P2P(center, average);

            List <float>[] distances   = new List <float> [5];
            List <Plane>[] part_planes = new List <Plane> [5];
            List <T>[]     part_values = new List <T> [5];
            for (int i = 0; i < 5; i++)
            {
                distances[i]   = new List <float>();
                part_planes[i] = new List <Plane>();
                part_values[i] = new List <T>();
            }
            for (int i = 0; i < origins.Count; i++)
            {
                Vector3f vector2  = P2P(center, origins[i]);
                int      quadrant = Quadrant(vector1, vector2);
                distances[quadrant].Add(Distance(origins[i], average));
                part_planes[quadrant].Add(planes[i]);
                part_values[quadrant].Add(values[i]);
            }
            for (int i = 0; i < 5; i++)
            {
                if (distances[i].Count != 0)
                {
                    List <float> _distance = new List <float>(distances[i]);
                    DataTools.Sort(ref _distance, ref part_planes[i]);
                    DataTools.Sort(ref distances[i], ref part_values[i]);
                }
            }
            part_planes[4].Reverse();
            part_values[4].Reverse();
            part_planes[2].Reverse();
            part_values[2].Reverse();
            planes.Clear();
            values.Clear();
            if (part_planes[3].Count != 0)
            {
                planes.AddRange(part_planes[3]);
            }
            if (part_planes[2].Count != 0)
            {
                planes.AddRange(part_planes[2]);
            }
            if (part_planes[1].Count != 0)
            {
                planes.AddRange(part_planes[1]);
            }
            if (part_planes[4].Count != 0)
            {
                planes.AddRange(part_planes[4]);
            }
            if (part_values[3].Count != 0)
            {
                values.AddRange(part_values[3]);
            }
            if (part_values[2].Count != 0)
            {
                values.AddRange(part_values[2]);
            }
            if (part_values[1].Count != 0)
            {
                values.AddRange(part_values[1]);
            }
            if (part_values[4].Count != 0)
            {
                values.AddRange(part_values[4]);
            }
        }
Пример #3
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            Mesh    brick    = new Mesh();
            Point3d center_d = new Point3f();
            GH_Structure <GH_String> raw_types = new GH_Structure <GH_String>();

            if (!DA.GetData("Brick", ref brick))
            {
                return;
            }
            if (!DA.GetData("Center", ref center_d))
            {
                return;
            }
            if (!DA.GetDataTree("Types", out raw_types))
            {
                return;
            }

            if (raw_types.DataCount == 0)
            {
                return;
            }

            if (!raw_types.get_DataItem(0).IsValid)
            {
                return;
            }
            if (!center_d.IsValid)
            {
                return;
            }

            if (!DataTools.IsTreeDimension2(raw_types))
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Wrong tree structure of types, please use {0}{1} type");
                return;
            }

            Point3f center = GeometryTools.D2F(center_d);
            List <List <string> > types = DataTools.TreeToList2(raw_types);

            List <Point3f> vertices  = new List <Point3f>();
            List <Line>    lines     = new List <Line>();
            List <float>   distances = new List <float>();
            List <Point3f> corners   = new List <Point3f>();
            Point3f        corner    = new Point3f();
            Point3f        average   = new Point3f();
            Point3f        average2  = new Point3f();

            //读取所有顶点,检测是否为8个
            vertices = brick.Vertices.ToList();
            GeometryTools.PurifyPoints(ref vertices, 0.1f);
            if (vertices.Count != 8)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "For a brick, there must be 8 vertices, now here is" + vertices.Count.ToString());
                return;
            }

            //取出各边,按边长排序
            for (int i = 0; i < vertices.Count - 1; i++)
            {
                for (int j = i + 1; j < vertices.Count; j++)
                {
                    lines.Add(new Line(vertices[i], vertices[j]));
                    distances.Add(GeometryTools.Distance(vertices[i], vertices[j]));
                }
            }
            DataTools.Sort(ref distances, ref lines);

            //取出最短四条边的上顶点
            for (int i = 0; i < 4; i++)
            {
                Point3f from = GeometryTools.D2F(lines[i].From);
                Point3f to   = GeometryTools.D2F(lines[i].To);
                float   z1   = from.Z;
                float   z2   = to.Z;
                if (z1 > z2)
                {
                    corners.Add(from);
                }
                else
                {
                    corners.Add(to);
                }
            }

            //按据角点距离排序顶点
            distances.Clear();
            for (int i = 0; i < corners.Count; i++)
            {
                distances.Add(GeometryTools.Distance(corners[i], center));
            }
            DataTools.Sort(ref distances, ref corners);
            corner = corners[0];
            distances.Clear();
            for (int i = 0; i < corners.Count; i++)
            {
                distances.Add(GeometryTools.Distance(corners[i], corner));
            }
            DataTools.Sort(ref distances, ref corners);

            average  = GeometryTools.Average(corners);
            average2 = GeometryTools.Average(new Point3f[] { corners[2], corners[3] });
            average2 = GeometryTools.Average(new Point3f[] { average, average2 });

            List <List <Plane> > planes_list = new List <List <Plane> >();

            //生成抓取坐标系
            for (int i = 0; i < types.Count; i++)
            {
                planes_list.Add(new List <Plane>());
                for (int j = 0; j < types[i].Count; j++)
                {
                    if (types[i][j] == "Horizontal" || types[i][j] == "Half")
                    {
                        planes_list[i].Add(new Plane(average, GeometryTools.P2P(corners[0], corners[2]), GeometryTools.P2P(corners[0], corners[1])));
                    }
                    else if (types[i][j] == "Vertical")
                    {
                        planes_list[i].Add(new Plane(average, GeometryTools.P2P(corners[0], corners[1]), GeometryTools.P2P(corners[0], corners[2])));
                    }
                    else
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Wrong type name");
                        return;
                    }
                }
            }

            DataTree <Plane> plane = DataTools.ListToTree2(planes_list);

            Plane home = planes_list[0][0];

            home = GeometryTools.Move(home, home.ZAxis * 200);

            DA.SetDataTree(0, plane);
            DA.SetData("Home", home);
        }
Пример #4
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            GH_Structure <GH_Plane>  raw_bricks  = new GH_Structure <GH_Plane>();
            GH_Structure <GH_String> raw_types   = new GH_Structure <GH_String>();
            GH_Structure <GH_Point>  raw_corners = new GH_Structure <GH_Point>();
            Plane  suckerCenter = new Plane();
            Plane  sensorCenter = new Plane();
            Plane  homePlane    = new Plane();
            double retreat      = 160;

            if (!DA.GetDataTree("Bricks", out raw_bricks))
            {
                return;
            }
            if (!DA.GetDataTree("Types", out raw_types))
            {
                return;
            }
            if (!DA.GetDataTree("Corners", out raw_corners))
            {
                return;
            }
            if (!DA.GetData("SuckerCenter", ref suckerCenter))
            {
                return;
            }
            if (!DA.GetData("SensorCenter", ref sensorCenter))
            {
                return;
            }
            if (!DA.GetData("HomePlane", ref homePlane))
            {
                return;
            }
            if (!DA.GetData("Retreat", ref retreat))
            {
                return;
            }

            if (raw_bricks.DataCount == 0)
            {
                return;
            }
            if (raw_types.DataCount == 0)
            {
                return;
            }
            if (raw_corners.DataCount == 0)
            {
                return;
            }

            if (!raw_bricks.get_DataItem(0).IsValid)
            {
                return;
            }
            if (!raw_types.get_DataItem(0).IsValid)
            {
                return;
            }
            if (!raw_corners.get_DataItem(0).IsValid)
            {
                return;
            }

            if (!DataTools.IsTreeDimension2(raw_bricks))
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Wrong tree structure of bricks, please use {0}{1} type");
                return;
            }
            if (!DataTools.IsTreeDimension2(raw_types))
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Wrong tree structure of types, please use {0}{1} type");
                return;
            }
            if (!DataTools.IsTreeDimension3(raw_corners))
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Wrong tree structure of corners, please use {0;0}{0;1} type");
                return;
            }
            if (!DataTools.IsTreeMatch23(raw_bricks, raw_corners))
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Bricks and corners does not match");
                return;
            }
            if (!DataTools.IsTreeMatch23(raw_types, raw_corners))
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Types and corners does not match");
                return;
            }
            if (retreat < 0)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Retreat must not be negative");
                return;
            }

            List <List <Plane> >           bricks  = DataTools.TreeToList2(raw_bricks);
            List <List <string> >          types   = DataTools.TreeToList2(raw_types);
            List <List <List <Point3d> > > corners = DataTools.TreeToList3(raw_corners);

            List <List <Plane> >  targets_list = new List <List <Plane> >();
            List <List <string> > names_list   = new List <List <string> >();

            string[] title = { "Floor", "Middle", "Brick", "Sensor" };

            for (int i = 0; i < bricks.Count - 1; i++)
            {
                targets_list.Add(new List <Plane>());
                names_list.Add(new List <string>());

                targets_list[i].Add(GeometryTools.Move(homePlane, new Vector3d(0, 0, (bricks[i][0].OriginZ - bricks[0][0].OriginZ) * 0.8)));
                names_list[i].Add(title[0] + i.ToString() + title[1] + "0");

                for (int j = 0; j < bricks[i].Count; j++)
                {
                    Point3d[] now_points   = new Point3d[4];
                    Point3d[] this_corners = corners[i][j].ToArray();

                    Point3d this_center = GeometryTools.Average(this_corners);

                    if (types[i][j] == "Horizontal" || types[i][j] == "Half")
                    {
                        now_points[0] = GeometryTools.Average(this_center, this_corners[0]);
                        now_points[1] = GeometryTools.Average(this_center, this_corners[1]);
                        now_points[2] = GeometryTools.Average(this_center, this_corners[3]);
                        now_points[3] = GeometryTools.Average(this_center, this_corners[2]);
                    }
                    else if (types[i][j] == "Vertical")
                    {
                        now_points[0] = GeometryTools.Average(this_center, this_corners[1]);
                        now_points[1] = GeometryTools.Average(this_center, this_corners[3]);
                        now_points[2] = GeometryTools.Average(this_center, this_corners[2]);
                        now_points[3] = GeometryTools.Average(this_center, this_corners[0]);
                    }

                    for (int k = 0; k < now_points.Count(); k++)
                    {
                        Plane now_plane = GeometryTools.Move(bricks[i][j], GeometryTools.P2P(bricks[i][j].Origin, now_points[k]));
                        now_plane = GeometryTools.Move(now_plane, 0, 0, retreat - 50);
                        now_plane = GeometryTools.Transform(sensorCenter, suckerCenter, now_plane);

                        targets_list[i].Add(now_plane);
                        names_list[i].Add(title[0] + i.ToString() + title[2] + j.ToString() + title[3] + k.ToString());
                    }
                }

                targets_list[i].Add(GeometryTools.Move(homePlane, new Vector3d(0, 0, (bricks[i][0].OriginZ - bricks[0][0].OriginZ) * 0.8)));
                names_list[i].Add(title[0] + i.ToString() + title[1] + "1");
            }

            DataTree <Plane>  targets = DataTools.ListToTree2(targets_list);
            DataTree <string> names   = DataTools.ListToTree2(names_list);

            DA.SetDataTree(0, targets);
            DA.SetDataTree(1, names);
        }
Пример #5
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            GH_Structure <GH_Plane>  raw_bricks  = new GH_Structure <GH_Plane>();
            GH_Structure <GH_String> raw_types   = new GH_Structure <GH_String>();
            GH_Structure <GH_Point>  raw_corners = new GH_Structure <GH_Point>();
            Plane  suckerCenter     = new Plane();
            Plane  nozzleCenter     = new Plane();
            Plane  homePlane        = new Plane();
            double horizontalBorder = 25;
            double verticalBorder   = 25;
            double gap     = 25;
            double retreat = 10;

            if (!DA.GetDataTree("Bricks", out raw_bricks))
            {
                return;
            }
            if (!DA.GetDataTree("Types", out raw_types))
            {
                return;
            }
            if (!DA.GetDataTree("Corners", out raw_corners))
            {
                return;
            }
            if (!DA.GetData("SuckerCenter", ref suckerCenter))
            {
                return;
            }
            if (!DA.GetData("NozzleCenter", ref nozzleCenter))
            {
                return;
            }
            if (!DA.GetData("HomePlane", ref homePlane))
            {
                return;
            }
            if (!DA.GetData("HorizontalBorder", ref horizontalBorder))
            {
                return;
            }
            if (!DA.GetData("VerticalBorder", ref verticalBorder))
            {
                return;
            }
            if (!DA.GetData("Gap", ref gap))
            {
                return;
            }
            if (!DA.GetData("Retreat", ref retreat))
            {
                return;
            }

            if (raw_bricks.DataCount == 0)
            {
                return;
            }
            if (raw_types.DataCount == 0)
            {
                return;
            }
            if (raw_corners.DataCount == 0)
            {
                return;
            }

            if (!raw_bricks.get_DataItem(0).IsValid)
            {
                return;
            }
            if (!raw_types.get_DataItem(0).IsValid)
            {
                return;
            }
            if (!raw_corners.get_DataItem(0).IsValid)
            {
                return;
            }

            if (!DataTools.IsTreeDimension2(raw_bricks))
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Wrong tree structure of bricks, please use {0}{1} type");
                return;
            }
            if (!DataTools.IsTreeDimension2(raw_types))
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Wrong tree structure of types, please use {0}{1} type");
                return;
            }
            if (!DataTools.IsTreeDimension3(raw_corners))
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Wrong tree structure of corners, please use {0;0}{0;1} type");
                return;
            }
            if (!DataTools.IsTreeMatch23(raw_bricks, raw_corners))
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Bricks and corners does not match");
                return;
            }
            if (!DataTools.IsTreeMatch23(raw_types, raw_corners))
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Types and corners does not match");
                return;
            }
            if (horizontalBorder < 0)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Horizontal border must not be negative");
                return;
            }
            if (verticalBorder < 0)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Vertical border must not be negative");
                return;
            }
            if (gap <= 0)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Gap must be positive");
                return;
            }
            if (retreat < 0)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Retreat must not be negative");
                return;
            }

            List <List <Plane> >           bricks  = DataTools.TreeToList2(raw_bricks);
            List <List <string> >          types   = DataTools.TreeToList2(raw_types);
            List <List <List <Point3d> > > corners = DataTools.TreeToList3(raw_corners);

            List <List <Plane> >  targets_list = new List <List <Plane> >();
            List <List <string> > names_list   = new List <List <string> >();

            string[] title = { "Floor", "Target" };

            for (int i = 0; i < bricks.Count - 1; i++)
            {
                targets_list.Add(new List <Plane>());
                names_list.Add(new List <string>());

                int count = 0;
                targets_list[i].Add(GeometryTools.Move(homePlane, new Vector3d(0, 0, (bricks[i][0].OriginZ - bricks[0][0].OriginZ) * 0.8)));
                names_list[i].Add(title[0] + i.ToString() + title[1] + count.ToString());

                for (int j = 0; j < bricks[i].Count; j++)
                {
                    List <Plane> now_planes     = new List <Plane>();
                    Point3d[]    sorted_corners = new Point3d[4];
                    Point3d[]    this_corners   = corners[i][j].ToArray();

                    if (types[i][j] == "Horizontal" || types[i][j] == "Half")
                    {
                        sorted_corners = this_corners;
                        now_planes     = GeometryTools.Hatch(bricks[i][j], sorted_corners, horizontalBorder, verticalBorder, gap);
                    }
                    else if (types[i][j] == "Vertical")
                    {
                        sorted_corners[0] = this_corners[1];
                        sorted_corners[1] = this_corners[3];
                        sorted_corners[2] = this_corners[0];
                        sorted_corners[3] = this_corners[2];
                        now_planes        = GeometryTools.Hatch(bricks[i][j], sorted_corners, verticalBorder, horizontalBorder, gap);
                    }
                    else
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Wrong type name");
                        return;
                    }

                    for (int k = 0; k < now_planes.Count; k++)
                    {
                        now_planes[k] = GeometryTools.Move(now_planes[k], 0, 0, retreat);
                        now_planes[k] = GeometryTools.Transform(nozzleCenter, suckerCenter, now_planes[k]);
                        if (j == 0 && k == 0)
                        {
                            count++;
                            targets_list[i].Add(GeometryTools.Move(now_planes[k], -bricks[i][j].XAxis * 150));
                            names_list[i].Add(title[0] + i.ToString() + title[1] + count.ToString());
                        }
                        count++;
                        targets_list[i].Add(now_planes[k]);
                        names_list[i].Add(title[0] + i.ToString() + title[1] + count.ToString());
                        if (j == bricks[i].Count - 1 && k == now_planes.Count - 1)
                        {
                            count++;
                            targets_list[i].Add(GeometryTools.Move(now_planes[k], bricks[i][j].XAxis * 150));
                            names_list[i].Add(title[0] + i.ToString() + title[1] + count.ToString());
                        }
                    }
                }

                count++;
                targets_list[i].Add(GeometryTools.Move(homePlane, new Vector3d(0, 0, (bricks[i][0].OriginZ - bricks[0][0].OriginZ) * 0.8)));
                names_list[i].Add(title[0] + i.ToString() + title[1] + count.ToString());
            }

            DataTree <Plane>  targets = DataTools.ListToTree2(targets_list);
            DataTree <string> names   = DataTools.ListToTree2(names_list);

            DA.SetDataTree(0, targets);
            DA.SetDataTree(1, names);
        }