| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375 |
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Text.RegularExpressions;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Windows.Shapes;
- using Autodesk.Revit.DB;
- using DevExpress.Mvvm.Native;
- using SAGA.DotNetUtils.Extend;
- using SAGA.RevitUtils.Extends;
- using WPolyline = System.Windows.Shapes.Polyline;
- using Point = System.Windows.Point;
- using System.Windows.Media.Animation;
- using System.Windows.Threading;
- using Autodesk.Revit.UI;
- using Newtonsoft.Json.Linq;
- using SAGA.DotNetUtils.Logger;
- using SAGA.MBI.Common;
- using SAGA.MBI.DataArrange;
- using SAGA.MBI.JsonConvert;
- using SAGA.MBI.Model;
- using SAGA.MBI.RequestData;
- using SAGA.MBI.Tools;
- using SAGA.MBI.WinView.ModeInfoMaintenance;
- using SAGA.RevitUtils.Windows;
- using Visibility = System.Windows.Visibility;
- using Path = System.IO.Path;
- //TODO:1.目前存在的问题,如果只选两个已有的端点画线不能实现
- //TODO:2.画图过程中,ESC可取消当前画图
- //TODO:3.切换楼层检测是否有需要保存的数据,如果有则提示是否保存
- namespace SAGA.MBI.WinView.Space
- {
- /// <summary>
- /// 空间管理
- /// </summary>
- public partial class WinCreateSpaces : WinBase
- {
- public WinCreateSpaces()
- {
- this.IsLoadHistroyData = false;
- InitializeComponent();
- tv.ItemsSource = Items;
- this.Loaded += MainWindow_Loaded;
- this.Closed += WinCreateSpaces_Closed;
- }
- /// <summary>
- /// 窗体关闭,同时关闭空间属性窗
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void WinCreateSpaces_Closed(object sender, EventArgs e)
- {
- WinModeInfoMaintenance.GetWindow().Close();
- }
- /*
- 颜色分类:墙为黑色,
- 已有空间分隔符为绿色,
- 柱为蓝色
- 新的空间分隔符为红色
- */
- private List<List<XYZ>> m_wallsData;
- private List<PointPair> m_virXyzs;
- private List<XYZ> m_columnsLocation;
- public List<int> DeletedPolylines = new List<int>();//被删除的已存在的虚拟墙的Id
- //建筑与楼层列表数据
- private ObservableCollection<TreeNodeItem> items;
- //最大值X
- double m_minX = double.MaxValue;
- double m_maxX = 0.0;
- double m_minY = double.MaxValue;
- double m_maxY = 0.0;
- //初始缩放比例
- double m_scale = 15 / 1.5d;
- //起始点
- Point m_previousMousePoint = new Point(0, 0);
- //当前线段
- private Polyline m_polyline;
- //是否开始画线
- bool m_flag = false;
- //建筑与楼层列表数据
- public ObservableCollection<TreeNodeItem> Items
- {
- get => new ObservableCollection<TreeNodeItem>(DalModeFileManange.GetMissFileFloors(false));
- set => items = value;
- }
- //本层空间数据缓存
- private List<MSpace> m_spacesCache;
- private void MainWindow_Loaded(object sender, RoutedEventArgs e)
- {
- CanvasDefaultTips();
- }
- /// <summary>
- /// 初始化画布,并在画图上画出相关数据
- /// </summary>
- private bool InitData()
- {
- //获取边界值
- GetBoundary();
- //获取缩放比例
- m_scale = Math.Min((canvas.ActualWidth - 40) / (m_maxX - m_minX), (canvas.ActualHeight - 40) / (m_maxY - m_minY));
- //虚拟墙
- m_virXyzs?.ForEach(line =>
- {
- var pline = CreateDefaultPolyLine(line.Point, Brushes.Green, 2);
- pline.Tag = line.ElementId;
- });
- //墙
- m_wallsData.Select(row => row.Select(xyz => xyz.ToW2DPoint()).ToList()).ForEach(line =>
- {
- CreateDefaultPolyLine(line, Brushes.Black, 4);
- });
- //画柱
- DrawColumns();
- return true;
- }
- /// <summary>
- /// 获取数据的边界值
- /// </summary>
- void GetBoundary()
- {
- //Revit坐标与wpf的Y坐标相反,WPF Y向下
- var xs = new List<double>();
- var ys = new List<double>();
- this.m_wallsData.ForEach(list =>
- {
- list.ForEach((xyz) =>
- {
- xs.Add(xyz.X);
- ys.Add(xyz.Y);
- });
- });
- this.m_virXyzs.ForEach(list =>
- {
- list.Point.ForEach((point) =>
- {
- xs.Add(point.X);
- ys.Add(point.Y);
- });
- });
- this.m_columnsLocation.ForEach(point =>
- {
- xs.Add(point.X);
- ys.Add(point.Y);
- });
- if (xs.Count == 0 || ys.Count == 0) return;
- m_maxX = xs.Max();
- m_minX = xs.Min();
- m_maxY = ys.Max();
- m_minY = ys.Min();
- }
- /// <summary>
- /// 平移坐标点,使其更适应界面
- /// </summary>
- /// <param name="point"></param>
- /// <returns></returns>
- Point MovePoint(Point point)
- {
- var newPoint = new Point((point.X - m_minX) * m_scale, -(point.Y - m_maxY) * m_scale);
- newPoint.Offset(20, 20);
- return newPoint;
- }
- /// <summary>
- /// 画柱子
- /// </summary>
- void DrawColumns()
- {
- foreach (var xyz in m_columnsLocation)
- {
- var point = MovePoint(new Point(xyz.X, xyz.Y));
- var line = new WPolyline
- {
- Stroke = Brushes.Blue,
- StrokeThickness = 2,
- Tag = new Point(point.X, point.Y)
- };
- //这里为了方便后边计算,在线上记录柱中心
- var offset = 7;
- //左上角
- point.Offset(-offset, -offset);
- line.Points.Add(point);
- point.Offset(0, 2 * offset);
- line.Points.Add(point);
- point.Offset(2 * offset, 0);
- line.Points.Add(point);
- point.Offset(0, -2 * offset);
- line.Points.Add(point);
- point.Offset(-2 * offset, 0);
- line.Points.Add(point);
- this.canvas.Children.Add(line);
- }
- }
- /// <summary>
- /// 鼠标移动,实时显示虚拟墙动态
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void canvas_MouseMove(object sender, MouseEventArgs e)
- {
- if (m_flag == false)
- return;
- if (m_isDraw == true)
- {
- m_polyline.Points[m_polyline.Points.Count - 1] = e.GetPosition(canvas);
- Console.WriteLine("Move: " + m_polyline.Points[m_polyline.Points.Count - 1]);
- }
- }
- /// <summary>
- /// 开始画虚拟墙
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
- {
- if (m_isDraw != true) return;
- var point = e.GetPosition(canvas);
- if (m_polyline == null)
- {
- // if (flag == false) {
- m_polyline = new Polyline
- {
- Stroke = Brushes.Red,
- StrokeThickness = 2,
- FillRule = FillRule.EvenOdd
- };
- this.canvas.Children.Add(m_polyline);
- //如果是第一个点,则自动附着到现有的线段上
- point = GeometryHelper.ConvertOnLinePoint(point, this.canvas, m_polyline);
- }
- m_polyline.Points.Add(point);
- if (m_polyline.Points.Count == 1)
- m_polyline.Points.Add(e.GetPosition(canvas));
- m_flag = true;
- this.btnSave.IsEnabled = true;
- Console.WriteLine("Left Down: " + e.GetPosition(canvas));
- }
-
- /// <summary>
- /// 缩放画布
- /// </summary>
- /// <param name="scale"></param>
- /// <param name="center"></param>
- private void MoveElement(double scale, Point center, bool isReset = false)
- {
- //foreach (UIElement s in canvas.Children)
- {
- if (canvas.RenderTransform is TransformGroup tg)
- {
- //缩放
- if (tg.Children.FirstOrDefault(tr => tr is ScaleTransform) is ScaleTransform stf)
- {
- //重置
- if (isReset)
- {
- stf.ScaleX = 1;
- stf.ScaleY = 1;
- return;
- }
- //缩放的大小不能太小
- stf.ScaleX = Math.Max(stf.ScaleX + scale, 0.3);
- stf.ScaleY = Math.Max(stf.ScaleY + scale, 0.3);
- //if (center.X <= 0 || center.Y <= 0) {
- // return;
- //}
- // stf.CenterX = center.X;
- // stf.CenterY = center.Y;
- }
- else
- {
- scale = Math.Max(scale, 1);
- ScaleTransform scaleTransform = new ScaleTransform
- {
- ScaleX = scale,
- ScaleY = scale
- };
- tg.Children.Add(scaleTransform);
- }
- }
- else
- {
- TransformGroup transformGroup = new TransformGroup();
- ScaleTransform scaleTransform = new ScaleTransform();
- scaleTransform.ScaleX = 1;
- scaleTransform.ScaleY = 1;
- transformGroup.Children.Add(scaleTransform);
- canvas.RenderTransform = transformGroup;
- }
- }
- }
- /// <summary>
- /// TranslateTransform是平移画布
- /// </summary>
- /// <param name="dx"></param>
- /// <param name="dy"></param>
- private void MoveElement(double dx, double dy, bool isReset = false)
- {
- //foreach (UIElement s in canvas.Children)
- {
- if (canvas.RenderTransform is TransformGroup tg)
- {
- //平移
- if (tg.Children.FirstOrDefault(tr => tr is TranslateTransform) is TranslateTransform ttf)
- {
- var anim1 = new DoubleAnimation(ttf.X,
- (isReset ? 0 : (ttf.X + dx)),
- TimeSpan.FromSeconds(.01))
- { EasingFunction = new SineEase() };
- var anim2 = new DoubleAnimation(ttf.Y, (isReset ? 0 : (ttf.Y + dy)), TimeSpan.FromSeconds(.01)) { EasingFunction = new SineEase() };
- ttf.BeginAnimation(TranslateTransform.XProperty, anim1);
- ttf.BeginAnimation(TranslateTransform.YProperty, anim2);
- }
- else
- {
- TranslateTransform ttfNew = new TranslateTransform
- {
- // X = dx,
- // Y = dy
- };
- var anim1 = new DoubleAnimation(0, dx, TimeSpan.FromSeconds(.2)) { EasingFunction = new SineEase() };
- var anim2 = new DoubleAnimation(0, dy, TimeSpan.FromSeconds(.2)) { EasingFunction = new SineEase() };
- ttfNew.BeginAnimation(TranslateTransform.XProperty, anim1);
- ttfNew.BeginAnimation(TranslateTransform.YProperty, anim2);
- tg.Children.Add(ttfNew);
- }
- }
- else
- {
- TransformGroup transformGroup = new TransformGroup();
- TranslateTransform translateTransform = new TranslateTransform();
- //translateTransform.X = dx;
- //translateTransform.Y = dy;
- var anim1 = new DoubleAnimation(0, dx, TimeSpan.FromSeconds(.1)) { EasingFunction = new SineEase() };
- var anim2 = new DoubleAnimation(0, dy, TimeSpan.FromSeconds(.1)) { EasingFunction = new SineEase() };
- translateTransform.BeginAnimation(TranslateTransform.XProperty, anim1);
- translateTransform.BeginAnimation(TranslateTransform.YProperty, anim2);
- transformGroup.Children.Add(translateTransform);
- ScaleTransform scaleTransform = new ScaleTransform
- {
- ScaleX = 1,
- ScaleY = 1
- };
- // transformGroup.Children.Add(scaleTransform);
- canvas.RenderTransform = transformGroup;
- }
- }
- }
- /// <summary>
- /// 选择并删除虚拟墙
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void canvas_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
- {
- Point point = e.GetPosition(canvas);
- if (m_isDraw == false)//擦除线
- {
- foreach (var canvasChild in this.canvas.Children)
- {
- if (canvasChild is WPolyline line)
- {
- for (int i = 0; i < line.Points.Count - 1; i++)
- {
- if (PointIsInLine(point, line.Points[i], line.Points[i + 1], 4))
- {
- //黑线与蓝线不能删除,红线直接删除,绿线删除需记录
- if (line.Stroke == Brushes.Red)
- {
- canvas.Children.Remove(line);
- btnSave.IsEnabled = true;
- }
- else if (line.Stroke == Brushes.Green)
- {
- DeletedPolylines.Add((int)line.Tag);
- canvas.Children.Remove(line);
- btnSave.IsEnabled = true;
- }
- return;
- }
- }
- }
- }
- }
- }
- private bool? m_isDraw = null;
- /// <summary>
- /// 开始画图
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void btnDraw_Click(object sender, RoutedEventArgs e)
- {
- if (m_isDraw != true)
- {
- m_isDraw = true;
- this.Cursor = Cursors.Pen;
- }
- else
- {
- m_isDraw = null;
- this.Cursor = Cursors.Hand;
- }
- }
- /// <summary>
- ///
- /// 开始删除操作
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void btnClear_Click(object sender, RoutedEventArgs e)
- {
- m_isDraw = false;
- this.Cursor = Cursors.Cross;
- }
-
- /// <summary>
- /// 判断点是否在直线上
- /// </summary>
- /// <param name="pf"></param>
- /// <param name="p1"></param>
- /// <param name="p2"></param>
- /// <param name="range"></param>
- /// <returns></returns>
- public static bool PointIsInLine(Point pf, Point p1, Point p2, double range = 0)
- {
- //range 判断的的误差,不需要误差则赋值0
- //点在线段首尾两端之外则return false
- double cross = (p2.X - p1.X) * (pf.X - p1.X) + (p2.Y - p1.Y) * (pf.Y - p1.Y);
- if (cross <= 0) return false;
- double d2 = (p2.X - p1.X) * (p2.X - p1.X) + (p2.Y - p1.Y) * (p2.Y - p1.Y);
- if (cross >= d2) return false;
- double r = cross / d2;
- double px = p1.X + (p2.X - p1.X) * r;
- double py = p1.Y + (p2.Y - p1.Y) * r;
- //判断距离是否小于误差
- return Math.Sqrt((pf.X - px) * (pf.X - px) + (py - pf.Y) * (py - pf.Y)) <= range;
- }
- /// <summary>
- /// 创建虚拟墙
- /// </summary>
- /// <param name="xyzs"></param>
- /// <param name="brush"></param>
- /// <param name="thinkness"></param>
- /// <returns></returns>
- Polyline CreateDefaultPolyLine(List<Point> xyzs, Brush brush, double thinkness = 2)
- {
- var pl = new Polyline
- {
- Stroke = brush,
- StrokeThickness = thinkness,
- StrokeStartLineCap = PenLineCap.Flat,
- StrokeEndLineCap = PenLineCap.Flat,
- StrokeLineJoin = PenLineJoin.Round
- };
- this.AddPoints(xyzs, pl);
- canvas.Children.Add(pl);
- return pl;
- }
- /// <summary>
- /// 添加虚拟墙的点
- /// </summary>
- /// <param name="lstPt"></param>
- /// <param name="pl"></param>
- void AddPoints(IEnumerable<Point> lstPt, Polyline pl)
- {
- foreach (var pt in lstPt)
- {
- pl.Points.Add(MovePoint(new Point(pt.X, pt.Y)));
- }
- }
- /// <summary>
- /// 将画布坐标转换为Revit坐标
- /// </summary>
- /// <param name="point"></param>
- /// <returns></returns>
- XYZ WpfPointToReivt(Point point)
- {
- return new XYZ(((point.X - 20) / m_scale + m_minX), ((point.Y - 20) / (-m_scale) + (m_maxY)), 0);
- }
- /// <summary>
- /// 保存所画的线
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void btnSave_Click(object sender, RoutedEventArgs e)
- {
- m_isAsynFinished = false;
- //禁用界面,防止重复提交
- this.IsEnabled = false;
- m_isDraw = null;
- //需要保存的分隔符数据
- List<PointPair> saveDatas = new List<PointPair>();
- //取出所有的线
- for (var j = 0; j < this.canvas.Children.Count; j++)
- {
- var child = this.canvas.Children[j];
- if (child is WPolyline line && line.Stroke == Brushes.Red)
- {
- for (int i = 0; i < line.Points.Count - 1; i++)
- {
- //创建新的虚拟墙
- var newLine = new Polyline()
- {
- Stroke = Brushes.Green,
- StrokeThickness = 2,
- };
- newLine.Points.Add(line.Points[i]);
- newLine.Points.Add(line.Points[i + 1]);
- //将现有坐标转化
- saveDatas.Add(new PointPair()
- {
- RPoint = new List<XYZ>() { WpfPointToReivt(line.Points[i]), WpfPointToReivt(line.Points[i + 1]) },
- ShowLine = newLine
- });
- this.canvas.Children.Add(newLine);
- }
- //删除现有的虚拟墙
- this.canvas.Children.Remove(line);
- j = -1;
- }
- }
- //保存数据到Revit,创建空间分隔符
- var doc = m_document;
- ExecuteCmd.ExecuteCommand(() =>
- {
- Logs.Log($"空间分隔符开始");
- var create = new CreateSpaceCommand();
- //创建空间分隔符
- create.CreateSpaceSeqarate(doc, saveDatas, DeletedPolylines);
- //删除已有的空间分隔符
- DeletedPolylines.Clear();
- Logs.Log($"空间分隔符结束");
- // btnSaveToRevit.IsEnabled = true;
- return Result.Succeeded;
- });
- //保存后重新创建空间,并加载空间分隔符与空间数据
- CreateSpaceAndReload(doc, () =>
- {
- WinConfirm confirm = new WinConfirm()
- {
- ShowMessage = "空间已发生变化,是否现在就上传模型并计算空间?",
- TTitle = "空间计算确认",
- BtnSure = "上传模型并计算空间",
- BtnCancel = "暂不计算",
- Owner=this,
- };
- var result = confirm.ShowDialog();
- //选择以后界面可用
- this.IsEnabled = true;
- if (result == true)
- {
- // 由于上传需要关闭所有模型,所以这里需要对所有数据进行清空
- this.canvas.Children.Clear();
- //添加默认提示
- CanvasDefaultTips();
- lbSpaces.ItemsSource = new ObservableCollection<MSpace>();
- WinModeInfoMaintenance.GetWindow().Hide();
- m_isCreaded = true;
- return false;
- }
- else
- {
- return true;
- }
- });
- timer = new DispatcherTimer();
- timer.Tick += Timer_Elapsed;
- timer.Interval = TimeSpan.FromMilliseconds(1000);
- timer.Start();
- }
- private bool m_isCreaded = false;//是否上传数据的标志,用于定时器
- private bool m_isAsynFinished = false;
- private void Timer_Elapsed(object sender, EventArgs e)
- {
- if (m_isAsynFinished)
- {
- //所有的操作只在这里进行保存
- m_document.Save();
- Logs.Log($"{DateTime.Now}被保存!!!!!!!!!!!!!!!!!!");
- if (m_isCreaded)
- {
- //放在命令里面
- //ExecuteCmd.ExecuteCommand(() =>
- //{
- try
- {
- string str = "";
- UploadModeCommand command = new UploadModeCommand();
- command.Execute(null, ref str, null);
- }
- catch (Exception exception)
- {
- Console.WriteLine(exception);
- MessageBox.Show(exception.Message);
- }
- // return Result.Succeeded;
- //});
- m_isCreaded = false;
- }
- timer.Stop();
- m_isAsynFinished = false;
- }
- }
- /// <summary>
- /// 离开画布,改变鼠标样式
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void canvas_MouseLeave(object sender, MouseEventArgs e)
- {
- this.Cursor = Cursors.Arrow;
- }
- /// <summary>
- /// 鼠标进入画布,改变鼠标样式
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void canvas_MouseEnter(object sender, MouseEventArgs e)
- {
- if (m_isDraw == true)
- {
- this.Cursor = Cursors.Pen;
- }
- else if (m_isDraw == false)
- {
- this.Cursor = Cursors.Cross;
- }
- else
- {
- this.Cursor = Cursors.Hand;
- }
- }
- /// <summary>
- /// 鼠标右键,结束画线
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void canvas_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
- {
- if (m_polyline == null || m_isDraw != true) return;
- //结束,调整最后一个点,让其自动附着
- m_polyline.Points[m_polyline.Points.Count - 1] = GeometryHelper.ConvertOnLinePoint(m_polyline.Points[m_polyline.Points.Count - 1], canvas, m_polyline);
- m_polyline = null;
- m_flag = false;
- }
- private void viewer_MouseWheel(object sender, MouseWheelEventArgs e)
- {
- double val = (double)e.Delta / 2000; //描述鼠标滑轮滚动
- // scaleValue += val;
- var center = e.GetPosition(this.canvas);
- //if (center.X <= 0 || center.Y <= 0) {
- // return;
- //}
- MoveElement(val, center);
- }
- /// <summary>
- /// 鼠标up事件,获取鼠标抬起的位置,并根据移动距离平移画布
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void viewer_MouseUp(object sender, MouseButtonEventArgs e)
- {
- //如果按下的是中键
- if (e.ChangedButton == MouseButton.Middle)
- {
- Point position = e.GetPosition(viewer);
- var tempx = position.X - this.m_previousMousePoint.X;
- var tempy = position.Y - this.m_previousMousePoint.Y;
- //平移画布
- MoveElement(tempx, tempy);
- }
- }
- /// <summary>
- /// 鼠标down事件,获取点击初始位置
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void viewer_MouseDown(object sender, MouseButtonEventArgs e)
- {
- if (e.ChangedButton == MouseButton.Middle)
- {
- m_previousMousePoint = e.GetPosition(viewer);
- btnSave.IsEnabled = true;
- }
- }
- /// <summary>
- /// 鼠标中键滚轮事件,控制canvas的缩放
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void viewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
- {
- double val = (double)e.Delta / 2000; //描述鼠标滑轮滚动
- var center = e.GetPosition(this.canvas);
- MoveElement(val, center);
- }
- private string m_curFloorId = "";//当前选择项楼层Id
- private Document m_document;//当前操作的模型
- /// <summary>
- /// 楼层切换
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void Tv_OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
- {
- //检测是否有未保存的数据,数据分两部分:新建的空间分隔符,删除的空间分隔符
- #region 切换前节点处理
- if (DeletedPolylines.Count > 0 || this.canvas.Children.OfType<UIElement>().Any(el => (el is WPolyline line && line.Stroke == Brushes.Red)))
- {
- WinConfirm confirm = new WinConfirm()
- {
- ShowMessage = "尚未保存空间变化,确认放弃修改?",
- TTitle = "空间修改确认",
- BtnSure = "保存并更改模型",
- BtnCancel = "放弃修改"
- };
- var result = confirm.ShowDialog();
- if (result == true)
- {
- btnSave_Click(null, null);
- return;
- }
- DeletedPolylines.Clear();
- }
- #endregion
- if (tv.SelectedItem is TreeNodeItem item && item.Item is MFloor floor)
- {
- try
- {
- //关闭空间属性窗
- WinModeInfoMaintenance.GetWindow().Hide();
- m_curFloorId = floor.Id;
- this.canvas.Children.Clear();
- this.canvas.IsEnabled = false;
- this.lbSpaces.ItemsSource = null;
- //模型文件路径
- var filePath = floor.FullPath;
- //检测文件是否存在
- if (!File.Exists(filePath))
- {
- MessageBox.Show("无法找到相关模型文件!");
- return;
- }
- //加载模型文件并激活
- // var uiDoc = ExternalDataWrapper.Current.App.OpenDocumentFile(filePath);
- Logs.Log("加载模型开始");
- var uiDoc = ExternalDataWrapper.Current.UiApp.OpenAndActivateDocument(filePath);
- Logs.Log("加载模型结束");
- var doc = uiDoc.Document;
- m_document = doc;
- var view = doc.GetElements<ViewPlan>().FirstOrDefault(t => t.GenLevel?.Name != null && t.Name?.IndexOf("-saga") > -1 && t.ViewType == ViewType.FloorPlan);
- if (view == null)
- {
- MessageBox.Show("无法找到名称以-saga结尾的视图!");
- return;
- }
- bool result = LoadData();
- if (!result)
- {
- MessageBox.Show("模型文件没有找到相关数据!");
- return;
- }
- this.canvas.IsEnabled = true;
- //重置画布
- btnOrigin_Click(null, null);
- //缓存所有空间数据
- m_spacesCache = SpaceConvert.GetFloorSpaceInfos(m_curFloorId).OfType<MSpace>().ToList();
- //创建空间
- //检测日志,是否有墙,虚拟墙,柱子数据的改变
- CreateSpaceAndReload(doc, InitData);
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message);
- }
- }
- }
- /// <summary>
- /// 创建空间并重新加载到列表
- /// </summary>
- /// <param name="doc"></param>
- /// <param name="callback">异步回调函数</param>
- private void CreateSpaceAndReload(Document doc, Func<bool> callback)
- {
- ExecuteCmd.ExecuteCommand(() =>
- {
- Logs.Log($"创建空间开始");
- //生成空间
- CreateSpaceCommand cmd = new CreateSpaceCommand();
- cmd.CreateSpace(doc);
- // doc.Regenerate();
- Logs.Log($"创建空间结束");
- return Result.Succeeded;
- });
- //因为异步执行,获取空间不能直接放到下面
- //删除冲突的空间
- ExecuteCmd.ExecuteCommand(() =>
- {
- Logs.Log($"删除空间开始");
- // DeleteFailuresPreprocessorData(doc);
- DeleteFailuresPreprocessorDataByManual(doc);
- //保存数据
- // doc.Save();
- bool? isReload = callback?.Invoke();
- if (isReload == true)
- {
- try
- {
- //加载空间
- var spaces = doc.GetElements<SpatialElement>().Where(s => s is Autodesk.Revit.DB.Mechanical.Space && s.Area > 0).ToList();
- //创建空间轮廓,这里必须放在初始化之后创建
- CreateAllSpaceSeq(spaces);
- //创建右侧空间树
- ShowSpacesListFrowServer(spaces);
- }
- catch (Exception e)
- {
- MessageBox.Show(e.Message);
- }
- }
- m_isAsynFinished = true;
- //btnSaveToRevit.IsEnabled = true;
- try
- {
- Logs.Log($"删除空间结束");
- doc.Save();
- DocumentChangedLog.RemoveInvalidLogs();
- }
- catch (Exception e)
- {
- MessageBox.Show(e.Message);
- }
- return Result.Succeeded;
- });
- }
- /// <summary>
- /// 创建边线
- /// </summary>
- /// <param name="spaces"></param>
- void CreateAllSpaceSeq(List<SpatialElement> spaces)
- {
- //清除已有的空间边线
- for (int i = 0; i < this.canvas.Children.Count; i++)
- {
- if (this.canvas.Children[i] is WPolyline line && line.Tag is Autodesk.Revit.DB.Mechanical.Space)
- {
- this.canvas.Children.RemoveAt(i);
- i -= 1;
- }
- }
- spaces.ForEach(s => CreateSpaceBoundary(s as Autodesk.Revit.DB.Mechanical.Space));
- }
- /// <summary>
- /// 获取所有空间对应的服务器端的信息
- /// </summary>
- /// <param name="spaces"></param>
- private void ShowSpacesListFrowServer(List<SpatialElement> spaces)
- {
- // var infosjobj = ConvertElementsToJArray(spaces);
- //var datas = CommonConvert.QueryObjectInfoByIds(m_curFloorId, infosjobj).OfType<MSpace>().ToList();
- var datas = GetSpaceFromCacheByIds(spaces.Select(t => t.Id).ToList());
- var localSpace = spaces.Where(t => !datas.Any(s => s.BimID.Split(':')[1] == t.Id.ToString()))
- .Select(t => new MSpace("", $"{Guid.NewGuid()}:{t.Id.ToString()}") { Name = t.Name });
- datas.AddRange(localSpace);
- //List<string> dd;
- //dd.AddRange();
- lbSpaces.ItemsSource = new ObservableCollection<MSpace>(datas);
- }
-
- /// <summary>
- /// 手动删除冲突的空间
- /// </summary>
- /// <param name="doc"></param>
- private void DeleteFailuresPreprocessorDataByManual(Document doc)
- {
- bool isReCreate = false;
- using (Transaction trans = new Transaction(doc, "删除多余的空间"))
- {
- trans.Start();
- try
- {
- //处理异常显示
- FailureHandlingOptions fho = trans.GetFailureHandlingOptions();
- fho.SetFailuresPreprocessor(new FailuresPreprocessor(false));
- trans.SetFailureHandlingOptions(fho);
- List<ServerSpace> serverSpaces = new List<ServerSpace>();
- Regex regex = new Regex("^\\d+$");
- var index = 1;
- //对冲突的空间进行删除
- foreach (List<ElementId> elementIds in StaticData.FailuresPreprocessorData)
- {
- Logs.Log(string.Join("-", elementIds));
- //取出空间的服务器信息
-
- var spacesServerInfo = GetSpaceFromCacheByIds(elementIds);
- //如果返回值小于等于1,自动处理
- //如果返回值大于1,则在界面处理
- if (spacesServerInfo == null || spacesServerInfo.Count == 0)
- {
- var firstElement = doc.GetElement(elementIds.FirstOrDefault());
- //对所有冲突的空间编号进行比较,保留较小编号的空间
- if (firstElement is Autodesk.Revit.DB.Mechanical.Space first)
- {
- foreach (var id in elementIds)
- {
- if (first.Id.IsEqual(id))
- continue;
- var curr = doc.GetElement(id) as Autodesk.Revit.DB.Mechanical.Space;
- Logs.Log("=============");
- Logs.Log($"当前空间Id:{id},Num:{curr.Number}");
- //如果编号非数字,删其中一个
- if (!regex.IsMatch(first.Number))
- {
- doc.Delete(new List<ElementId>() { first.Id });
- first = curr;
- continue;
- }
- if (!regex.IsMatch(curr.Number))
- {
- doc.Delete(new List<ElementId>() { id });
- continue;
- }
- if (int.Parse(first.Number) > int.Parse(curr.Number))
- {
- Logs.Log($"1.被删除的空间Id:{id},Num:{first.Number}");
- doc.Delete(new List<ElementId>() { first.Id });
- first = curr;
- }
- else
- {
- Logs.Log($"2.被删除的空间Id:{id},Num:{curr.Number}");
- doc.Delete(new List<ElementId>() { id });
- }
- Logs.Log("=============");
- }
- }
- }
- else if (spacesServerInfo.Count == 1)
- {
- var serverSpaceId = spacesServerInfo[0].BimID.Split(':')[1];
- doc.Delete(elementIds.Where(t => t.ToString() != serverSpaceId).ToList());
- }
- else
- {
- doc.Delete(elementIds.Where(t => !spacesServerInfo.Exists(sp => sp.BimID.Split(':')[1] == t.ToString())).ToList());
- var groupName = $"待合并元空间组{index}";
- foreach (var mRevitEquipBase in spacesServerInfo)
- {
- if (mRevitEquipBase is MSpace space)
- {
- serverSpaces.Add(new ServerSpace()
- {
- Space = space,
- GroupName = groupName
- });
- }
- }
- serverSpaces.Add(new ServerSpace()
- {
- Name = "不保留已有空间,创建新空间",
- GroupName = groupName
- });
- index++;
- }
- }
- if (serverSpaces.Count > 0)
- {
- var winDeal = new WinSelectSpace(serverSpaces);
- var result = winDeal.ShowDialog();
- if (result == true)
- {
- var ids = winDeal.DeleteElementIds.Select(t => new ElementId(int.Parse(t))).ToList();
- doc.Delete(ids);
- isReCreate = winDeal.IsReCreate;
- }
- }
- //提交事务
- trans.Commit();
- }
- catch (Exception e)
- {
- //回滚事务
- trans.RollBack();
- }
- }
- StaticData.FailuresPreprocessorData.Clear();
- if (isReCreate) CreateSpaceAndReload(doc, null);
- }
-
- /// <summary>
- /// 加载模型数据
- /// </summary>
- private bool LoadData()
- {
- var doc = m_document;
- //读取墙数据
- List<Wall> walls = doc.FilterElements<Wall>().ToList();
- if (walls.Count == 0) return false;
- // List<List<XYZ>> wallData = GroupWallByParallel(walls);//太慢改为直接获取墙线
- //获取虚拟墙(空间分隔符或者房间分隔符)
- var wallData = walls.Select(t => t.GetCurve().Tessellate().ToList()).ToList();
- var virWalls = doc.FilterElements<CurveElement>((line) =>
- {
- var categoryId = line.Category.Id.IntegerValue;
- return categoryId == (int)BuiltInCategory.OST_MEPSpaceSeparationLines ||
- categoryId == (int)BuiltInCategory.OST_RoomSeparationLines;
- }).Where(line => line is ModelLine).Select(line =>
- {
- var ml = line as ModelLine;
- var mlLine = ml.Location.GetLine();
- //return new SgLine(mlLine.StartPoint().ToW2DPoint(), mlLine.EndPoint().ToW2DPoint()); //return new SgLine(mlLine.StartPoint().ToW2DPoint(), mlLine.EndPoint().ToW2DPoint());
- return
- new PointPair(ml.Id.IntegerValue, new List<System.Windows.Point>()
- {
- mlLine.StartPoint().ToW2DPoint(),
- mlLine.EndPoint().ToW2DPoint()
- });
- }).ToList();
- //获取所有建筑柱子
- var columns = doc.GetElements<FamilyInstance>(BuiltInCategory.OST_Columns);
- //结构柱
- var stColumns = doc.GetElements<FamilyInstance>(BuiltInCategory.OST_StructuralColumns);
- columns.AddRange(stColumns);
- m_columnsLocation = columns.Select(c => c.Location.GetPoint())
- .Where(t => !t.IsEqual(new XYZ(0, 0, 0), 0.000001)//TODO:临时处理
- ).ToList();
- this.m_wallsData = wallData;
- this.m_virXyzs = virWalls;
- return true;
- }
- /// <summary>
- /// 切换空间,亮显空间
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void lbSpaces_SelectionChanged(object sender, SelectionChangedEventArgs e)
- {
- if (lbSpaces.SelectedItems.Count == 0) return;
- var space = lbSpaces.SelectedItems[0] as MSpace;
- var bimId = space.BimID.Split(':')[1];
- foreach (var polyline in this.canvas.Children.OfType<WPolyline>())
- {
- if (polyline.Tag is Autodesk.Revit.DB.Mechanical.Space s)
- {
- if (s.Id.ToString() == (bimId))
- {
- polyline.Fill = Brushes.Aquamarine;
- //显示属性窗口
- ShowSpaceProperty(s);
- }
- else if (polyline.Fill == Brushes.Aquamarine)
- {
- polyline.Fill = Brushes.Transparent;
- }
- }
- }
- }
- /// <summary>
- /// 显示空间属性窗体
- /// </summary>
- /// <param name="space"></param>
- private static void ShowSpaceProperty(Autodesk.Revit.DB.Mechanical.Space space)
- {
- MRevitEquipBase equipment = DalCommon.GetEquipmentQueryId(space);
- ShowSpaceProperty(equipment);
- }
-
- private static void ShowSpaceProperty(MRevitEquipBase equipment)
- {
- try
- {
- if (equipment != null)
- {
- var win = WinModeInfoMaintenanceForSpace.GetWindow();
- win.Topmost = true;
- win.Show(equipment);
- win.Visibility = Visibility.Visible;
- }
- }
- catch (Exception e)
- {
- MessageBox.Show("显示属性窗口出错" + e.Message, "系统提示");
- }
- }
- /// <summary>
- /// 从缓存获取空间信息
- /// </summary>
- /// <param name="ids"></param>
- /// <returns></returns>
- private List<MSpace> GetSpaceFromCacheByIds(List<ElementId> ids)
- {
- if (m_spacesCache != null)
- return m_spacesCache.Where(s => ids.Exists(id => id.ToString() == s.BimID.Split(':')[1])).ToList();
- return new List<MSpace>();
- }
- /// <summary>
- /// 创建空间边缘轮廓
- /// </summary>
- /// <param name="space"></param>
- private void CreateSpaceBoundary(Autodesk.Revit.DB.Mechanical.Space space)
- {
- if (space == null) return;
- //过滤未放置空间
- if (space.Area.IsEqual(0, 0.0001)) return;
- //取出边缘
- var mySegments = space.GetBoundarySegments(new SpatialElementBoundaryOptions());
- var seg = mySegments.FirstOrDefault();
- if (seg == null)
- {
- MessageBox.Show(space.Id.IntegerValue + "");
- return;
- }
- List<Point> datas = new List<Point>();
- foreach (BoundarySegment segment in seg)
- {
- datas.AddRange(segment.GetCurve().Tessellate().Select(xyz => xyz.ToW2DPoint()).ToList());
- }
- var polyLine = this.CreateDefaultPolyLine(datas, Brushes.Transparent);
- polyLine.Tag = space;//此处比较重要,这个是判断曲线是否为轮廓线的关键
- polyLine.Fill = Brushes.Transparent;
- polyLine.MouseLeftButtonDown += PolyLine_MouseDown;
- }
- /// <summary>
- /// 空间轮廓点击事件
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void PolyLine_MouseDown(object sender, MouseButtonEventArgs e)
- {
- if ((sender is WPolyline line) && m_isDraw == null)
- {
- //找到已亮显的空间
- var showSpaces = this.canvas.Children.OfType<WPolyline>().FirstOrDefault(t => t is WPolyline l && l.Fill == Brushes.Aquamarine);
- //先清除
- if (showSpaces != null) showSpaces.Fill = Brushes.Transparent;
- line.Fill = Brushes.Aquamarine;
- //MessageBox.Show(line.Tag+"");
- if (line.Tag is Autodesk.Revit.DB.Mechanical.Space space)
- {
- //反选右侧树
- for (int i = 0; i < lbSpaces.Items.Count; i++)
- {
- var showSpace = lbSpaces.Items[i] as MSpace;
- var spaceId = showSpace.BimID.Split(':')[1];
- if (spaceId == space.Id.ToString())
- {
- lbSpaces.SelectedIndex = i;
- break;
- }
- }
- //显示属性板
- ShowSpaceProperty(space);
- }
- }
- }
- private void btnZoomIn_Click(object sender, RoutedEventArgs e)
- {
- MoveElement(-0.1, new Point());
- }
- private void btnOrigin_Click(object sender, RoutedEventArgs e)
- {
- MoveElement(0.1, new Point(), isReset: true);
- MoveElement(0, 0, isReset: true);
- }
- private void btnZoomOut_Click(object sender, RoutedEventArgs e)
- {
- MoveElement(0.1, new Point());
- }
- //创建定时器,以检测所有操作是否全部保存完成
- private DispatcherTimer timer;
-
- private void CanvasDefaultTips()
- {
- string tips = "请选择一个需要进行空间管理的楼层";
- TextBlock txtTips = new TextBlock
- {
- FontSize = 21,
- Width = 345,
- Height = 40,
- Text = tips,
- Foreground = Brushes.LightCyan
- };
- this.canvas.Children.Add(txtTips);
- Canvas.SetLeft(txtTips, this.canvas.ActualWidth / 2.0d - 160);
- Canvas.SetTop(txtTips, canvas.ActualHeight / 2.0d);
- }
- }
- /// <summary>
- /// 已有空间分割线的数据实体
- /// </summary>
- public class PointPair
- {
- //空间分割线的端点(WPF)
- public List<Point> Point { get; set; }
- //空间分割线的端点(Revit)
- public List<XYZ> RPoint { get; set; } = new List<XYZ>();
- //空间分割线的Id
- public int ElementId { set; get; }
- //WPF中显示的线
- public Polyline ShowLine { get; set; }
- public PointPair()
- {
- }
- public PointPair(int elemId, List<Point> point)
- {
- this.Point = point;
- this.ElementId = elemId;
- }
- }
- }
|