2 コミット c03be448e5 ... a3ca2a8066

作者 SHA1 メッセージ 日付
  xulisong a3ca2a8066 xxxxxx 5 年 前
  xulisong cf9b0709f3 xls:墙轮廓解析 5 年 前

+ 4 - 0
JBIM/JBIM/Component/Column.cs

@@ -19,5 +19,9 @@ namespace JBIM.Component
     public class Column : VisibleComponentObject
     {
         //是否加上,建筑结构,是否是房间判断等枚举
+        /// <summary>
+        /// 是否是房间边界
+        /// </summary>
+        public bool RoomBoundary { get; set; } = true;
     }
 }

+ 1 - 0
JBIM/JBIM/Component/Door.cs

@@ -21,5 +21,6 @@ namespace JBIM.Component
         public BimId Owner { get; set; }
         public XYZ FaceDirection { get; set; }
         public XYZ HandDirection { get; set; }
+        public double Thick { get; set; }
     }
 }

+ 1 - 0
JBIM/JBIM/Component/Window.cs

@@ -19,5 +19,6 @@ namespace JBIM.Component
     public class Window : VisibleComponentObject
     {
         public BimId Owner { get; set; }
+        public double Thick { get; set; }
     }
 }

+ 9 - 0
JBIM/RevitToJBim/Common/Converter.cs

@@ -43,6 +43,15 @@ namespace RevitToJBim.Common
             return new XYZ() {X = FtToUse(xyz.X), Y = FtToUse(xyz.Y), Z = FtToUse(xyz.Z), };
         }
         /// <summary>
+        /// 转换成向量
+        /// </summary>
+        /// <param name="xyz"></param>
+        /// <returns></returns>
+        public static XYZ ConvertToDirection(Autodesk.Revit.DB.XYZ xyz)
+        {
+            return new XYZ() { X = xyz.X, Y = xyz.Y, Z = xyz.Z, };
+        }
+        /// <summary>
         /// 将点转换成毫米单位形式
         /// </summary>
         /// <param name="xyzes"></param>

+ 35 - 20
JBIM/RevitToJBim/Common/RevitUtil.cs

@@ -18,6 +18,7 @@ using RevitToJBim.MBI;
 using SAGA.DotNetUtils;
 using Parameter=JBIM.Component.Parameter;
 using SAGA.RevitUtils;
