using netDxf.Entities; using netDxf; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MECF.Framework.UI.Core.DxfScript { /// /// 名称:RecognizeShape类 /// 作用:识别dxf文件中的图形 转化为自定义对象 /// public partial class GasDxfDocument { private void RecognizeShape() { RecognizeGasAITValve(); RecognizeGasButton(); RecognizeAnalogControl4Jet(); } //识别文字是否在圆内 private bool IsTextInCircle(GasText text, GasCircle circle) { double x, y; x = text.X; y = text.Y; if (circle.Contains(x, y)) { return true; } return false; } //判断多线段是否是矩形 private bool IsPolyLineRect(GasPolyLine polyLine) { if (polyLine.InnerLines.Count != 4) { return false; } GasLine lineH1, lineH2, lineV1, lineV2; lineH1 = lineH2 = lineV1 = lineV2 = null; for (int i = 0; i < 4; i++) { GasLine line = polyLine.InnerLines[i]; if (line.IsHorizental) { if (lineH1 == null) { lineH1 = line; } else if (lineH2 == null) { lineH2 = line; } else { return false; } } else if (line.IsVertical) { if (lineV1 == null) { lineV1 = line; } else if (lineV2 == null) { lineV2 = line; } else { return false; } } } if (lineH1 != null && lineH2 != null && lineV1 != null && lineV2 != null) { if (lineH1.CornerAt(lineV1) && lineH1.CornerAt(lineV2) && lineH2.CornerAt(lineV1) && lineH2.CornerAt(lineV2)) { return true; } } return false; } //判断文字是否在矩形内 private bool IsTextInRect(GasText text, GasPolyLine polyLine) { if (!IsPolyLineRect(polyLine)) { return false; } double x, y; x = text.X; y = text.Y; if (!polyLine.Contains(x, y)) { return false; } return true; } //识别漏斗 private void RecognizeGasFunnel(DxfDocument dxf, string blockName = "HV") { foreach (var entity in dxf.Entities.All) { if (entity.Type != EntityType.Insert) continue; Insert insert = (Insert)entity; var block = insert.Block; if (block == null || block.Name != blockName) continue; GasFunnel gasFunnel = new GasFunnel(insert.Position.X, insert.Position.Y, insert.Position.Z, insert.Scale.X, insert.Scale.Y, insert.Scale.Z, insert.Rotation); gasFunnel.SetGasLines(insert); Funnels.Add(gasFunnel); } } //识别阀门 private void RecognizeGasAITValve() { //识别可调节阀门 for (int textId = 0; textId < Texts.Count; textId++) { //遍历文本 GasText theText = Texts[textId]; for (int circleId = 0; circleId < Circles.Count; circleId++) { //针对每个文本,再去遍历圆圈 GasCircle theCircle = Circles[circleId]; if (IsTextInCircle(theText, theCircle)) { //文本在圆圈内,组成valve Valves.Add(new GasAITValve(theCircle, theText, null)); Texts.RemoveAt(textId); Circles.RemoveAt(circleId); textId--; circleId--; break; } } } //识别不可调节阀门 for (int valveId = 0; valveId < Valves.Count; valveId++) { for (int polyId = 0; polyId < PolyLines.Count; polyId++) { GasPolyLine thePolyLine = PolyLines[polyId]; if (!IsPolyLineRect(thePolyLine)) { continue; } GasAITValve theValve = Valves[valveId]; double rectWidth = Math.Abs(thePolyLine.InnerLines[0].X1 - thePolyLine.InnerLines[0].X2); if (rectWidth > 3 * theValve.InnerCircle.R) { continue; } if (thePolyLine.Contains(theValve.InnerCircle.X, theValve.InnerCircle.Y)) { theValve.InnerPolyLine = thePolyLine; PolyLines.RemoveAt(polyId); polyId--; theValve.Enable = false; break; } } } } //识别按钮 private void RecognizeGasButton() { for (int polyId = 0; polyId < PolyLines.Count; polyId++) { GasText foundText = null; int foundCount = 0; GasPolyLine thePolyLine = PolyLines[polyId]; if (!IsPolyLineRect(thePolyLine)) { continue; } int textId; for (textId = 0; textId < Texts.Count; textId++) { GasText theText = Texts[textId]; if (!IsTextInRect(theText, thePolyLine)) { continue; } if (foundText == null) { foundText = theText; } foundCount++; } if (foundText != null && foundCount != 2) { double minY, maxY; minY = Math.Min(thePolyLine.InnerLines[0].Y1, thePolyLine.InnerLines[0].Y2); maxY = Math.Max(thePolyLine.InnerLines[0].Y1, thePolyLine.InnerLines[0].Y2); minY = Math.Min(thePolyLine.InnerLines[1].Y1, minY); minY = Math.Min(thePolyLine.InnerLines[1].Y2, minY); minY = Math.Min(thePolyLine.InnerLines[2].Y1, minY); minY = Math.Min(thePolyLine.InnerLines[2].Y2, minY); minY = Math.Min(thePolyLine.InnerLines[3].Y1, minY); minY = Math.Min(thePolyLine.InnerLines[3].Y2, minY); maxY = Math.Max(thePolyLine.InnerLines[1].Y1, maxY); maxY = Math.Max(thePolyLine.InnerLines[1].Y2, maxY); maxY = Math.Max(thePolyLine.InnerLines[2].Y1, maxY); maxY = Math.Max(thePolyLine.InnerLines[2].Y2, maxY); maxY = Math.Max(thePolyLine.InnerLines[3].Y1, maxY); maxY = Math.Max(thePolyLine.InnerLines[3].Y2, maxY); if (maxY - minY > 50) { continue; } Buttons.Add(new GasButton(thePolyLine, foundText)); Texts.Remove(foundText); PolyLines.RemoveAt(polyId); polyId--; } } } //识别analog mfc private void RecognizeAnalogControl4Jet() { for (int buttonId = 0; buttonId < Buttons.Count; buttonId++) { GasButton theButton = Buttons[buttonId]; GasText text1, text2; text1 = text2 = null; for (int textId = 0; textId < Texts.Count; textId++) { if (IsTextInRect(Texts[textId], theButton.InnerPolyLine)) { if (text1 == null) { text1 = Texts[textId]; } else if (text2 == null) { text2 = Texts[textId]; break; } } } if (text1 == null || text2 == null) { continue; } GasLine theHLine = null; GasLine theVLine = null; bool failed = false; for (int lineId = 0; lineId < Lines.Count; lineId++) { GasLine theLine = Lines[lineId]; double x, y; x = (theLine.X1 + theLine.X2) / 2; y = (theLine.Y1 + theLine.Y2) / 2; if (theButton.Contains(x, y)) { if (theLine.IsHorizental) { if (theHLine == null) { double theLineLength = Math.Abs(theLine.X1 - theLine.X2); double theButtonWidth = Math.Abs(theButton.InnerPolyLine.InnerLines[0].X1 - theButton.InnerPolyLine.InnerLines[0].X2); if (Math.Abs(theLineLength - theButtonWidth) < GasBaseShape.E) { theHLine = theLine; } else { Lines.RemoveAt(lineId); lineId--; } } else { failed = true; break;//不是analog,下一个button } } else if (theLine.IsVertical) { if (theVLine == null) { theVLine = theLine; } else { failed = true; break;//不是analog,下一个button } } else { continue;//线段不在poly内,下一个线段 } } } if (failed) { continue; //不是analog,下一个button } if (theHLine == null || theVLine == null) { continue;//不是analog,下一个button } GasPolyLine polyUp, polyLeft, polyRight; //按上、右、下、左顺序排列顶点 double x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, x7, y7; double x8, y8;//中心点 x1 = Math.Min(theButton.InnerPolyLine.InnerLines[0].X1, theButton.InnerPolyLine.InnerLines[0].X2); y1 = theButton.InnerPolyLine.InnerLines[0].Y1; x2 = Math.Max(theButton.InnerPolyLine.InnerLines[0].X1, theButton.InnerPolyLine.InnerLines[0].X2); y2 = y1; x3 = x2; y3 = theHLine.Y1; x4 = x2; y4 = theButton.InnerPolyLine.InnerLines[2].Y1; x5 = theVLine.X1; y5 = y4; x6 = x1; y6 = y4; x7 = x1; y7 = y3; x8 = x5; y8 = y3; polyUp = new GasPolyLine(); polyUp.AddLine(new GasLine(x1, y1, x2, y2)); polyUp.AddLine(new GasLine(x2, y2, x3, y3)); polyUp.AddLine(new GasLine(x3, y3, x7, y7)); polyUp.AddLine(new GasLine(x7, y7, x1, y1)); polyLeft = new GasPolyLine(); polyLeft.AddLine(new GasLine(x7, y7, x8, y8)); polyLeft.AddLine(new GasLine(x8, y8, x5, y5)); polyLeft.AddLine(new GasLine(x5, y5, x6, y6)); polyLeft.AddLine(new GasLine(x6, y6, x7, y7)); polyRight = new GasPolyLine(); polyRight.AddLine(new GasLine(x8, y7, x3, y3)); polyRight.AddLine(new GasLine(x3, y3, x4, y4)); polyRight.AddLine(new GasLine(x4, y4, x5, y5)); polyRight.AddLine(new GasLine(x5, y5, x8, y8)); GasText textTop, textLeft, textRight; textTop = textLeft = textRight = null; GasButton TopButton, LeftButton, RightButton; TopButton = LeftButton = RightButton = null; if (IsTextInRect(theButton.InnerText, polyUp)) { textTop = theButton.InnerText; } else if (IsTextInRect(text1, polyUp)) { textTop = text1; } else if (IsTextInRect(text2, polyUp)) { textTop = text2; } else { continue;//没有text,下一个button } if (IsTextInRect(theButton.InnerText, polyLeft)) { textLeft = theButton.InnerText; } else if (IsTextInRect(text1, polyLeft)) { textLeft = text1; } else if (IsTextInRect(text2, polyLeft)) { textLeft = text2; } else { continue;//没有text,下一个button } if (IsTextInRect(theButton.InnerText, polyRight)) { textRight = theButton.InnerText; } else if (IsTextInRect(text1, polyRight)) { textRight = text1; } else if (IsTextInRect(text2, polyRight)) { textRight = text2; } else { continue;//没有text,下一个button } if (textTop == null || textLeft == null || textRight == null) { continue;//没有text,下一个button } TopButton = new GasButton(polyUp, textTop); LeftButton = new GasButton(polyLeft, textLeft); RightButton = new GasButton(polyRight, textRight); LeftButton.InnerText.Text = "0.00"; RightButton.InnerText.Text = "slm"; Analogs.Add(new GasAnalogControl4Jet(theButton, TopButton, LeftButton, RightButton)); Lines.Remove(theHLine); Lines.Remove(theVLine); Texts.Remove(text1); Texts.Remove(text2); Buttons.RemoveAt(buttonId); buttonId--; } } } }