标签:
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 ();
}
}
}
}
标签:
原文地址:http://www.cnblogs.com/cxzhe/p/4349558.html