+using SAGA.DotNetUtils.Extend;
 
 namespace RevitToJBim.Common
 {
@@ -137,10 +138,11 @@ namespace RevitToJBim.Common
                 var usePoint = xyzs[i];
                 var refDirection = usePoint - location;
                 var offset = refDirection.DotProduct(handDirection);
+                var projectPoint = location.OffsetPoint(handDirection, offset);
                 #region 初始化逻辑
                 if (i == 0)
                 {
-                    minXYZ = maxXYZ = usePoint;
+                    minXYZ = maxXYZ = projectPoint;
                     min = max = offset;
                 }
                 #endregion
@@ -149,13 +151,13 @@ namespace RevitToJBim.Common
                 {
                     if (offset < min)
                     {
-                        minXYZ = usePoint;
+                        minXYZ = projectPoint;
                         min = offset;
                         continue;
                     }
                     if (max < offset)
                     {
-                        maxXYZ = usePoint;
+                        maxXYZ = projectPoint;
                         max = offset;
                         continue;
                     }
@@ -172,13 +174,18 @@ namespace RevitToJBim.Common
         public static List<XYZ> GetVertexPoints(Element element)
         {
             List<XYZ> xyzs = new List<XYZ>();
-            var solids = element.GetSolids();
-            foreach (var solid in solids)
+            //var solids = Extension.GeometryElementExtension.GetSolids(element,element.Document.GetUseView());
+            //foreach (var solid in solids)
+            //{
+            //    foreach (Edge edge in solid.Edges)
+            //    {
+            //        xyzs.AddRange(edge.Tessellate());
+            //    }
+            //}
+            var curves= Extension.GeometryElementExtension.GetGeometryObjects<Curve>(element, element.Document.GetUseView());
+            foreach (var curve in curves)
             {
-                foreach (Edge edge in solid.Edges)
-                {
-                    xyzs.AddRange(edge.Tessellate());
-                }
+                xyzs.AddRange(curve.Tessellate());
             }
             return xyzs.Distinct(new XyzEqualComparer()).ToList();
         }
@@ -190,23 +197,31 @@ namespace RevitToJBim.Common
         /// <returns></returns>
         public static List<List<XYZ>> GetWallPolygon(Wall wall)
         {
-            /*
+            /* 方案1:
              * 1找到墙的定位线,
              * 2将定位线拆分成多段
              * 3按照宽度,将多段定位线生成闭合区域
+             * 方案2:
+             * 直接去墙的顶面,过滤相关face形成轮廓
              */
-            var curve = wall.GetLocationCurve();
-
-
             List<List<XYZ>> polygons = new List<List<XYZ>>();
-            var refs = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Exterior).OfType<Face>();
-            foreach (Face face in refs)
+            #region 过滤墙的顶面         
+            List<PlanarFace> faces = wall.GetTopFaces();
+            #endregion
+            foreach (PlanarFace face in faces)
             {
-                List<XYZ> polygon = new List<XYZ>();
-                //foreach (Curve curve in face.ed)
-                //{
-
-                //}
+                foreach (CurveLoop curveLoop in face.GetEdgesAsCurveLoops())
+                {
+                    if (curveLoop == null)
+                    {
+                        continue;
+                    }
+                    var polygon = curveLoop.GetPolygon();
+                    if (polygon.Any())
+                    {
+                        polygons.Add(polygon);
+                    }
+                }
             }
             return polygons;
         }

+ 3 - 2
JBIM/RevitToJBim/ComponentParse/ParseDoor.cs

@@ -45,6 +45,7 @@ namespace RevitToJBim.ComponentParse
             if (fi.Host != null)
             {
                 jObject.Owner = context.Parser.ParseElement(ElementWrapperFactory.CreateWrapper(fi.Host))?.FirstOrDefault();
+                jObject.Thick = (fi.Host as Autodesk.Revit.DB.Wall).Width.FtToUse();
             }
             var polygonPath = RevitUtil.GetWindowDoorLocation(fi);
             if (polygonPath != null && polygonPath.Any())
@@ -52,8 +53,8 @@ namespace RevitToJBim.ComponentParse
                 Polygon outLine = new Polygon(BimConvert.ConvertToXYZs(polygonPath));
                 jObject.OutLine.Add(outLine);
             }
-            jObject.HandDirection = BimConvert.ConvertToXYZ(fi.HandOrientation);
-            jObject.FaceDirection = BimConvert.ConvertToXYZ(fi.FacingOrientation);
+            jObject.HandDirection = BimConvert.ConvertToDirection(fi.HandOrientation);
+            jObject.FaceDirection = BimConvert.ConvertToDirection(fi.FacingOrientation);
             return new List<BimId>() { jObject.Id };
         }
 

+ 10 - 4
JBIM/RevitToJBim/ComponentParse/ParseWall.cs

@@ -13,6 +13,8 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using JBIM.Definition;
+using RevitToJBim.Common;
 using JWall = JBIM.Component.Wall;
 namespace RevitToJBim.ComponentParse
 {
@@ -39,10 +41,14 @@ namespace RevitToJBim.ComponentParse
             ParseCore.AttachObject(jObject, wrapper);
             context.AddBimObject(jObject);
             jObject.Location = ParseCore.GetLocation(wall.Location);
-            //if (fi.Host != null)
-            //{
-            //    jObject.Owner = context.Parser.ParseElement(ElementWrapperFactory.CreateWrapper(fi.Host))?.FirstOrDefault();
-            //}
+            var polygons = RevitUtil.GetWallPolygon(wall);
+            foreach (var polygon in polygons)
+            {               
+                var outLine = new Polygon(BimConvert.ConvertToXYZs(polygon));
+                jObject.OutLine.Add(outLine);
+            }
+
+            jObject.Width = wall.Width.FtToUse();
 
             return new List<BimId>() { jObject.Id };
         }

+ 4 - 2
JBIM/RevitToJBim/ComponentParse/ParseWindow.cs

