public static List <LineSegment3d> getWallline(LineSegment3d line, IEnumerable <LineSegment3d> entities) { double width = maxWallWidth + 1; // step 1: get the parallel lines in the loop: skip the colinear line var dir = line.Direction; var parallelLines = new List <LineSegment3d>(); foreach (LineSegment3d tmpLine in entities) { if (line != tmpLine) { if (dir.IsParallelTo(tmpLine.Direction) && (!tmpLine.IsOn(line.StartPoint) || tmpLine.IsOn(line.EndPoint))) // check if colinear line { parallelLines.Add(WallRecognizer.toLineSegment3d(tmpLine.StartPoint, tmpLine.EndPoint)); } } } List <LineSegment3d> innerlines = new List <LineSegment3d>(); // step 2: get poper innerlines foreach (LineSegment3d line1 in parallelLines) { Line3d line3d = WallRecognizer.toLine3d(line1.StartPoint, line1.EndPoint); // skip the colinear line and the two lines should be projection overlapped if (!line3d.IsOn(line.StartPoint) && WallRecognizer.isSegmentsProjectionOverlapped(line1, line)) { double dist = line3d.GetDistanceTo(line.StartPoint); if (DoubleExtensions.Larger(500, dist)) { updateInnerLines(line, line1, dist, innerlines); } /*// pixel to millemeter * dist = (dist * MILLIMETER_TO_METER) / PIXEL_TO_M_FACTOR; * // the dist should > minWallWidth & < maxWallWidth * if (DoubleExtensions.Larger(dist, minWallWidth) && DoubleExtensions.Larger(maxWallWidth, dist)) * { * //width = Math.Round(dist); * updateInnerLines(line1, dist, innerlines); * }*/ } } return(innerlines); }
private static ApartmentContourInfo GetApartmentContour(IEnumerable <ObjectId> linearIds) { var info = ApartmentContour.CalcContour(Application.DocumentManager.MdiActiveDocument, linearIds); var database = Application.DocumentManager.MdiActiveDocument.Database; // Test code ! using (var transaction = database.TransactionManager.StartTransaction()) { var contourSegments = info.Contour; var innerSegments = info.InternalSegments; // find out windows on wall, usually there are 4 or 3 parallel line segments for a window like below. // ----------------------- // ----------------------- // ----------------------- // ----------------------- const double maxWallWidth = 600; // todo Tolerance tol = new Tolerance(0.001, 0.001); List <LineSegment3d> sideWindowSegments = new List <LineSegment3d>(); List <List <LineSegment3d> > windowGroup = new List <List <LineSegment3d> >(); for (var i = 0; i < innerSegments.Count; i++) { var thisSeg = innerSegments[i]; //var startPt = innerSegments[i].StartPoint; //var endPt = innerSegments[i].EndPoint; // do check if the start and end points are on the wall //var cIndex = contourSegments.FindIndex((seg) => { // if (seg.IsOn(startPt, tol) && seg.IsOn(endPt, tol)) // return true; // return false; //}); // find out if the line segment is on the outer contour wall //var cIndex = contourSegments.FindIndex((seg) => //{ // if (seg.IsParallelTo(innerSegments[i], tol)) // { // var dist = seg.GetDistanceTo(thisSeg.MidPoint); // if (dist < maxWallWidth) // return true; // } // return false; //}); //if (cIndex != -1) { // find out all other parallel and equal length segments with this one var startPt = thisSeg.StartPoint; var endPt = thisSeg.EndPoint; double thisLength = thisSeg.Length; Vector3d direction = thisSeg.Direction.RotateBy(Math.PI / 2, Vector3d.ZAxis); Line3d startLine = new Line3d(startPt, direction); Line3d endLine = new Line3d(endPt, direction); List <LineSegment3d> parEqualSegs = new List <LineSegment3d>(); for (var j = 0; j < innerSegments.Count; j++) { if (i == j || innerSegments[j] == null) { continue; // itself } if (thisSeg.IsParallelTo(innerSegments[j]) && (startLine.IsOn(innerSegments[j].StartPoint, tol) && endLine.IsOn(innerSegments[j].EndPoint, tol)) || (startLine.IsOn(innerSegments[j].EndPoint, tol) && endLine.IsOn(innerSegments[j].StartPoint, tol))) { parEqualSegs.Add(innerSegments[j]); } } if (parEqualSegs.Count > 1) { Line3d helper1 = new Line3d(thisSeg.MidPoint, thisSeg.Direction); Line3d helper2 = new Line3d(thisSeg.MidPoint, direction); var intersects = helper1.IntersectWith(helper2); var basePt = intersects[0]; //direction = (thisSeg.MidPoint - basePt).GetNormal(); // sort them by direction parEqualSegs.Add(thisSeg); parEqualSegs.Sort((seg1, seg2) => { Vector3d vector1 = seg1.MidPoint - basePt; Vector3d vector2 = seg2.MidPoint - basePt; if (Math.Abs(vector1.DotProduct(direction) - vector2.DotProduct(direction)) < 0.001) { return(0); } else if (vector1.DotProduct(direction) > vector2.DotProduct(direction)) { return(1); } return(-1); }); List <LineSegment3d> thisWindow = new List <LineSegment3d>(); double distance = parEqualSegs[1].MidPoint.DistanceTo(parEqualSegs[0].MidPoint); if (distance < maxWallWidth / 2) { thisWindow.Add(parEqualSegs[0]); thisWindow.Add(parEqualSegs[1]); for (var k = 2; k < parEqualSegs.Count; k++) { var dist = parEqualSegs[k].MidPoint.DistanceTo(parEqualSegs[k - 1].MidPoint); if (thisWindow.Count > 4 || Math.Abs(dist - distance) > 100) { // we have find out 4 parallel lines or the distance is not equal to previous one break; } thisWindow.Add(parEqualSegs[k]); } if (thisWindow.Count > 2) { // this will be treaded as a valid window windowGroup.Add(thisWindow); } } } } } innerSegments.RemoveAll((seg) => { var index = windowGroup.FindIndex((window) => { return(window.Contains(seg)); }); if (index != -1) { return(true); } return(false); }); // end window var modelspaceId = SymbolUtilityServices.GetBlockModelSpaceId(database); var modelspace = (BlockTableRecord)transaction.GetObject(modelspaceId, OpenMode.ForWrite); var color1 = Color.FromColorIndex(ColorMethod.ByAci, 1); // 1: red ObjectId layerId = LayerUtils.AddNewLayer(database, "temp-poly", "Continuous", color1); for (var i = 0; i < windowGroup.Count; i++) { var window = windowGroup[i]; for (var j = 0; j < window.Count; j++) { var start = window[j].StartPoint; var end = window[j].EndPoint; var line = new Line(start, end); line.Color = color1; line.LayerId = layerId; modelspace.AppendEntity(line); transaction.AddNewlyCreatedDBObject(line, add: true); } } var color = Color.FromColorIndex(ColorMethod.ByAci, 3); // Green var polyline = new Polyline(); for (var i = 0; i < contourSegments.Count; i++) { var segment = contourSegments[i]; var start = segment.StartPoint; polyline.AddVertexAt(i, new Point2d(start.X, start.Y), 0, 0, 0); } polyline.Closed = true; polyline.Color = color; polyline.LayerId = layerId; modelspace.AppendEntity(polyline); transaction.AddNewlyCreatedDBObject(polyline, add: true); foreach (var segment in innerSegments) { var line = new Line(segment.StartPoint, segment.EndPoint); line.Color = color; line.LayerId = layerId; modelspace.AppendEntity(line); transaction.AddNewlyCreatedDBObject(line, add: true); } transaction.Commit(); } return(info); }