码迷,mamicode.com
首页 > 其他好文 > 详细

AddElevationTool copy

时间:2015-03-19 10:07:25      阅读:122      评论:0      收藏:0      [点我收藏+]

标签:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

using CoreGraphics;
using UIKit;

using Pasasoft.GeometryLib;
using Pasasoft.Fep.Model;
using Pasasoft.Fep.Drawing;
using Pasasoft.Fep.Model.Shapes;
using Pasasoft.Fep.Resources;
using Pasasoft.Fep.Views;
using Pasasoft.Fep.Alignments;
using Pasasoft.Fep.UIKit;
using Pasasoft.Fep.Commands;
using Pasasoft.Utilities;
using Pasasoft.Fep.Settings;
using Kernel.Disto;
using Pasasoft.Measurement;
using Pasasoft.Fep.AutoClose;
using Pasasoft.Localization;

namespace Pasasoft.Fep.Tools
{
    public class AddElevationTool : PolygonTool
    {
        private PointToOneRoomRule pointToOneRoomRule;
        private DotDivideLineRule dotRoomRule;
        private IAreaShape _deckShape;
//        private Poly2dInfo _freeRgnInfo {
//            get;
//            set;
//        }

        private AutoCloseElevationManager autoCloseManager = new AutoCloseElevationManager();
//        private bool isCancelFreeDraw = false;

        public override void TouchBegin (CGPoint point)
        {
            _touchPoint = point;
        }

        public AddElevationTool (ToolManager toolManager):base(toolManager)
        {
            pointToOneRoomRule = new PointToOneRoomRule ();
            pointToOneRoomRule.Options = PointToRoomAlignOption.Inner;
            dotRoomRule = new DotDivideLineRule ();
            _alignRule = p2pRule  | ((horzVert45Rule | orthoRule | parallelRule) & (dotRoomRule | pointToOneRoomRule | cornerRule));
        }

        public override void Draw (CGContext context)
        {
            for (int i = 0; i < _points.Count - 1; i++) 
            {
                if (dicArcPointObj.Keys.Contains(_points [i].Point)) {
                    var arc = dicArcPointObj [_points [i].Point];
                    context.DrawArcLine (arc, this.Coordinate);
                    context.DrawDimension (this.Coordinate, arc, Fonts.SystemFont);
                } else {
                    var p1 = LogicalToDevice (_points [i].Point);
                    var p2 = LogicalToDevice (_points [i + 1].Point);
                    context.DrawLine (p1, p2,UIColor.Blue.CGColor);
                    context.DrawDimension (Coordinate, _points [i].Point, _points [i + 1].Point, Fonts.SystemFont);
                    if (_points [i].ContainsType (PointType.DoorStart)) {
                        var rect1 = new CGRect (p1.X - 3, p1.Y - 3, 6, 6);
                        var rect2 = new CGRect (p2.X - 3, p2.Y - 3, 6, 6);
                        context.FillEllipse (rect1, UIColor.Red.CGColor);
                        context.FillEllipse (rect2, UIColor.Red.CGColor);
                        context.DrawLine (p1, p2, UIColor.Red.CGColor, 3.0f);
                    }

                    if (_points [i].ContainsType (PointType.MissingWall)) {
                        context.DrawDotLine (p1, p2, UIColor.Green.CGColor, 1.0f, new nfloat[] { 2, 2 });
                    }
                }
            }

            if (_currentPoint != null && _currentPoint.HasValue) {
                Point2d ptStartLogical = _currentPoint.Value;
                CGPoint ptCur = LogicalToDevice (ptStartLogical);
                using (var color = UIColor.FromRGB (0, 255, 255))
                {
                    context.DrawCrosshair (ptCur,View.Bounds,color.CGColor);
                }
            }

            if(_points.Count > 0 && _currentPoint.HasValue)
            {               
                var sideStart = _reversed ? _points[0].Point :_points[_points.Count-1].Point;

                var cp = LogicalToDevice(_currentPoint.Value);
                var lastPoint = LogicalToDevice (sideStart);

                context.DrawLine(lastPoint,cp,UIColor.Blue.CGColor);
                if(_reversed)
                    context.DrawDimension(Coordinate,_currentPoint.Value,sideStart,Fonts.SystemFont);
                else
                    context.DrawDimension(Coordinate,sideStart,_currentPoint.Value,Fonts.SystemFont);
            }

            triangulor.Draw (context, Coordinate, _currentPoint);

            if(_points.Count > 0)
            {
                CGPoint pt;
                if(_reversed) 
                    pt = LogicalToDevice(_points[0].Point);
                else                
                    pt = LogicalToDevice(_points[_points.Count - 1].Point);
                context.DrawLine(new CGPoint(pt.X,pt.Y-10),new CGPoint(pt.X,pt.Y+10),UIColor.Purple.CGColor);
                context.DrawLine(new CGPoint(pt.X-10,pt.Y),new CGPoint(pt.X+10,pt.Y),UIColor.Purple.CGColor);
                context.FillEllipse(new CGRect(new CGPoint(pt.X-3,pt.Y-3),new CGSize(6,6)),UIColor.Purple.CGColor);
            }

            if (_intersectedLines.Count > 0)
                for (int i = 0; i< _intersectedLines.Count; i++) {
                    context.DrawLine (LogicalToDevice(_intersectedLines [i].From),
                        LogicalToDevice(_intersectedLines [i].To), UIColor.Red.CGColor,2.0f);
                }

            if (_currentPoint != null && _currentPoint.HasValue) {
                Point2d ptStartLogical = _currentPoint.Value;
                CGPoint ptCur = LogicalToDevice (ptStartLogical);
                using (var color = UIColor.FromRGB (0, 255, 255))
                {
                    context.DrawCrosshair (ptCur,View.Bounds,color.CGColor);
                }
            }

            DrawAlignment (context);
            autoCloseManager.Draw (context, Coordinate);
            pointToOneRoomRule.Draw (context, Coordinate, GetLine (), _currentPoint);
            if (dotRoomRule.SnapPoint != null && dotRoomRule.IsAligned)
                DrawDotPoint (context, dotRoomRule.SnapPoint.Value);
        }

