소스 검색

mxg:修正建模规范坐标重叠检查错误bug

mengxiangge 5 년 전
부모
커밋
c613f666a4

+ 284 - 0
FWindSoft/Saga.PlugIn/CreateSpaceCommand.cs

@@ -0,0 +1,284 @@
+/*-------------------------------------------------------------------------
+ * 功能描述:创建空间外轮廓
+ * 作者:xulisong
+ * 创建时间: 2019/3/21 8:59:02
+ * 版本号:v1.0
+ *  -------------------------------------------------------------------------*/
+
+using Autodesk.Revit.Attributes;
+using Autodesk.Revit.DB;
+using Autodesk.Revit.DB.Mechanical;
+using Autodesk.Revit.UI;
+using FWindSoft.Revit;
+using FWindSoft.Revit.Menu;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Shapes;
+using FWindSoft.SystemExtensions;
+using SAGA.DotNetUtils.Extend;
+using SAGA.RevitUtils.Extends;
+using SAGA.RevitUtils.MEP;
+using ExternalCommand = FWindSoft.Revit.ExternalCommand;
+using Line = Autodesk.Revit.DB.Line;
+using DocumentExtension = FWindSoft.Revit.DocumentExtension;
+
+namespace LRH.Tool
+{
+    [Transaction(TransactionMode.Manual)]
+    [Regeneration(RegenerationOption.Manual)]
+    [Button(ButtonName = "创建空间轮廓线")]
+    public class CreateSpaceOutLineCommand : ExternalCommand
+    {
+        public override Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
+        {
+            using (Transaction tran = new Transaction(RevitCore.Doc, "创建空间"))
+            {
+                try
+                {
+                    tran.Start();
+
+                    var space = RevitCore.UIApp.PickElement("请选择空间", new CommonFilter(t => { return t is Space; })) as Space;
+                    if (space == null) return Result.Cancelled;
+                    SpatialElementBoundaryOptions options = new SpatialElementBoundaryOptions();
+                    options.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.CoreBoundary;
+                    var segments = space.GetBoundarySegments(options);
+
+                    foreach (var segment in segments)
+                    {
+                        List<XYZ> xyzs = new List<XYZ>();
+                        foreach (BoundarySegment boundarySegment in segment)
+                        {
+                            var wall = RevitCore.Doc.GetElement(boundarySegment.ElementId) as Wall;
+                            if (wall == null) continue;
+                            var wallCurve = ElementExtension.GetLocationCurve(wall);
+                            var parallelWalls = GetParallelWalls(wall);
+                            var segmentCurve = boundarySegment.GetCurve();
+                            var tessellates = segmentCurve.Tessellate();
+                            foreach (XYZ tessellate in tessellates)
+                            {
+                                xyzs.Add(tessellate);
+                                //var project = wallCurve.GetProjectPt(tessellate);
+                                //var verticalVector = (project - tessellate).Normalize();
+                                //var tempXyz = GetOuterXYZ(tessellate, verticalVector, segmentCurve, parallelWalls);
+                                //if (tempXyz != null)
+                                //    xyzs.Add(tempXyz);
+                            }
+                        }
+
+                        //int count = xyzs.Count;
+                        ///*
+                        // * 相邻两条线求交点
+                        // * 处理内拐角
+                        // */
+                        //for (int i = 0; i < count; i++)
+                        //{
+                        //    var p1 = xyzs[i];
+                        //    int j2 = i + 1 >= xyzs.Count ? i + 1 - count : i + 1;
+                        //    var p2 = xyzs[j2];
+                        //    int j3 = i + 2 >= xyzs.Count ? i + 2 - count : i + 2;
+                        //    var p3 = xyzs[j3];
+                        //    int j4 = i + 3 >= xyzs.Count ? i + 3 - count : i + 3;
+                        //    var p4 = xyzs[j4];
+                        //    if (p1.IsEqual(p2) || p2.IsEqual(p3) || p3.IsEqual(p4))
+                        //        continue;
+                        //    Curve curve1 = Line.CreateBound(p1, p2);
+                        //    Curve curve2 = Line.CreateBound(p3, p4);
+                        //    XYZ intersection = curve1.GetIntersection(curve2);
+                        //    if (intersection == null) continue;
+                        //    xyzs[j2] = intersection;
+                        //    xyzs[j3] = intersection;
+                        //}
+
+                        if(xyzs.Any())
+                            xyzs.Add(xyzs[0]);
+                        //画线
+                        for (int i = 0; i < xyzs.Count - 1; i++)
+                        {
+                            try
+                            {
+                                var p1 = xyzs[i];
+                                var p2 = xyzs[i + 1];
+                                if (p1.IsAlmostEqualTo(p2))
+                                    continue;
+                                Curve curve = Line.CreateBound(p1, p2);
+                                RevitCore.DocCreater.NewDetailCurve(RevitCore.UIDoc.ActiveView, curve);
+                            }
+                            catch (Exception e)
+                            {
+                                Console.WriteLine(e);
+                            }
+                            
+                        }
+                    }
+
+
+                    tran.Commit();
+                }
+                catch (Exception e)
+                {
+                    tran.RollBack();
+                    throw;
+                }
+            }
+            return Result.Succeeded;
+        }
+
+        private double m_RedundancySpace = 10d;
+        /// <summary>
+        /// 获取平行墙,平行且投影有重叠部分
+        /// </summary>
+        /// <param name="wall"></param>
+        /// <returns></returns>
+        public List<Wall> GetParallelWalls(Wall wall)
+        {
+            List<Wall> walls = new List<Wall>();
+            walls.Add(wall);
+            var doc = wall.Document;
+            var allWalls = DocumentExtension.GetElements<Wall>(doc);
+            var curve = ElementExtension.GetLocationCurve(wall);
+            var parallelWalls = allWalls.Where(t => ElementExtension.GetLocationCurve(t).IsParallel(curve));
+
+            int len = walls.Count;
+            do
+            {
+                len = walls.Count;
+                foreach (Wall parallelWall in parallelWalls)
+                {
+                    var curve1 = ElementExtension.GetLocationCurve(parallelWall);
+                    var startP11 = CurveExtend.StartPoint(curve1);
+                    var endP11 = CurveExtend.EndPoint(curve1);
+                    double width1 = parallelWall.Width.FromApi();
+                    for (int i = 0; i < walls.Count; i++)
+                    {
+                        Wall referenceWall = walls[i];
+                        if (walls.Contains(parallelWall)) continue;
+                        var curve2 = ElementExtension.GetLocationCurve(referenceWall);
+                        var startP12 = CurveExtend.GetProjectPt(curve2, startP11);
+                        var endP12 = CurveExtend.GetProjectPt(curve2, endP11);
+                        var startP21 = CurveExtend.StartPoint(curve2);
+                        var endP21 = CurveExtend.EndPoint(curve2);
+                        var startP22 = CurveExtend.GetProjectPt(curve1, startP21);
+                        var endP22 = CurveExtend.GetProjectPt(curve1, endP21);
+                        //没有重叠部分
+                        if (startP12.IsOnCurve(curve2) || endP12.IsOnCurve(curve2) || startP22.IsOnCurve(curve1) ||
+                            endP22.IsOnCurve(curve1))
+                        {
+                            double width2 = referenceWall.Width.FromApi();
+                            double distacne = curve1.Distance(curve2).FromApi();
+                            if (distacne < (width1 + width2) / 2.0 + m_RedundancySpace)
+                                walls.Add(parallelWall);
+                        }
+                    }
+                }
+            } while (len != walls.Count);
+
+            return walls;
+        }
+        /// <summary>
+        /// 获取外廓后的点
+        /// </summary>
+        /// <param name="xyz">外廓点</param>
+        /// <param name="verticalVector">外廓向量</param>
+        /// <param name="segmentCurve">参考Curve</param>
+        /// <param name="walls">平行墙集合</param>
+        /// <returns></returns>
+        public XYZ GetOuterXYZ(XYZ xyz, XYZ verticalVector, Curve segmentCurve, List<Wall> walls)
+        {
+            XYZ outerXyz = null;
+            double distance = 0;
+            foreach (Wall wall in walls)
+            {
+                List<PlanarFace> faces = GetBottomFaces(wall);
+                foreach (PlanarFace face in faces)
+                {
+                    foreach (CurveLoop curveLoop in face.GetEdgesAsCurveLoops())
+                    {
+                        foreach (Curve curve in curveLoop)
+                        {
+                            /*
+                             * 1. 获取平行边
+                             * 2. 平行边求投影,投影点形成向量为向外
+                             * 3. 投影点在线上
+                             */
+                            if (!segmentCurve.IsParallel(curve))
+                                continue;
+                            var projectPt = curve.GetProjectPt(xyz);
+                            var tempVector = (projectPt - xyz).Normalize();
+                            if (projectPt.IsOnCurve(curve) && !projectPt.IsEqual(xyz) && tempVector.IsEqual(verticalVector))
+                            {
+                                var tempDistance = xyz.DistanceTo(projectPt);
+                                if (tempDistance >= distance)
+                                {
+                                    distance = tempDistance;
+                                    outerXyz = projectPt;
+                                }
+                            }
+                            else
+                            {
+                                /*
+                                 * 无投影点,给个默认投影点的情况
+                                 * 处理斜边投影不到的情况边上的情况,
+                                 * 目前任意取了一个,多个取最近的??
+                                 */
+                                if (outerXyz == null || outerXyz.IsEqual(xyz))
+                                    outerXyz = projectPt;
+                            }
+                        }
+                    }
+                }
+            }
+
+            return outerXyz;
+        }
+        /// <summary>
+        /// 获取墙底面的轮廓,主要处理门窗分割墙问题
+        /// </summary>
+        /// <param name="wall"></param>
+        /// <returns></returns>
+        public List<PlanarFace> GetBottomFaces(Wall wall)
+        {
+            var solids = wall.GetSolids();
+
+
+            double volume = double.MinValue;
+            List<PlanarFace> faces = new List<PlanarFace>();
+            foreach (var solid in solids)
+            {
+                var tempVolume = solid.Volume;
+                double topZ = double.MaxValue;
+                //取体积最大的Solid
+                if (tempVolume.IsThan(volume))
+                {
+                    volume = tempVolume;
+                    faces.Clear();
+                }
+                else
+                {
+                    continue;
+                }
+                foreach (Face face in solid.Faces)
+                {
+                    if (face is PlanarFace planarFace && planarFace.FaceNormal.IsEqual(-XYZ.BasisZ))
+                    {
+                        var tempZ = planarFace.Origin.Z;
+                        //取底面FaceNormal为(0,0,-1),Z最小
+                        if (tempZ.IsLess(topZ))
+                        {
+                            faces.Clear();
+                            topZ = tempZ;
+                            faces.Add(planarFace);
+                        }
+                        else if (tempZ.IsEqual(topZ))
+                        {
+                            faces.Add(planarFace);
+                        }
+
+                    }
+                }
+            }
+            return faces;
+        }
+
+    }
+}

