Ejemplo n.º 1
0
        /// <summary>
        /// Tạo và trả về mặt cắt cho đối tượng tường đang xét
        /// </summary>
        /// <param name="linkedDoc">Document chứa đối tượng tường đang xét</param>
        /// <param name="doc">Document liên kết</param>
        /// <param name="id">Địa chỉ Id của đối tượng tường đang xét</param>
        /// <param name="viewName">Tên của mặt cắt trả về</param>
        /// <param name="offset">Giá trị offset từ biên đối tượng tường</param>
        /// <returns></returns>
        public static ViewSection CreateWallSection(Document linkedDoc, Document doc, ElementId id, string viewName, double offset)
        {
            Element e = linkedDoc.GetElement(id);

            if (!(e is Wall))
            {
                throw new Exception("Element is not a wall!");
            }
            Wall wall = (Wall)e;
            Line line = (wall.Location as LocationCurve).Curve as Line;

            ViewFamilyType vft = new FilteredElementCollector(doc).OfClass(typeof(ViewFamilyType)).Cast <ViewFamilyType>().FirstOrDefault <ViewFamilyType>(x => ViewFamily.Section == x.ViewFamily);

            XYZ        p1 = line.GetEndPoint(0), p2 = line.GetEndPoint(1);
            List <XYZ> ps = new List <XYZ> {
                p1, p2
            }; ps.Sort(new ZYXComparer());

            p1 = ps[0]; p2 = ps[1];

            BoundingBoxXYZ bb = wall.get_BoundingBox(null);
            double         minZ = bb.Min.Z, maxZ = bb.Max.Z;

            double l = GeomUtil.GetLength(GeomUtil.SubXYZ(p2, p1));
            double h = maxZ - minZ;
            double w = wall.WallType.Width;

            XYZ min = new XYZ(-l / 2 - offset, minZ - offset, -w - offset);
            XYZ max = new XYZ(l / 2 + offset, maxZ + offset, w + offset);

            Transform tf = Transform.Identity;

            tf.Origin = (p1 + p2) / 2;
            tf.BasisX = GeomUtil.UnitVector(p1 - p2);
            tf.BasisY = XYZ.BasisZ;
            tf.BasisZ = GeomUtil.CrossMatrix(tf.BasisX, tf.BasisY);

            BoundingBoxXYZ sectionBox = new BoundingBoxXYZ()
            {
                Transform = tf, Min = min, Max = max
            };
            ViewSection vs = ViewSection.CreateSection(doc, vft.Id, sectionBox);

            XYZ wallDir = GeomUtil.UnitVector(p2 - p1);
            XYZ upDir   = XYZ.BasisZ;
            XYZ viewDir = GeomUtil.CrossMatrix(wallDir, upDir);

            min = GeomUtil.OffsetPoint(GeomUtil.OffsetPoint(p1, -wallDir, offset), -viewDir, offset);
            min = new XYZ(min.X, min.Y, minZ - offset);
            max = GeomUtil.OffsetPoint(GeomUtil.OffsetPoint(p2, wallDir, offset), viewDir, offset);
            max = new XYZ(max.X, max.Y, maxZ + offset);

            tf  = vs.get_BoundingBox(null).Transform.Inverse;
            max = tf.OfPoint(max);
            min = tf.OfPoint(min);
            double maxx = 0, maxy = 0, maxz = 0, minx = 0, miny = 0, minz = 0;

            if (max.Z > min.Z)
            {
                maxz = max.Z;
                minz = min.Z;
            }
            else
            {
                maxz = min.Z;
                minz = max.Z;
            }


            if (Math.Round(max.X, 4) == Math.Round(min.X, 4))
            {
                maxx = max.X;
                minx = minz;
            }
            else if (max.X > min.X)
            {
                maxx = max.X;
                minx = min.X;
            }

            else
            {
                maxx = min.X;
                minx = max.X;
            }

            if (Math.Round(max.Y, 4) == Math.Round(min.Y, 4))
            {
                maxy = max.Y;
                miny = minz;
            }
            else if (max.Y > min.Y)
            {
                maxy = max.Y;
                miny = min.Y;
            }

            else
            {
                maxy = min.Y;
                miny = max.Y;
            }

            BoundingBoxXYZ sectionView = new BoundingBoxXYZ();

            sectionView.Max = new XYZ(maxx, maxy, maxz);
            sectionView.Min = new XYZ(minx, miny, minz);

            vs.get_Parameter(BuiltInParameter.VIEWER_VOLUME_OF_INTEREST_CROP).Set(ElementId.InvalidElementId);

            vs.get_Parameter(BuiltInParameter.VIEWER_BOUND_FAR_CLIPPING).Set(0);

            vs.CropBoxActive  = true;
            vs.CropBoxVisible = true;

            doc.Regenerate();

            vs.CropBox = sectionView;
            vs.Name    = viewName;
            return(vs);
        }