        private void DrawDotPoint(CGContext context, Point2d dotPoint)
        {
            var dp = LogicalToDevice(dotPoint);
            var rect1 = new CGRect(dp.X - 6, dp.Y - 6, 12, 12);
            context.FillEllipse(rect1, UIColor.Green.CGColor);
            context.StrokeEllipse(rect1, UIColor.Black.CGColor);
        }

        public override void Pan (UIPanGestureRecognizer gestureRecognizer)
        {
            if(_deckShape == null)
            {
                if(gestureRecognizer.State == UIGestureRecognizerState.Began)
                {
                    var p = DeviceToLogical(_touchPoint);
                    IShape shape = LayerContext.HitTestShape(p);

                    if(shape is IFloor)
                    {
                        _deckShape = shape as IAreaShape;
                        var room = _deckShape.Parent as IRoom;
                        pointToOneRoomRule.Room = room;
                        dotRoomRule.Lines = room.Floor.GeoRegion.Lines;

//                        if(!isCancelFreeDraw)
//                        {
//                            _points.Clear();
//                            PointObj pv = new PointObj();
//                            pv.Point = p;
//
//                            var command = Command.CreateListInsert (_points, 0, pv);
//                            CommandContainer.ExecuteQueue(command);
//                        }
                    }
                }
            }
            else
            {
                if (!gestureRecognizer.IsDone ()) {
                    var dp = gestureRecognizer.LocationInView (View);
                    dp.Y -= 48;
                    dp.X -= 48;
                    var point = DeviceToLogical (dp);
                    SetAlignmentArgs ();
                    pointToOneRoomRule.Coordinate = Coordinate;
                    _currentPoint = _alignRule.Align (point);
                }

                bool intersect = this.CheckDrawingLineStatus ();

                if(gestureRecognizer.IsDone())
                {
                    if (!intersect)
                        return;

                    if (_points.Count > 0) {
                        double len = _currentPoint.Value.Distance (_points[_points.Count - 1].Point);
                        if (len < Measure.LogicUnitPerInch * 3) {
                            this.RefreshToolView ();
                            return;
                        }
                    }

                    if(_points.Count > 2 && p2pRule.IsAligned)
                    {                    
                        CloseFreeDraw();
                        this.CommandContainer.Clear ();
                    }
                    else
                    {
                        PointObj pv = new PointObj();
                        if (HitTestRoomInner(_currentPoint.Value)) 
                            pv.AddType (PointType.Wall);

                        pv.Point = _currentPoint.Value;
                        Command command;

                        if (_reversed)
                            command = AddForwardPointCommand (pv);
                        else
                            command = AddReversePointCommand (pv);
                        
                        CommandContainer.Execute(command);
                        
                        _currentPoint = null;
                        triangulor.ResetReferencePoint ();
                    }        
                    return;
                }
                this.RefreshToolView();
            }
        }

