123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203 |
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.IO;
- using System.Linq;
- 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 SAGA.MBI.DataArrange;
- using SAGA.MBI.Model;
- using SAGA.MBI.WinView.ModeInfoMaintenance;
- using SAGA.RevitUtils;
- using SAGA.RevitUtils.Windows;
- using Visibility = System.Windows.Visibility;
- //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 void MainWindow_Loaded(object sender, RoutedEventArgs e)
- {
- CanvasDefaultTips();
- }
- /// <summary>
- /// 初始化画布,并在画图上画出相关数据
- /// </summary>
- private void 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();
- var spaces =CurrentContext.Document.GetElements<SpatialElement>().Where(s => s is Autodesk.Revit.DB.Mechanical.Space && s.Area > 0).ToList();
- //创建空间轮廓,这里必须放在初始化之后创建
- CreateAllSpaceSeq(spaces);
- //创建右侧空间树
- ShowSpacesListFrowServer(spaces);
- }
- /// <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>
- /// <returns></returns>
- private Window GetUploadConfirm()
- {
- WinConfirm confirm = new WinConfirm()
- {
- ShowMessage = "空间已发生变化,是否现在就上传模型并计算空间?",
- TTitle = "空间计算确认",
- BtnSure = "上传模型并计算空间",
- BtnCancel = "暂不计算",
- Owner = this,
- };
- return confirm;
- }
- /// <summary>
- /// 保存所画的线
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void btnSave_Click(object sender, RoutedEventArgs e)
- {
- SaveFloor();
- ExecuteCmd.ExecuteCommandOnce(() =>
- {
- if (tv.SelectedItem is TreeNodeItem item && item.Item is MFloor floor)
- {
- InitFloor(floor);
- }
- return Result.Succeeded;
- }, () => { return Result.Succeeded; });
- }
- /// <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);
- }
- public FloorSpaceContext CurrentContext;
- /// <summary>
- /// 楼层切换
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void Tv_OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
- {
- try
- {
- //检测是否有未保存的数据,数据分两部分:新建的空间分隔符,删除的空间分隔符
- #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 = "放弃修改",
- Owner = this
- };
- var result = confirm.ShowDialog();
- if (result == true)
- {
- SaveFloor();
- //return;
- }
- }
- #endregion
- //异步造成执行顺序混乱的情况,所以使用idling排队
- ExecuteCmd.ExecuteCommandOnce(() =>
- {
- if (tv.SelectedItem is TreeNodeItem item && item.Item is MFloor floor)
- {
- InitFloor(floor);
- }
- return Result.Succeeded;
- }, () => { return Result.Succeeded; });
-
- }
- catch (Exception ex)
- {
- MessageShow.Show(ex);
- }
- }
- public void InitFloor(MFloor floor)
- {
- try
- {
- //保存按钮不可用
- this.btnSave.IsEnabled = false;
- DeletedPolylines.Clear();
- //关闭空间属性窗
- WinModeInfoMaintenance.GetWindow().Hide();
- this.canvas.Children.Clear();
- this.canvas.IsEnabled = false;
- this.lbSpaces.ItemsSource = null;
- #region 数据整理
- FloorSpaceContext context = new FloorSpaceContext(floor);
- CurrentContext = context;
- var doc = context.Document;
- var view = doc.GetUseView();
- if (view == null)
- {
- MessageBox.Show("无法找到名称以-saga结尾的视图!");
- return;
- }
- bool result = LoadData();
- if (!result)
- {
- MessageBox.Show("模型文件没有找到相关数据!");
- return;
- }
- ExecuteCmd.ExecuteCommand(() =>
- {
- context.CreateSpaces();
- #region 初始化界面
- this.canvas.IsEnabled = true;
- btnOrigin_Click(null, null);
- InitData();
- #endregion
- return Result.Succeeded;
- });
- #endregion
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message);
- }
- }
- private List<PointPair> GetPoints()
- {
- 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;
- }
- }
- return saveDatas;
- }
- private void SaveFloor()
- {
- //禁用界面,防止重复提交
- this.IsEnabled = false;
- m_isDraw = null;
- //需要保存的分隔符数据
- List<PointPair> saveDatas = GetPoints();
- bool flagExecuteSuccess = true; //本应在回调函数里传值,目前代码不支持
- #region 扩展事件处理相关
- EventCommand updateCommand = new EventCommand(new ExternalEventHandler((app) => {
- try
- {
- var document = CurrentContext.Document;
- document.Save();
- if (!flagExecuteSuccess)
- {
- return;
- }
- SpaceManager.UploadModel(document);
- }
- catch (Exception ex)
- {
- MessageShow.Show(ex);
- }
- }));
- #endregion
- ExecuteCmd.ExecuteCommandOnce(() =>
- {
- try
- {
- updateCommand.Register();
- #region 创建空间
- using (TransactionGroup group = new TransactionGroup(CurrentContext.Document, "保存空间修改"))
- {
- group.Start();
- CurrentContext.UpdateSpaceSeqaration(saveDatas
- .Select(points => new SpaceSeparation(points.RPoint[0], points.RPoint[1])).ToList(),
- DeletedPolylines);
- DeletedPolylines.Clear();
- var createSuccess = CurrentContext.CreateSpaces();
- if (!createSuccess)
- {
- flagExecuteSuccess = false;
- group.RollBack();
- MessageShow.Infomation("保存楼层空间失败");
- return Result.Succeeded;
- }
- group.Assimilate();
- }
- #endregion
- #region 上传模型选择
- Window confirm = GetUploadConfirm();
- var result = confirm.ShowDialog();
- //选择以后界面可用
- this.IsEnabled = true;
- if (result == true)
- {
- // 由于上传需要关闭所有模型,所以这里需要对所有数据进行清空
- this.canvas.Children.Clear();
- //添加默认提示
- CanvasDefaultTips();
- lbSpaces.ItemsSource = new ObservableCollection<MISpace>();
- WinModeInfoMaintenance.GetWindow().Hide();
- }
- else
- {
- flagExecuteSuccess = false;
- }
- #endregion
- }
- finally
- {
- this.IsEnabled = true;
- }
- return Result.Succeeded;
- }, () =>
- {
- #region 代码中包含事务,不能再回调线程中使用
- //try
- //{
- // var document = CurrentContext.Document;
- // document.Save();
- // if (!flagExecuteSuccess)
- // {
- // return Result.Succeeded;
- // }
- // SpaceManager.UploadModel(document);
- //}
- //catch (Exception ex)
- //{
- // MessageShow.Show(ex);
- //}
- #endregion
- updateCommand.Raise();
- 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 datas = CurrentContext.GetPhysicalSpaces(spaces.Select(t => t.Id.IntegerValue.ToString()).ToList());
- var localSpace = spaces.Where(t => !datas.Any(s => s.BimID.Split(':')[1] == t.Id.ToString()))
- .Select(t => new MISpace("", $"{Guid.NewGuid()}:{t.Id.ToString()}") { Name = t.Name });
- datas.AddRange(localSpace);
- //List<string> dd;
- //dd.AddRange();
- lbSpaces.ItemsSource = new ObservableCollection<MISpace>(datas);
- }
-
-
- /// <summary>
- /// 加载模型数据
- /// </summary>
- private bool LoadData()
- {
- var doc = CurrentContext.Document;
- //读取墙数据
- List<Wall> walls = doc.FilterElements<Wall>().ToList();
- if (walls.Count == 0) return false;
- //获取虚拟墙(空间分隔符或者房间分隔符)
- 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 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)
- {
- try
- {
- #region 核心代码
- if (lbSpaces.SelectedItems.Count == 0) return;
- var space = lbSpaces.SelectedItems[0] as MISpace;
- 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;
- }
- }
- }
- #endregion
- }
- catch (Exception ex)
- {
- MessageShow.Show(ex);
- }
- }
- /// <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="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 MISpace;
- 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;
- }
- }
- }
|