public void Draw() { List <PathInfo> swept_paths = GetSweptPath(); AcadDB.SweepOptionsBuilder swept_options = new AcadDB.SweepOptionsBuilder(); swept_options.Align = AcadDB.SweepOptionsAlignOption.NoAlignment; using (AcadDB.Transaction tr = AcadFuncs.GetActiveDB().TransactionManager.StartTransaction()) { AcadDB.Solid3d union_sol3d = null; AcadDB.Solid3d union_sub_sol3d = null; foreach (var pi in swept_paths) { if (null != pi.sub_region) { AcadDB.Solid3d solid = new AcadDB.Solid3d(); swept_options.BasePoint = pi.start_position; solid.CreateSweptSolid(pi.sub_region, pi.path, swept_options.ToSweepOptions()); if (null == union_sub_sol3d) { union_sub_sol3d = solid; } else { union_sub_sol3d.BooleanOperation(AcadDB.BooleanOperationType.BoolUnite, solid); } } if (null != pi.region) { AcadDB.Solid3d solid = new AcadDB.Solid3d(); swept_options.BasePoint = pi.start_position; solid.CreateSweptSolid(pi.region, pi.path, swept_options.ToSweepOptions()); if (null == union_sol3d) { union_sol3d = solid; } else { union_sol3d.BooleanOperation(AcadDB.BooleanOperationType.BoolUnite, solid); } } } union_sol3d.BooleanOperation(AcadDB.BooleanOperationType.BoolSubtract, union_sub_sol3d); if (!(this is Straight)) { union_sol3d.ColorIndex = 1; } AcadFuncs.AddNewEnt(union_sol3d); tr.Commit(); } }
/// <summary> /// Create a <see cref="CadSolid"/> as lofted between cross sections /// </summary> /// <param name="document"></param> /// <param name="crossSections"></param> /// <param name="layer">set the layer for the solid (can be null)</param> /// <returns></returns> public static CadSolid ByLoft(Document document, Polyline3D[] crossSections, string layer) { if (document == null) { return(null); } if (crossSections?.Any() != true) { return(null); } var db = document.AcDocument.Database; using (var ctx = new DocumentContext(db)) { var id = ElementBinder.GetObjectIdFromTrace(ctx.Database); var apply = new Action <Solid3d>(solid => { var polylines = crossSections.Select(o => (Polyline3d)o.InternalDBObject).ToArray(); solid.CreateLoftedSolid(polylines, new Entity[] {}, null, new LoftOptions()); if (!string.IsNullOrWhiteSpace(layer)) { solid.Layer = layer; } }); using (var trans = db.TransactionManager.StartTransaction()) { if (id.IsValid & !id.IsErased) { var solid = (Solid3d)trans.GetObject(id, OpenMode.ForWrite, false, true); apply(solid); } else { var solid = new Solid3d(); apply(solid); var bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead, false, true); var modelspace = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite, false, true); id = modelspace.AppendEntity(solid); trans.AddNewlyCreatedDBObject(solid, true); } trans.Commit(); } var solidObj = ctx.GetTransaction().GetObject(id, OpenMode.ForRead, false, true) as Solid3d; return(solidObj != null ? new CadSolid(solidObj, true) : null); } }
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); }
internal CadSolid(Solid3d solid, bool isDynamoOwned) : base(solid, isDynamoOwned) { }
public void ImportUit3ds() { // Verkrijg document en database Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; acCurDb.Surfu = 0; acCurDb.Surfv = 0; using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { // Open de block-tabel BlockTable acBlkTbl; acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable; // Open de Model space om in te schrijven BlockTableRecord acBlkTblRec; acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; //Bestand openen om binair te lezen binReader = new BinaryReader(File.Open(@"C:/3DGISBuffer.dat", FileMode.Open)); //Loop door objecten int aantalobjecten = binReader.ReadInt32(); for (int i = 0; i < aantalobjecten; i++) { Point3dCollection vertarray = new Point3dCollection(); Int32Collection facearray = new Int32Collection(); // Maak een subdivision-mesh aan SubDMesh sdm = new SubDMesh(); sdm.SetDatabaseDefaults(); // Voeg het object toe aan de block-tabel acBlkTblRec.AppendEntity(sdm); acTrans.AddNewlyCreatedDBObject(sdm, true); //objectkleur lezen byte kleur_r = binReader.ReadByte(); byte kleur_g = binReader.ReadByte(); byte kleur_b = binReader.ReadByte(); //solidvlag lezen Boolean solidvlag = LeesBoolean(); // Vertexarray vullen met vertices Point3dCollection acPts3dPFMesh = new Point3dCollection(); Int32 nvts = binReader.ReadInt32(); for (int j = 1; j <= nvts; j++) { Single nX = binReader.ReadSingle(); Single nY = binReader.ReadSingle(); Single nZ = binReader.ReadSingle(); vertarray.Add(new Point3d(nX, nY, nZ)); } //Facearray vullen met faces int nfcs = binReader.ReadInt32(); for (int j = 1; j <= nfcs; j++) { int fc1 = binReader.ReadInt32(); int fc2 = binReader.ReadInt32(); int fc3 = binReader.ReadInt32(); facearray.Add(3); facearray.Add(fc1 - 1); facearray.Add(fc2 - 1); facearray.Add(fc3 - 1); } //Vertex- en facearray toevoegen aan mesh, smoothlevel 0 sdm.SetSubDMesh(vertarray, facearray, 0); Entity pMijnObj = null; if (solidvlag) { Autodesk.AutoCAD.DatabaseServices.Solid3d pSolid = sdm.ConvertToSolid(false, false); pMijnObj = (Entity)pSolid; } else { Autodesk.AutoCAD.DatabaseServices.Surface pSurface = sdm.ConvertToSurface(false, false); pMijnObj = (Entity)pSurface; } acBlkTblRec.AppendEntity(pMijnObj); acTrans.AddNewlyCreatedDBObject(pMijnObj, true); //Verwijder mesh sdm.Erase(); // Schrijf objectnaam naar Xrecord in de entity-dictionary van de surface SaveXRecord(pMijnObj, LeesAttributen(), "GISData", acTrans); //kleur van het object updaten pMijnObj.Color = Color.FromRgb(kleur_r, kleur_g, kleur_b); }//einde for-loop // Schrijf het object naar de AutoCAD-database en sluit binReader acTrans.Commit(); binReader.Close(); } //einde using transaction } //einde method