        public TwoArgumentCommand<List<PointObj>,PointObj> AddForwardPointCommand(PointObj pv)
        {
            return    new TwoArgumentCommand<List<PointObj>,PointObj> (_points, pv,
                (l, v) => { 
                    l.Insert (0, v);
                },
                (l, v) => {
                    l.RemoveAt (0);
                    pointToOneRoomRule.Reset();
                    dotRoomRule.Reset();
                    autoCloseManager.Reset();
                    if (l.Count == 0) {
//                        isCancelFreeDraw = false;
                        _deckShape = null;
//                        _freeRgnInfo = null;
                    }
                });
        }

        public TwoArgumentCommand<List<PointObj>,PointObj> AddReversePointCommand(PointObj pv)
        {
            return new TwoArgumentCommand<List<PointObj>,PointObj> (_points, pv,
                (l, v) => {
                    l.Add (v);
                },
                (l, v) => {
                    l.RemoveAt (l.Count - 1);
                    pointToOneRoomRule.Reset();
                    dotRoomRule.Reset();
                    autoCloseManager.Reset();
                    if (l.Count == 0) {
//                        isCancelFreeDraw = false;
                        _deckShape = null;
//                        _freeRgnInfo = null;
                    }
                });
        }

        private void UpdateDeckRegion()
        {
            if (null == _deckShape)
            {
//                _freeRgnInfo = null;
            }
            else
            {
                List<Polygon2dObj> freeRegions = new List<Polygon2dObj>();
                GetAreasSubtractElevation(_deckShape, freeRegions);
                MultiPoly2dInfo info = new MultiPoly2dInfo();
                info.AddPolyInfos(freeRegions);
//                _freeRgnInfo = info;
            } 
        }

        private static void GetAreasSubtractElevation(IAreaShape area, List<Polygon2dObj> rgns)
        {
            IPrism prism = area.Parent as IPrism;
            List<Polygon2dObj> elevations = new List<Polygon2dObj>();
            Polygon2dObj areaRegion = area.GeoRegion;
            switch (area.ShapeType)
            {
            case ShapeType.Floor:
                foreach (IElevation ele in prism.FloorElevations)
                    elevations.Add(ele.Floor.GeoRegion);
                break;
            case ShapeType.Wall:
                if (prism is IRoom)
                {
                    foreach (IElevation ele in (prism as IRoom).WallElevations)
                    {
                        if (ele.Deck == area)
                            elevations.Add(ele.Floor.GeoRegion);
                    }
                }
                break;
            }
            if (elevations.Count == 0)
            {
                rgns.Add(areaRegion);
            }
            else
            {
                MultiPoly2dInfo otherInfo = new MultiPoly2dInfo();
                otherInfo.AddPolyInfos(elevations);
                List<Polygon2dObj> remained = new List<Polygon2dObj>();
                List<Polygon2dObj> newPolys = new List<Polygon2dObj>();
                using (ObjDataStore.StoreAndClearLinesData(areaRegion, true))
                    using (ObjDataStore.StoreAndClearListData(otherInfo.PolyLines, true))
                {
                    GeoApiPoly.GetBoolean(areaRegion.PolyInfo, otherInfo, remained, newPolys, false, true, true, false);
                }
                rgns.AddRange(remained);
                rgns.AddRange(newPolys);
            }
        }

        protected override void Clear ()
        {
            base.Clear ();
//            isCancelFreeDraw = false;
            _deckShape = null;
//            _freeRgnInfo = null;
            autoCloseManager.Reset ();
            dotRoomRule.Reset ();
            pointToOneRoomRule.Reset ();
        }

