Hey Everyone,
I'm trying to automate a simple yet massively tedious task at the moment. Certain layers of my drawings contain 3D Polylines that have to be converted to cylinders. What I need to do is select all 3D Polylines in a specific layer and automatically convert them to cylinders, these cylinders will all share the same hardcoded diameter, however will retain the x,y,z, positioning of the 3D Polylines. The way that I'm approaching i'm attempting right now is to use a selection filter to select all 3D Polylines, save their co-ordinates into an array, create the cylinders using these co-ordinates and then deleting the existing polylines. At this point though, i'm wondering if there is an easier way to do this or if anybody has solved a similar problem, any input or examples would be greatly appreciated. I'm sure I could pull it off using the approach i've described above, i'm just hoping there's a more efficient way.
Thanks!
Solved! Go to Solution.
Solved by Hallex. Go to Solution.
Vince, try this one just for first two points of 3dpolyline
extend code to your needs, just a note created cylinders aren't
real cylinder, many properties of them not applicable,
see properties window after creating things
[CommandMethod("3cy")] public void Pline3dToExtrudedCylinders() { Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; // radius of cylinder double rad = 10.0; SelectionFilter filt = new SelectionFilter(new TypedValue[]{ new TypedValue(0,"polyline")});// add: ,new TypedValue(8,"mylayer") PromptSelectionResult res = ed.GetSelection(filt); if (res.Status != PromptStatus.OK) return; SelectionSet sset = res.Value; Entity ent; using (Transaction tr = doc.TransactionManager.StartTransaction()) { BlockTableRecord btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord; foreach (SelectedObject obj in sset) { ent = tr.GetObject(obj.ObjectId, OpenMode.ForRead) as Entity; if (ent == null) return; Polyline3d poly = ent as Polyline3d; if (poly == null) return; Point3d p1= poly.GetPointAtParameter(poly.StartParam); Point3d p2 = poly.GetPointAtParameter(poly.StartParam+1.0); Vector3d vec = (p2 - p1).GetNormal(); double height = p1.DistanceTo(p2); Circle circ = new Circle(p1, vec, rad); circ.Normal = vec; ObjectId objId = btr.AppendEntity(circ); tr.AddNewlyCreatedDBObject(circ, true); // Get the boundary curves to create a region DBObjectCollection regs = new DBObjectCollection(); regs.Add(circ); // Create a region from the circle. DBObjectCollection regions = new DBObjectCollection(); regions = Region.CreateFromCurves(regs); if (regions.Count == 0) { ed.WriteMessage("\nFailed to create region\n"); return; } Region reg = (Region)regions[0]; // Extrude the region to create a solid. Solid3d sol = new Solid3d(); sol.RecordHistory = true;// optional sol.ShowHistory = false;// optional sol.Extrude(reg, height, 0.0); ObjectId solId = ObjectId.Null; solId = btr.AppendEntity(sol); tr.AddNewlyCreatedDBObject(sol, true); if (!circ.IsWriteEnabled) circ.UpgradeOpen(); circ.Erase(); } tr.Commit(); } }
Hey Hallex,
This is just what I was looking for, thank you. I've run into a problem when I run the code on a 3d polyline with multiple segements though. If my 3dpoly is made up of two segements at a 90 degree angle of each other, then the code only convert a single one of those segements to a 3dsolid, is there an easy way to cycle through all of the 3dpoly segements?
Thanks
Hey Hallex,
Ignore that last post, I realized what is happening, it's that the code is set to grab Point1 and Point2 of the selected 3dpolylines, and if there are more than 2 points to the selected 3dpolyline, it is unable to process them. Is there a command in AutoCAD where I can break a 3dpolyine into it's indivdual segements or an simple way to cycle through the individual segements of a multi-segement polyline in code?
Thanks Again
Hi Vince, sorry, been busy
//Just replace this line:
sol.Extrude(reg, height, 0.0);
//with this one:
sol.ExtrudeAlongPath(reg, poly as Curve, 0.0);
Hi,
I think this is exaclty what I am looking for, however I do not know how to run this. is this a script or lisp?
Hey jso,
This is C# code that must be compiled and run in AutoCAD as a DLL. I use Visual Studio 2010 and AutoCAD 2013 to accomplish this. Hopefully that clears things up a bit.
Cheers
Vince
HALLEX! Thank You ... This code is just what I needed - one small change and you have 3D pipes / tubes ... EXCELLENT!!
//sol.Extrude(reg, height, 0.0); sol.ExtrudeAlongPath(reg, (Curve)poly, 0);
Can't find what you're looking for? Ask the community or share your knowledge.