@@ -24,11 +24,11 @@ namespace RevitToJBim.ComponentParse
     {
         public override List<string> FastIndex()
         {
-            return new List<string>() { CategoryGenerator.BuildingCategory(JFamilyType.Door) };
+            return new List<string>() { CategoryGenerator.BuildingCategory(JFamilyType.Window) };
         }
         public override bool Match(ElementWrapper wrapper)
         {
-            return wrapper.Category == CategoryGenerator.BuildingCategory(JFamilyType.Door);
+            return wrapper.Category == CategoryGenerator.BuildingCategory(JFamilyType.Window);
         }
 
 
@@ -45,6 +45,7 @@ namespace RevitToJBim.ComponentParse
             if (fi.Host != null)
             {
                 jObject.Owner = context.Parser.ParseElement(ElementWrapperFactory.CreateWrapper(fi.Host))?.FirstOrDefault();
+                jObject.Thick= (fi.Host as Autodesk.Revit.DB.Wall).Width.FtToUse();
             }
             var polygonPath = RevitUtil.GetWindowDoorLocation(fi);
             if (polygonPath != null && polygonPath.Any())
@@ -52,6 +53,7 @@ namespace RevitToJBim.ComponentParse
                 Polygon outLine = new Polygon(BimConvert.ConvertToXYZs(polygonPath));
                 jObject.OutLine.Add(outLine);
             }
+           
             return new List<BimId>() { jObject.Id };
         }
 

+ 34 - 0
JBIM/RevitToJBim/Extension/CurveLoopExtension.cs

@@ -0,0 +1,34 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:CurveLoopExtension
+ * 作者:xulisong
+ * 创建时间: 2019/6/26 17:53:33
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using Autodesk.Revit.DB;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RevitToJBim.Extension
+{
+    public static class CurveLoopExtension
+    {
+        public static List<XYZ> GetPolygon(this CurveLoop curveLoop)
+        {
+            List<XYZ> polygon = new List<XYZ>();
+
+
+            foreach (Curve curve in curveLoop)
+            {
+                var points = curve.Tessellate();
+                points.RemoveAt(points.Count - 1);
+                polygon.AddRange(points);
+            }
+
+            return polygon;
+        }
+    }
+}

+ 116 - 0
JBIM/RevitToJBim/Extension/GeometryElementExtension.cs

@@ -0,0 +1,116 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:GeometryElementExtension
+ * 作者:xulisong
+ * 创建时间: 2019/6/26 16:17:26
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Autodesk.Revit.DB;
+
+namespace RevitToJBim.Extension
+{
+    public static class  GeometryElementExtension
+    {
+        /// <summary>
+        /// 查找原始的几何对象
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="geoElement"></param>
+        /// <returns></returns>
+        public static List<T> GetGeometryOriginalObjects<T>(this GeometryElement geoElement) where T : GeometryObject
+        {
+            List<T> listRtn = new List<T>();
+            List<GeometryElement> useElements = new List<GeometryElement>() { geoElement };
+            for (int i = 0; i < useElements.Count; i++)
+            {
+                var useGeoElement = useElements[i];
+                foreach (var geoObject in useGeoElement)
+                {
+                    //系统族、相交切割后的外部族
+                    if (geoObject is T)
+                    {
+                        listRtn.Add(geoObject as T);
+                    }
+                    else if (geoObject is GeometryInstance)
+                    {
+                        var childElment = (geoObject as GeometryInstance).GetInstanceGeometry();
+                        if (childElment != null)
+                        {
+                            useElements.Add(childElment);
+                        }
+                    }
+                    else if (geoObject is GeometryElement)
+                    {
+                        useElements.Add(geoObject as GeometryElement);
+                    }
+                }
+            }
+            return listRtn;
+        }
+        public static List<T> GetGeometryObjects<T>(this GeometryElement geoElement) where T : GeometryObject
+        {
+            List<T> listRtn = geoElement.GetGeometryOriginalObjects<T>();
+            if (listRtn.Count == 0)
+            {
+                //计算为几何信息复制,可能引用相关有问题
+                var geoElementNew = geoElement.GetTransformed(Transform.Identity);
+                listRtn = geoElementNew.GetGeometryOriginalObjects<T>();
+            }
+            return listRtn;
+        }
+
+        /// <summary>
+        /// 获取指定元素的几何描述
+        /// </summary>
+        /// <param name="element"></param>
+        /// <param name="visibleObj"></param>
+        /// <param name="view"></param>
+        /// <returns></returns>
+        public static GeometryElement GetGeometryElement(this Element element, bool visibleObj = false, View view = null)
+        {
+            var options = new Options();
+            options.ComputeReferences = true;
+            options.IncludeNonVisibleObjects = visibleObj;
+            if (view == null)
+            {
+                options.DetailLevel = ViewDetailLevel.Fine;
+            }
+            else
+            {
+                options.View = view;
+            }
+
+            return element.get_Geometry(options);
+        }
+
+        /// <summary>
+        /// 获取几何Solid
+        /// </summary>
+        /// <param name="elem"></param>
+        /// <param name="view"></param>
+        /// <param name="visibleObj"></param>
+        /// <returns></returns>
+        public static List<Solid> GetSolids(this Element elem, View view = null, bool visibleObj = false)
+        {
+            var geoElement = elem.GetGeometryElement(visibleObj, view);
+            return geoElement.GetGeometryObjects<Solid>();
+        }
+        /// <summary>
+        /// 获取几何Solid
+        /// </summary>
+        /// <param name="elem"></param>
+        /// <param name="view"></param>
+        /// <param name="visibleObj"></param>
+        /// <returns></returns>
+        public static List<T> GetGeometryObjects<T>(this Element elem, View view = null, bool visibleObj = false) where T : GeometryObject
+        {
+            var geoElement = elem.GetGeometryElement(visibleObj, view);
+            return geoElement.GetGeometryObjects<T>();
+        }
+    }
+}