        protected override void ClearFreeDraw (UIButton button)
        {
            if (_points.Count == 0)
                return;
            PointObj[] point = new PointObj[_points.Count];
            _points.CopyTo(point);
            var command = new TwoArgumentCommand<List<PointObj>,PointObj[]>(_points,point,
                                                                            (l,v) => {
                _points.Clear();
//                isCancelFreeDraw = false;
                _deckShape = null;
//                _freeRgnInfo = null;
            },
            (l,v) => { l.AddRange(v); 
//                isCancelFreeDraw = true;
            }
                                                                            );
            CommandContainer.Execute(command);
            this.RefreshToolView();
        }

        protected override void InitializeOptionItems()
        {
            optionItems = new OptionItem[]{
                distoItem,
                OptionItem.CreateKeypad(ToggleControlPad),
                OptionItem.CreateSwitchStartPoint(ToggleReverse),
                OptionItem.CreateTriangle(ToggleMeasureTriangulation,triangulor.Enabled),
                OptionItem.CreateSwitchTriangleReference(MoveTriangleStartPoint),
                OptionItem.CreateAlignOption(ShowAlignOption),
                OptionItem.CreateDrawArc(ArcMeasureMode),
                OptionItem.CreateCloseShape(CloseFreeDraw),
                OptionItem.CreateLock4590(SethorzVert45RuleEnable),
            };
        }

        protected void ArcMeasureMode()
        {        
            if (_points.Count < 3) {            
                return;
            }
            DiscreteHost.HideToolOption (() => {
                IList<Point2d> points = new List<Point2d>();
                var room = _deckShape.Parent as IRoom;

                foreach(var line in room.Floor.GeoRegion.Lines)                
                    points.Add(line.From);

                var pts = this.Points.Select (x => x.Point).ToList<Point2d> ();
                points.AddRange(pts);

                PushAndSwitch (ToolType.AddArc, points, this.dicArcPointObj,room,room.Floor.GeoRegion.Lines.Count,
                    false, this._reversed);
            });        
        }

        protected void CloseFreeDraw ()
        {
            if (Points.Count >= 2 && Points [0].ContainsType (PointType.Wall) && Points [Points.Count - 1].ContainsType (PointType.Wall) && !p2pRule.IsAligned) {
                AddElevation();
                Clear();
                this.ModelToolHost.ReturnSelectTool (); 
                return;
            }
            if (!this.CheckDrawingLineStatus ()) {
                this.RefreshToolView ();
                return;
            }
            this.DoCloseFreeDraw ();
            this.ModelToolHost.ReturnSelectTool (); 
        }

        protected override void DoCloseFreeDraw()
        {
            if(_points.Count > 2)
                AddElevation();
            Clear();
            RefreshToolView();
        }

        public override void RestoredFrom (ToolType toolType,params object[] args)
        {
            base.RestoredFrom (toolType);
            if (args.Length > 0) {
//                _popCalculator = (bool)args [0];
                if (args.Length == 2) {
                    var arcPts = args [1] as List<Point2d>;
                    if (arcPts != null && arcPts.Count == 2) {

                        PointObj pv = new PointObj ();
                        pv.Point = arcPts [1];
                        pv.AddType (PointType.Wall);

                        if (_reversed) {
                            pv.AddType (PointType.Arc);
                            var arc = new Arc2d (pv.Point, this._points [0].Point, arcPts [0]);
                            CommandContainer.ExecuteDictionaryAdd (dicArcPointObj, pv.Point, arc, false);
                            CommandContainer.ExecuteListInsert (_points, 0, pv);
                        } else {
                            var pvEnd = this._points [this._points.Count - 1];
                            var arc = new Arc2d (pvEnd.Point, arcPts [1], arcPts [0]);
                            CommandContainer.Execute (PointType.Arc, pvEnd.AddType, pvEnd.RemoveType, false);
                            CommandContainer.ExecuteDictionaryAdd (dicArcPointObj, pvEnd.Point, arc, false);
                            CommandContainer.ExecuteListInsert (_points, this._points.Count, pv);
                        }
                    }
                }
            }
        }

        protected override void CommandCommitted ()
        {
            triangulor.ClearReferencePoint ();
            _intersectedLines.Clear ();
            base.CommandCommitted ();
            DetectAutoCloseLines ();
        }

        private void DetectAutoCloseLines()
        {
            if (_points.Count >= 2 && _points[0].PointTypes == PointType.Wall &&
                _points[_points.Count - 1].PointTypes == PointType.Wall) {
                var wallPoints = _points.
                    Select(p=>p.Point).ToList ();
                var polygons = (_deckShape.Parent as IRoom).WallSectionFrame.Frame;

                autoCloseManager.DetectLineImplement(polygons, wallPoints, _deckShape.Parent as IRoom);
            }
        }

