Exemplo n.º 1
0
        /// <summary>
        /// 根据选择的一个平面或者曲线来绘制一个面层对象
        /// </summary>
        /// <param name="uiDoc"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        private Result DrawFromOneFace(UIDocument uiDoc, FaceOptions options)
        {
            Result res = Result.Failed;

            // 在Revit界面中选择表面
            Reference faceRef = SelectSurface(uiDoc, options);

            if (faceRef != null)
            {
                // 1. 选择的单元
                Element struElement = _doc.GetElement(faceRef);

                // 2. 选择的表面
                GeometryObject obj = struElement.GetGeometryObjectFromReference(faceRef);
                if (!(obj is Face))
                {
                    MessageBox.Show("未检测到选择的面!", "提示");
                    return(Result.Failed);
                }
                Face face = (Face)obj;

                // 3. 族实例对象的 变换
                Transform transform = GetElementTransform(struElement);

                // ----------------------------------------------------------------------------------------------------
                // 对不同的选择情况进行分类处理
                using (Transaction tran = new Transaction(_doc, "在选择的面上生成面层"))
                {
                    try
                    {
                        tran.Start();

                        // 根据不同的选择类型进行分类处理
                        if (face is PlanarFace)
                        {
                            PlanarFace pFace = (PlanarFace)face;

                            // 对单元中所有同方向的面均进行绘制进行特殊处理

                            if (options.IncludeSameNormal)
                            {
                                IList <DirectShape> surfaces = ExtendToFacesWithSameNormal(tran, struElement,
                                                                                           pFace, options, transform);

                                // 设置面层对象的位置
                                ElementId[] ids = surfaces.Select(r => r.Id).ToArray();
                                uiDoc.Selection.SetElementIds(ids);
                            }
                            else  // 对于一般的单元进行操作
                            {
                                DirectShape ds = ConstructSurfaceFromPlanarFace(tran, pFace, options, transform);
                                if (ds != null)
                                {
                                    // 设置面层对象的位置
                                    uiDoc.Selection.SetElementIds(new ElementId[] { ds.Id });
                                }
                            }
                        }

                        else
                        {
                            // 将一个曲面转化为多个网格平面
                            SurfaceTriangulator st = new SurfaceTriangulator(face, transform);

                            List <PlanarFace> planarFaces = st.GetMeshedFaces();

                            List <FaceTransform> faceTransforms = planarFaces.Select(r => new FaceTransform(r, Transform.Identity)).ToList();
                            //
                            DirectShape ds = ConstructSurfaceFromPlanarFaces(tran, faceTransforms, options);

                            // throw new InvalidOperationException("无法在不是平面的表面生成面层。");
                        }

                        tran.Commit();
                        return(Result.Succeeded);
                    }
                    catch (Exception ex)
                    {
                        // Utils.ShowDebugCatch(ex, "生成面层出错。");
                        tran.RollBack();
                        throw new InvalidOperationException("生成面层出错。", ex);
                        return(Result.Failed);
                    }
                }
            }
            return(res);
        }
