public static SqlBytes SerializeSqlGeographyMultiPoint(Point3dCollection points3d) { var result = ""; foreach (Point3d point in points3d) { if (points3d.IndexOf(point) == 0) { result = String.Format("MULTIPOINT (({0} {1} {2})", point.X, point.Y, point.Z); } result += String.Format(",({0} {1} {2})", point.X, point.Y, point.Z); } if (String.IsNullOrEmpty(result)) { return(null); } result += ")"; //, null)"; SqlGeometry multipoint = SqlGeometry.STMPointFromText(new SqlChars(result), 0); return(multipoint.Serialize()); }
internal static List <MeshData> SolidInfoForCollection(Document doc, Point3d camPos, ObjectIdCollection ids) { var sols = new List <MeshData>(); using (var tr = doc.TransactionManager.StartOpenCloseTransaction()) { foreach (ObjectId id in ids) { Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity; // Entity handle to name the Three.js objects String hand = ent.Handle.ToString(); Autodesk.AutoCAD.Colors.EntityColor clr = ent.EntityColor; // Entity color to use for the Three.js objects long b, g, r; if (ent.ColorIndex < 256) { System.Byte byt = System.Convert.ToByte(ent.ColorIndex); int rgb = Autodesk.AutoCAD.Colors.EntityColor.LookUpRgb(byt); b = (rgb & 0xffL); g = (rgb & 0xff00L) >> 8; r = rgb >> 16; } else { b = 127; g = 127; r = 127; } String entColor = "0x" + String.Format("{0:X2}{1:X2}{2:X2}", r, g, b); // Entity extents Extents3d ext = ent.GeometricExtents; var tmp = ext.MinPoint + 0.5 * (ext.MaxPoint - ext.MinPoint); Vector3d dir = ext.MaxPoint - ext.MinPoint; var mid = new Point3d(ext.MinPoint.X, tmp.Y, tmp.Z); var dist = camPos.DistanceTo(mid); if (id.ObjectClass.Name.Equals("AcDbSubDMesh")) { // Already a Mesh. Get the face info and clean it up // a bit to export it as a THREE.Face3 which only has three vertices var mesh = ent as SubDMesh; Point3dCollection threeVertices = new Point3dCollection(); Autodesk.AutoCAD.Geometry.Int32Collection threeFaceInfo = new Autodesk.AutoCAD.Geometry.Int32Collection(); Point3dCollection vertices = mesh.Vertices; int[] faceArr = mesh.FaceArray.ToArray(); int[] edgeArr = mesh.EdgeArray.ToArray(); Autodesk.AutoCAD.Geometry.Int32Collection faceVertices = new Autodesk.AutoCAD.Geometry.Int32Collection(); int verticesInFace = 0; int facecnt = 0; for (int x = 0; x < faceArr.Length; facecnt++, x = x + verticesInFace + 1) { faceVertices.Clear(); verticesInFace = faceArr[x]; for (int y = x + 1; y <= x + verticesInFace; y++) { faceVertices.Add(faceArr[y]); } // Merging of mesh faces can result in faces with multiple vertices // A simple collinearity check can help remove those redundant vertices bool continueCollinearCheck = false; do { continueCollinearCheck = false; for (int index = 0; index < faceVertices.Count; index++) { int v1 = index; int v2 = (index + 1) >= faceVertices.Count ? (index + 1) - faceVertices.Count : index + 1; int v3 = (index + 2) >= faceVertices.Count ? (index + 2) - faceVertices.Count : index + 2; // Check collinear Point3d p1 = vertices[faceVertices[v1]]; Point3d p2 = vertices[faceVertices[v2]]; Point3d p3 = vertices[faceVertices[v3]]; Vector3d vec1 = p1 - p2; Vector3d vec2 = p2 - p3; if (vec1.IsCodirectionalTo(vec2)) { faceVertices.RemoveAt(v2); continueCollinearCheck = true; break; } } } while (continueCollinearCheck); if (faceVertices.Count == 3) { Point3d p1 = vertices[faceVertices[0]]; Point3d p2 = vertices[faceVertices[1]]; Point3d p3 = vertices[faceVertices[2]]; if (!threeVertices.Contains(p1)) { threeVertices.Add(p1); } threeFaceInfo.Add(threeVertices.IndexOf(p1)); if (!threeVertices.Contains(p2)) { threeVertices.Add(p2); } threeFaceInfo.Add(threeVertices.IndexOf(p2)); if (!threeVertices.Contains(p3)) { threeVertices.Add(p3); } threeFaceInfo.Add(threeVertices.IndexOf(p3)); } else if (faceVertices.Count == 4) { // A face with 4 vertices, lets split it to // make it easier later to create a THREE.Face3 Point3d p1 = vertices[faceVertices[0]]; Point3d p2 = vertices[faceVertices[1]]; Point3d p3 = vertices[faceVertices[2]]; if (!threeVertices.Contains(p1)) { threeVertices.Add(p1); } threeFaceInfo.Add(threeVertices.IndexOf(p1)); if (!threeVertices.Contains(p2)) { threeVertices.Add(p2); } threeFaceInfo.Add(threeVertices.IndexOf(p2)); if (!threeVertices.Contains(p3)) { threeVertices.Add(p3); } threeFaceInfo.Add(threeVertices.IndexOf(p3)); p1 = vertices[faceVertices[2]]; p2 = vertices[faceVertices[3]]; p3 = vertices[faceVertices[0]]; if (!threeVertices.Contains(p1)) { threeVertices.Add(p1); } threeFaceInfo.Add(threeVertices.IndexOf(p1)); if (!threeVertices.Contains(p2)) { threeVertices.Add(p2); } threeFaceInfo.Add(threeVertices.IndexOf(p2)); if (!threeVertices.Contains(p3)) { threeVertices.Add(p3); } threeFaceInfo.Add(threeVertices.IndexOf(p3)); } else { Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("Face with more than 4 vertices will need triangulation to import in Three.js "); } } sols.Add(new MeshData(dist, hand, ext, threeVertices, threeFaceInfo, entColor)); } else if (id.ObjectClass.Name.Equals("AcDb3dSolid")) { // Mesh the solid to export to Three.js Autodesk.AutoCAD.DatabaseServices.Solid3d sld = tr.GetObject(id, OpenMode.ForRead) as Autodesk.AutoCAD.DatabaseServices.Solid3d; MeshFaceterData mfd = new MeshFaceterData(); // Only triangles mfd.FaceterMeshType = 2; // May need change based on how granular we want the mesh to be. mfd.FaceterMaxEdgeLength = dir.Length * 0.025; MeshDataCollection md = SubDMesh.GetObjectMesh(sld, mfd); Point3dCollection threeVertices = new Point3dCollection(); Autodesk.AutoCAD.Geometry.Int32Collection threeFaceInfo = new Autodesk.AutoCAD.Geometry.Int32Collection(); Point3dCollection vertices = md.VertexArray; int[] faceArr = md.FaceArray.ToArray(); Autodesk.AutoCAD.Geometry.Int32Collection faceVertices = new Autodesk.AutoCAD.Geometry.Int32Collection(); int verticesInFace = 0; int facecnt = 0; for (int x = 0; x < faceArr.Length; facecnt++, x = x + verticesInFace + 1) { faceVertices.Clear(); verticesInFace = faceArr[x]; for (int y = x + 1; y <= x + verticesInFace; y++) { faceVertices.Add(faceArr[y]); } if (faceVertices.Count == 3) { Point3d p1 = vertices[faceVertices[0]]; Point3d p2 = vertices[faceVertices[1]]; Point3d p3 = vertices[faceVertices[2]]; if (!threeVertices.Contains(p1)) { threeVertices.Add(p1); } threeFaceInfo.Add(threeVertices.IndexOf(p1)); if (!threeVertices.Contains(p2)) { threeVertices.Add(p2); } threeFaceInfo.Add(threeVertices.IndexOf(p2)); if (!threeVertices.Contains(p3)) { threeVertices.Add(p3); } threeFaceInfo.Add(threeVertices.IndexOf(p3)); } } sols.Add(new MeshData(dist, hand, ext, threeVertices, threeFaceInfo, entColor)); tr.Commit(); } } } return(sols); }
public void AddPolylineVertex() { var db = HostApplicationServices.WorkingDatabase; var ed = db.GetEditor(); var doc = db.GetDocument(); try { var ent_res = ed.GetEntity("请选择一条多段线:\n"); if (ent_res.Status != PromptStatus.OK) { return; } var pt_res = ed.GetPoint("请选择一个点:\n"); if (pt_res.Status != PromptStatus.OK) { return; } var new_pt = pt_res.Value; // 新增的端点 var pl_Index = 0; // 记录插入第几段 var pts = new Point3dCollection(); //多段线的顶点集合 var ptAtpl = Point3d.Origin; // 选择点与多段线的最近点 var width = 0.0; using (doc.LockDocument()) using (var tr = db.TransactionManager.StartTransaction()) { var ent = tr.GetObject(ent_res.ObjectId, OpenMode.ForWrite) as Entity; var pl = ent as Polyline; if (pl != null) { if (pl.Closed) { PublicMethod.Instance.ShowMessage("面设备不能增加顶点。"); return; } ptAtpl = pl.GetClosestPointTo(new_pt, false); width = pl.GetStartWidthAt(0); for (var index = 0; index < pl.NumberOfVertices; index++) { pts.Add(pl.GetPoint3dAt(index)); } } tr.Commit(); } if (pts.Count >= 2) { var isPlPt = pts.Contains(ptAtpl); //如果是多段线顶点 if (isPlPt) { pl_Index = pts.IndexOf(ptAtpl); ed.WriteMessageWithReturn(string.Format("最近点多段线顶点重合 {0}", pts.IndexOf(ptAtpl))); } else { for (int i = 0; i < pts.Count - 1; i++) { var line = new Line(pts[i], pts[i + 1]); var ptAtline = line.GetClosestPointTo(ptAtpl, false); if (ptAtpl.IsEqualTo(ptAtline)) { pl_Index = i; ed.WriteMessageWithReturn(string.Format("最近点在第 {0} 段线上", i)); } line.Dispose(); } } // 插入顶点 using (var tr = db.TransactionManager.StartTransaction()) { var ent = tr.GetObject(ent_res.ObjectId, OpenMode.ForWrite) as Entity; var pl = ent as Polyline; if (pl != null) { pl.AddVertexAt(pl_Index + 1, new Point2d(new_pt.X, new_pt.Y), 0, width, width); // 设置线宽度 } tr.Commit(); } } } catch (System.Exception ex) { ed.WriteMessageWithReturn(ex); } }
public void createPolyline(Point3dCollection pts) { LineSegment3d segmentLine = null; CircularArc3d segmentArc = null; int segmentCounter; Point3d linePt0 = new Point3d(); Point3d linePt1 = new Point3d(); double anglePt0 = -1; double anglePt1 = -1; bool pt0IsaLine = false; bool pt0IsanArc = false; CoordinateSystem3d cs = Application.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem.CoordinateSystem3d; Plane plan = new Plane(Point3d.Origin, cs.Zaxis); double param = new double(); //loop through point and get segment type. Create new lines foreach (Point3d pt in pts) { //oint3d closest = _runningLine.GetClosestPointTo(pt, false); for (segmentCounter = 0; segmentCounter < _runningLine.NumberOfVertices; segmentCounter++) { //try //{ if (_runningLine.OnSegmentAt(segmentCounter, pt.Convert2d(plan), param)) { if (_runningLine.GetSegmentType(segmentCounter) == SegmentType.Arc) { segmentArc = _runningLine.GetArcSegmentAt(segmentCounter); if (pts.IndexOf(pt) == 0) { anglePt0 = segmentArc.Center.GetVectorTo(pt).AngleOnPlane(plan); pt0IsanArc = true; break; } if (pt0IsaLine) { if ((segmentLine.GetDistanceTo(pt) / segmentLine.Length) < .5) { linePt1 = new Point3d(segmentLine.EndPoint.X, segmentLine.EndPoint.Y, segmentLine.EndPoint.Z); } else { linePt1 = new Point3d(segmentLine.StartPoint.X, segmentLine.StartPoint.Y, segmentLine.StartPoint.Z); } anglePt0 = segmentArc.Center.GetVectorTo(linePt1).AngleOnPlane(plan); } anglePt1 = segmentArc.Center.GetVectorTo(pt).AngleOnPlane(plan); break; } else //if not an arc is a line { segmentLine = _runningLine.GetLineSegmentAt(segmentCounter); if (pts.IndexOf(pt) == 0) { linePt0 = new Point3d(pt.X, pt.Y, pt.Z); pt0IsaLine = true; break; } linePt1 = new Point3d(pt.X, pt.Y, pt.Z); if (pt0IsanArc) { if (pt.GetVectorTo(segmentLine.StartPoint).Length > pt.GetVectorTo(segmentLine.EndPoint).Length) { linePt0 = new Point3d(segmentLine.EndPoint.X, segmentLine.EndPoint.Y, segmentLine.EndPoint.Z); } else { linePt0 = new Point3d(segmentLine.StartPoint.X, segmentLine.StartPoint.Y, segmentLine.StartPoint.Z); } anglePt1 = segmentArc.Center.GetVectorTo(linePt0).AngleOnPlane(plan); } linePt1 = new Point3d(pt.X, pt.Y, pt.Z); break; } } } } Transaction tr = acCurDb.TransactionManager.StartTransaction(); using (tr) { Arc dbArc = null; Line dbLine = null; // Open the Block table record for read BlockTable acBlkTbl; acBlkTbl = tr.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable; // Open the Block table record Model space for write BlockTableRecord acBlkTblRec; acBlkTblRec = tr.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; if (anglePt0 >= 0) { if (anglePt0 > anglePt1) { dbArc = new Arc(segmentArc.Center, segmentArc.Radius, anglePt1, anglePt0); } else { dbArc = new Arc(segmentArc.Center, segmentArc.Radius, anglePt0, anglePt1); } } if (linePt0 != null) { dbLine = new Line(linePt0, linePt1); } if (dbArc != null && dbLine != null) { Polyline pl1 = new Polyline(); pl1.AddVertexAt(0, segmentLine.StartPoint.Convert2d(plan), 0, 0, 0); pl1.AddVertexAt(1, segmentLine.EndPoint.Convert2d(plan), 0, 0, 0); //pl1.AddVertexAt(2, segmentArc.EndPoint.Convert2d(plan), segmentArc.); } if (dbArc != null) { acBlkTblRec.AppendEntity(dbArc); tr.AddNewlyCreatedDBObject(dbArc, true); } if (dbLine != null) { acBlkTblRec.AppendEntity(dbLine); tr.AddNewlyCreatedDBObject(dbLine, true); } tr.Commit(); } }