        private void AddElevation()
        {
            if (autoCloseManager.AutoImplements.Count () > 0 && !p2pRule.IsAligned) {
                var autoLines = autoCloseManager.AutoImplements;
                for (int i = autoLines.Count - 1; i >= 0; i--) {
                    var po = new PointObj ();
                    po.Point = autoLines[i].From;
                    po.AddType (PointType.Wall);
                    Points.Add (po);
                }
            }

            using (CommandManager.Start())
            {
                //IList<Line2dObj> lines = GeoApiLineSet.CloneAsLine2dArc2d(DrawnLines, false);
//                Polygon2d poly = new Polygon2d();
//                poly.CreateDirect(lines);
//                poly.MakeAntiClockwise();

                List<Line2dObj> lines = new List<Line2dObj> ();
                for(int i = 0; i < this.Points.Count;i++)
                {
                    if (dicArcPointObj.Keys.Contains (this.Points[i].Point)) {
                        lines.Add (this.dicArcPointObj [this.Points [i].Point]);
                    } else {
                        lines.Add (new Line2d (this.Points [i].Point, this.Points [(i + 1) % this.Points.Count].Point));
                    }
                }

                //Polygon2d poly = new Polygon2d(points,true);    
                var poly = new Polygon2d ();
                poly.CreateDirect (lines);
                poly.MakeAntiClockwise ();

                IPrism prism = _deckShape.Parent as IPrism;

                IElevation ele = Shape.Factory.CreateElevation(poly, Shape.Settings.DefaultElevationHeight);
                ele.Deck = _deckShape;
                ele.Label = "C".AllocateName (prism.FloorElevations.Select (e => e.Label));
                prism.AddElevation(ele);
                if (_deckShape is IFloor)
                {
                    (_deckShape as IFloor).Update(true);
                    ele.Floor.Update(true);
                }
                else if (_deckShape is IWall)
                {
                    (_deckShape as IWall).NeedUpdateHole = true;
                    (_deckShape as IWall).Update(true);
                }
                CommandManager.Commit();
            }
            UpdateDeckRegion();
        }

        private bool HitTestRoomInner(Point2d point)
        {
            foreach (var line in (_deckShape.Parent as IRoom).Floor.GeoRegion.Lines) {
                if (ModelHelper.HitTestLine (line.From, line.To, point, Coordinate)) 
                    return true;
            }
            return false;
        }

        private Line2dObj GetLine()
        {
            Line2dObj lineobj = null;
            if (_currentPoint.HasValue) {
                foreach (var line in (_deckShape.Parent as IRoom).Floor.GeoRegion.Lines) {
                    if (ModelHelper.HitTestLine (line.From, line.To, _currentPoint.Value, Coordinate))
                        lineobj = line;
                }        
                foreach (var line in (_deckShape.Parent as IRoom).Floor.GeoRegion.Lines) {
                    if (ModelHelper.HitTestLine (line.From, line.To, _currentPoint.Value, Coordinate, 6))
                        lineobj = line;
                }
            }
            return lineobj;
        }

        public override void DoneTool ()
        {
            if (Points.Count >= 2 && Points [0].ContainsType (PointType.Wall) && Points [Points.Count - 1].ContainsType (PointType.Wall)) {
                this.CloseFreeDraw ();
                return;
            }else if (_points.Count < 3) {
                Clear ();
                this.ModelToolHost.ReturnSelectTool ();
                return;
            }

            if (!this.CheckDrawingLineStatus ()) {    
                this.RefreshToolView ();
                MessageBox.Show (string.Empty, "Do you want to discard current drawings?".Localize(), (s, e) => {
                    if (e.DialogResult == DialogResult.Yes) {
                        this.Clear ();
                    } 
                    this.ModelToolHost.ReturnSelectTool ();
                }, MessageBoxButtons.YesNo);
            } else {
                this.DoCloseFreeDraw ();
                this.ModelToolHost.ReturnSelectTool ();
            }
        }
    }
}

AddElevationTool copy

标签:

原文地址:http://www.cnblogs.com/cxzhe/p/4349558.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!