Exemplo n.º 2
0
        //   根据指定的类别与类型来进行面层对象的过滤
        /// <summary>
        ///  从整个文档中的指定集合中 按指定的过滤选项 搜索面层对象
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="elementIds"> 如果其值为null,则表示过滤集合为整个文档中的所有单元 </param>
        /// <returns></returns>
        private IList <ElementId> Filterfaces(Document doc, ICollection <ElementId> elementIds, FaceOptions opt)
        {
            List <ElementId> faces = new List <ElementId>();

            FilteredElementCollector coll;

            coll = (elementIds == null) ? new FilteredElementCollector(doc) : new FilteredElementCollector(doc, elementIds);

            // 首先判断类型 与 过滤指定的类别
            coll.OfClass(typeof(DirectShape)).OfCategoryId(opt.CategoryId);

            // 跟据参数值进行过滤
            string tag;

            foreach (Element ele in coll)
            {
                WallFace wallface;

                if (!WallFace.IsWallFace(ele as DirectShape, out wallface))
                {
                    continue;
                }

                // 2. 过滤面层类型,如“防水”
                bool hasType = wallface.GetFaceType(out tag);
                if (!hasType || tag == null || !tag.Equals(opt.FaceType, StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                // 满足所有过滤条件
                faces.Add(ele.Id);
            }

            return(faces);
        }
Exemplo n.º 3
0
        /// <summary>
        /// 为面层实体设置颜色、类型等参数
        /// </summary>
        /// <param name="tran"></param>
        /// <param name="ds"></param>
        /// <param name="volumn"></param>
        /// <param name="area"></param>
        /// <param name="faceOptions"></param>
        private void SetParameters(Transaction tran, DirectShape ds, double volumn, double area, FaceOptions faceOptions)
        {
            // 设置实体对象在指定视力中的填充颜色
            OverrideGraphicSettings gs = _view.GetElementOverrides(ds.Id);

            // 填充颜色
            gs.SetProjectionFillColor(faceOptions.Color);

            // 填充模式

            string             fillPatternName = "实体填充";
            FillPatternElement fpe             = FillPatternElement.GetFillPatternElementByName(_doc, FillPatternTarget.Drafting, fillPatternName);

            if (fpe == null)
            {
                fpe = FillPatternElement.Create(_doc,
                                                new FillPattern(fillPatternName, FillPatternTarget.Drafting, FillPatternHostOrientation.ToHost));
            }

            gs.SetProjectionFillPatternId(fpe.Id);
            gs.SetProjectionFillPatternVisible(true);
            _view.SetElementOverrides(ds.Id, gs);

            // 设置参数
            Parameter p;

            // 面层对象标识
            p = ds.get_Parameter(FaceWallParameters.sp_FaceIdTag_guid);
            if (p != null)
            {
                p.Set(FaceWallParameters.FaceIdentificaion);
            }

            // 面积
            p = ds.get_Parameter(FaceWallParameters.sp_Area_guid);
            if (p != null)
            {
                p.Set(area);
            }

            // 体积
            p = ds.get_Parameter(FaceWallParameters.sp_Volumn_guid);
            if (p != null)
            {
                p.Set(volumn);
            }

            // 类型
            p = ds.get_Parameter(FaceWallParameters.sp_FaceType_guid);
            if (p != null)
            {
                p.Set(faceOptions.FaceType);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// 将多个平面生成为一个面层对象
        /// </summary>
        /// <param name="docTran">  </param>
        /// <param name="faceTransforms"> 键表示用来生成面层的多个面,对应的值表示将 face 对象 转换到模型空间中所需要进行的变换 </param>
        /// <param name="faceOp"> 生成面层的选项 </param>
        /// <returns> 如果新生成的面层实体或者进行剪切后的实体体积太小,则认为不会生成此实体(在施工中也不可能考虑如此精细的施工),此时返回 null</returns>
        private DirectShape ConstructSurfaceFromPlanarFaces(Transaction docTran, List <FaceTransform> faceTransforms, FaceOptions faceOp)
        {
            IList <Solid> solids = new List <Solid>();

            foreach (FaceTransform face_Transform in faceTransforms)
            {
                PlanarFace face      = face_Transform.planarFace;
                Transform  transform = face_Transform.transform;

                Solid solid = ExtrudeSolid(face, transform, faceOp.SurfaceThickness);
                solids.Add(solid);
            }


            docTran.SetName("通过多个平面来生成一个面层对象");
            // create direct shape and assign the sphere shape
            DirectShape ds = DirectShape.CreateElement(_doc, faceOp.CategoryId,
                                                       "Application id",
                                                       "Geometry object id");

            ds.SetShape(solids.Select(r => r as GeometryObject).ToList());

            _doc.Regenerate();

            bool reSetFace = false; // 是否要将当前的面层对象删除后再重新生成


            bool hasIntersect;
            // 将初步生成的面层对象与周围的环境相剪切,并返回剪切后的实体集合。
            // 集合中的Solid的体积可能为零,说明它已经被剪切掉了,但是其定义还在。
            IList <Solid> extrudedSolids = ExcludeIntersect(ds, solids, out hasIntersect);

            // 在将此面层对象中的多个Solid进行组合之前,先获取到面层对象的面积

            double area  = 0;
            int    index = 0;

            foreach (var faceTransform in faceTransforms)
            {
                PlanarFace f         = faceTransform.planarFace;
                Transform  transform = faceTransform.transform;
                //
                Solid solid = extrudedSolids[index];
                if (solid.Volume > 0)
                {
                    Face face = CorrespondFace(solid, f, transform);
                    //
                    area += face.Area;
                }
                //
                index += 1;
            }

            IList <Solid> finnalSolids;

            if (faceOp.UnionInnerSolids)
            {
                // 将此面层对象中的多个Solid进行组合,最后集合中就只包含一个用来Union的Solid,以及不能成功被Union的Solids。
                finnalSolids = UnionSolid(extrudedSolids);
            }
            else
            {
                finnalSolids = extrudedSolids;
            }

            // 计算组合之后的最终面层的真实体积。

            double volumn = finnalSolids.Sum(s => s.Volume);

            // 不管原来生成的面层对象与周围环境是否有相交,都删除原来的实体,并根据剪切后的实体重新创建
            _doc.Delete(ds.Id);

            // create direct shape and assign the sphere shape
            ds = DirectShape.CreateElement(_doc, faceOp.CategoryId,
                                           "Application id",
                                           "Geometry object id");
            ds.SetShape(finnalSolids.Select(r => r as GeometryObject).ToList());
            // ds.SetShape(new GeometryObject[] { unionedSolid });

            //  设置面层单元的各种参数
            SetParameters(docTran, ds, volumn: volumn, area: area, faceOptions: faceOp);

            return(ds);
        }
Exemplo n.º 5
0
        /// <summary>
        /// 从单一平面来生成面层对象
        /// </summary>
        /// <param name="face"> 用来生成面层的那个面 </param>
        /// <param name="faceOp"> 生成面层的选项 </param>
        /// <returns> 如果新生成的面层实体或者进行剪切后的实体体积太小,则认为不会生成此实体(在施工中也不可能考虑如此精细的施工),此时返回 null</returns>
        /// <param name="transform"> 从族几何到实例对象的变换 </param>
        private DirectShape ConstructSurfaceFromPlanarFace(Transaction docTran, PlanarFace face, FaceOptions faceOp, Transform transform)
        {
            Solid solid = ExtrudeSolid(face, transform, faceOp.SurfaceThickness);

            if (solid.Volume < 0.00001)
            {
                // 如果新生成的面层实体体积太小,则认为不会生成此实体(在施工中也不可能考虑如此精细的施工)
                return(null);
            }

            docTran.SetName("生成面层");

            // create direct shape and assign the sphere shape

            DirectShape ds = DirectShape.CreateElement(_doc, faceOp.CategoryId,
                                                       "Application id",
                                                       "Geometry object id");

            ds.SetShape(new GeometryObject[] { solid });

            _doc.Regenerate();

            // 判断生成的实体与周围的结构的相交关系
            bool          hasIntersect;
            IList <Solid> solids = ExcludeIntersect(ds, new Solid[] { solid }, out hasIntersect);

            if (hasIntersect)
            {
                if (!solids.Any())
                {
                    // 如果新生成的面层实体体积太小,则认为不会生成此实体(在施工中也不可能考虑如此精细的施工)
                    _doc.Delete(ds.Id);
                    return(null);
                }

                solid = solids.First();

                // 删除原来的实体,并根据剪切后的实体重新创建
                _doc.Delete(ds.Id);

                if (solid.Volume < 0.000001)
                {
                    // 如果新生成的面层实体被剪切之后体积太小,则认为不会生成此实体(在施工中也不可能考虑如此精细的施工)
                    return(null);
                }
                else
                {
                    // create direct shape and assign the sphere shape
                    ds = DirectShape.CreateElement(_doc, faceOp.CategoryId,
                                                   "Application id",
                                                   "Geometry object id");
                    ds.SetShape(new GeometryObject[] { solid });
                }
            }

            PlanarFace pFace = CorrespondFace(solid, face, transform);

            //  设置面层单元的各种参数
            SetParameters(docTran, ds, volumn: solid.Volume, area: pFace.Area, faceOptions: faceOp);

            return(ds);
        }
Exemplo n.º 6
0
        /// <summary>
        /// 将楼梯中所有与选择的表面相同方向的面上都生成面层
        /// </summary>
        /// <param name="docTran">  </param>
        /// <param name="elem"> 用来生成面层的单元。此函数会搜索此单元中所有与 baseFace 同法向的面,并进行面层的绘制 </param>
        /// <param name="pickedFace"> 楼梯中用来生成面层的那个面</param>
        /// <param name="faceOp"> 生成面层的选项</param>
        /// <param name="transf"> </param>
        /// <returns></returns>
        private IList <DirectShape> ExtendToFacesWithSameNormal(Transaction docTran, Element elem, PlanarFace pickedFace, FaceOptions faceOp, Transform transf)
        {
            IList <DirectShape> directShapes = new List <DirectShape>();

            // 值中的false 表示solid 是 Family中的solid,后期还要再进行一次transform才能变换 Familyinstance 所对应的位置
            Dictionary <Solid, bool> solids = GeoHelper.GetSolidsInModel(elem, GeoHelper.SolidVolumnConstraint.Positive);

            foreach (Solid solid in solids.Keys)
            {
                foreach (Face face in solid.Faces)
                {
                    if ((face is PlanarFace))
                    {
                        PlanarFace planarFace = (PlanarFace)face;

                        if (GeoHelper.IsSameDirection(planarFace.FaceNormal, transf.OfVector(pickedFace.FaceNormal)))
                        {
                            DirectShape ds = ConstructSurfaceFromPlanarFace(docTran, planarFace, faceOp, Transform.Identity);

                            if (ds != null)
                            {
                                directShapes.Add(ds);
                            }
                        }
                    }
                }
            }

            return(directShapes);
        }
Exemplo n.º 7
0
        /// <summary>
        /// 选择多个面,并将对应的多个面层绘制到一个DirectShape中
        /// </summary>
        /// <param name="uiDoc"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        private Result DrawOneElemWithFaces(UIDocument uiDoc, FaceOptions options)
        {
            Result res = Result.Failed;

            // 在Revit界面中选择表面
            var faceRefs = SelectSurfaces(uiDoc, options);



            if (faceRefs != null && faceRefs.Count > 0)
            {
                // 提取每一个选择的表面,以及对应的单元的 Transform 对象
                List <FaceTransform> faceTransforms = new List <FaceTransform>();
                foreach (Reference faceRef in faceRefs)
                {
                    // 1. 选择的单元
                    Element struElement = _doc.GetElement(faceRef);

                    // 2. 选择的表面
                    GeometryObject obj = struElement.GetGeometryObjectFromReference(faceRef);
                    // 3. 族实例对象的 变换
                    Transform transform = GetElementTransform(struElement);

                    if (!(obj is PlanarFace))
                    {
                        Face face = (Face)obj;

                        // 将一个曲面转化为多个网格平面
                        SurfaceTriangulator st = new SurfaceTriangulator(face, transform);

                        List <PlanarFace> planarFaces = st.GetMeshedFaces();
                        // 一个曲面所对应的所有平面网格
                        List <FaceTransform> ft = planarFaces.Select(r => new FaceTransform(r, Transform.Identity)).ToList();

                        // 将这一个曲面所对应的三角形平面集合添加到总的集合中
                        faceTransforms.AddRange(ft);
                    }
                    else
                    {
                        PlanarFace pFace = (PlanarFace)obj;

                        faceTransforms.Add(new FaceTransform(pFace, transform));
                    }
                }

                // ----------------------------------------------------------------------------------------------------
                // 对不同的选择情况进行分类处理
                using (Transaction tran = new Transaction(_doc, "通过多个平面来生成一个面层对象"))
                {
                    try
                    {
                        tran.Start();

                        DirectShape ds = ConstructSurfaceFromPlanarFaces(tran, faceTransforms, options);

                        if (ds != null)
                        {
                            // 设置面层对象的位置
                            uiDoc.Selection.SetElementIds(new ElementId[] { ds.Id });
                        }

                        tran.Commit();
                        return(Result.Succeeded);
                    }
                    catch (Exception ex)
                    {
                        //  Utils.ShowDebugCatch(ex, "生成面层出错。");
                        tran.RollBack();

                        throw new InvalidOperationException("生成面层出错。", ex);
                        //  return Result.Failed;
                    }
                }
            }
            return(res);
        }