+ 41 - 0
JBIM/RevitToJBim/Extension/WallExtension.cs

@@ -0,0 +1,41 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:WallExtension
+ * 作者:xulisong
+ * 创建时间: 2019/6/26 17:57:20
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Autodesk.Revit.DB;
+using SAGA.DotNetUtils.Extend;
+using SAGA.RevitUtils;
+using SAGA.RevitUtils.Extends;
+
+namespace RevitToJBim.Extension
+{
+    public static class WallExtension
+    {
+        public static List<PlanarFace> GetTopFaces(this Wall wall)
+        {
+            var solids = Extension.GeometryElementExtension.GetSolids(wall, wall.Document.GetUseView());
+            var topZ = wall.GetTopStaticHeight();
+            List<PlanarFace> faces = new List<PlanarFace>();
+            foreach (var solid in solids)
+            {
+                foreach (Face face in solid.Faces)
+                {
+                    if (face is PlanarFace planarFace && planarFace.FaceNormal == XYZ.BasisZ && planarFace.Origin.Z.IsEqual(topZ))
+                    {
+
+                        faces.Add(planarFace);
+                    }
+                }
+            }
+            return faces;
+        }
+    }
+}

+ 3 - 0
JBIM/RevitToJBim/RevitToJBim.csproj

@@ -70,6 +70,9 @@
     <Compile Include="ComponentParse\ParseLevel.cs" />
     <Compile Include="ComponentParse\ParseUnit.cs" />
     <Compile Include="Extension\SpaceExtension.cs" />
+    <Compile Include="Extension\CurveLoopExtension.cs" />
+    <Compile Include="Extension\GeometryElementExtension.cs" />
+    <Compile Include="Extension\WallExtension.cs" />
     <Compile Include="JsonConverter\ParameterConverter.cs" />
     <Compile Include="MBI\MBIBuiltInParameterName.cs" />
     <Compile Include="MBI\MBIRegexPattern.cs" />

+ 1 - 0
JBIM/RevitToJBim/TestExport.cs

@@ -43,6 +43,7 @@ namespace RevitToJBim
             string fileName = DateTime.Now.ToString("yyyyMMddHHmmss");
             string path = Path.Combine(@"D:\", $"{fileName}.json");
             File.WriteAllText(path, result);
+            System.Diagnostics.Process.Start("notepad.exe", path);
         }
     }
     /// <summary>