BIN
FWindSoft/Saga.PlugIn/ModelCheck/ExcelTemplate/模型检查结果输出格式-模版.xlsx


+ 1 - 1
FWindSoft/Saga.PlugIn/ModelCheck/FamilyNameCheck.cs

@@ -140,7 +140,7 @@ namespace Saga.PlugIn.ModelCheck
                     DataCheckNPOIStyle style = result.IsRight ? DataCheckNPOIStyle.Content : DataCheckNPOIStyle.Error;
                     DataCheckNPOIStyle style = result.IsRight ? DataCheckNPOIStyle.Content : DataCheckNPOIStyle.Error;
                     int j = -1;
                     int j = -1;
                     rowN.AddCell(++j, result.FamilyName, style);
                     rowN.AddCell(++j, result.FamilyName, style);
-                    rowN.AddCell(++j, result.Type.GetDescription(), style);
+                    //rowN.AddCell(++j, result.Type.GetDescription(), style);
                     string rowN4 = result.IsRight ? "通过" : "不通过";
                     string rowN4 = result.IsRight ? "通过" : "不通过";
                     rowN.AddCell(++j, rowN4, style);
                     rowN.AddCell(++j, rowN4, style);
                     rowN.AddCell(++j, result.RMessage, style);
                     rowN.AddCell(++j, result.RMessage, style);

+ 1 - 0
FWindSoft/Saga.PlugIn/ModelCheck/InstanceLocationOverlapCheck.cs

@@ -47,6 +47,7 @@ namespace Saga.PlugIn.ModelCheck
             {
             {
                 var doc = signResult.RDocument;
                 var doc = signResult.RDocument;
                 var instances = doc.GetFamilyInstances();
                 var instances = doc.GetFamilyInstances();
+                instances = instances.Where(t => t.GetLocationPoint() != null).ToList();
                 var groups = instances.GroupBy(t => t.GetLocationPoint(),new XyzEqualComparer(0.01d));
                 var groups = instances.GroupBy(t => t.GetLocationPoint(),new XyzEqualComparer(0.01d));
                 foreach (var group in groups)
                 foreach (var group in groups)
                 {
                 {

+ 1 - 0
FWindSoft/Saga.PlugIn/Saga.PlugIn.csproj

@@ -101,6 +101,7 @@
       <DependentUpon>WinTipMissFamily.xaml</DependentUpon>
       <DependentUpon>WinTipMissFamily.xaml</DependentUpon>
     </Compile>
     </Compile>
     <Compile Include="CreateFacilityCommand.cs" />
     <Compile Include="CreateFacilityCommand.cs" />
+    <Compile Include="CreateSpaceCommand.cs" />
     <Compile Include="OtherCommand.cs" />
     <Compile Include="OtherCommand.cs" />
     <Compile Include="Other\CopyParameterValue.cs" />
     <Compile Include="Other\CopyParameterValue.cs" />
     <Compile Include="Other\RenameSystemName.cs" />
     <Compile Include="Other\RenameSystemName.cs" />