Measure-like Command
Good morning,I'd like to know if anyone has a way of copying a point or block along a line/pline the way the measure command does; but only one instance of a point or block; and rotating the point/block to follow the curvature of the line/pline in the same way the measure command does.
Cheers I design balustrades and most of the time I have to put posts at certain ctrs around a radius or arc. I have a spreadsheet that helps me with this.
Im pretty sure LeeMac will have a lisp for what you require.
but I hope this can help. (someway)
Drawing Aids.zip Sounds like the array command would be ideal for you?
My application is about copying a block along a path e.g a road, railway etc. where the path has many intricate curves and 3D movements. All I want to do is copy a block X amount of distance along the line in plan view, ignoring Z values.
Cheers. Time was limited so there is ridiculously minimal testing and error checking, but:
static public void RefDistAlongPath() { Database db = HostApplicationServices.WorkingDatabase; Editor ed = Acad.DocumentManager.MdiActiveDocument.Editor; using (Transaction trans = db.TransactionManager.StartTransaction()) { // Put your command code here PromptEntityOptions peo = new PromptEntityOptions("Select target curve: "); peo.SetRejectMessage("\nPlease only select a curve entity!"); peo.AddAllowedClass(typeof(Autodesk.AutoCAD.DatabaseServices.Curve), false); PromptEntityResult per = ed.GetEntity(peo); if (per.Status != PromptStatus.OK) return; ObjectId oid = per.ObjectId; Curve crv = (Curve)trans.GetObject(oid, OpenMode.ForRead, false); Plane pl = new Plane(ed.CurrentUserCoordinateSystem.CoordinateSystem3d.Origin, ed.CurrentUserCoordinateSystem.CoordinateSystem3d.Zaxis); Curve projCrv = crv.GetOrthoProjectedCurve(pl); PromptStringOptions pso = new PromptStringOptions("Enter name of block to create reference: "); PromptResult pr = ed.GetString(pso); String blkName = pr.StringResult; BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead); if (!bt.Has(blkName)) { ed.WriteMessage ("Current Database does not contain a block of that name!"); return; } BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt, OpenMode.ForRead); PromptDistanceOptions pdo = new PromptDistanceOptions("Indicate distance along path: "); pdo.AllowArbitraryInput = false; PromptDoubleResult pdr = ed.GetDistance(pdo); if (pdr.Status != PromptStatus.OK) return; Point3d p3d = projCrv.GetPointAtDist(pdr.Value); Vector3d v3d = projCrv.GetFirstDerivative(p3d); Double ang = Math.Atan(v3d.Y / v3d.X); BlockTableRecord currSpace = trans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord; BlockReference insert = new BlockReference(p3d, btr.ObjectId); insert.Rotation = ang; currSpace.AppendEntity(insert); insert.SetDatabaseDefaults(); trans.AddNewlyCreatedDBObject(insert, true); projCrv.Dispose(); trans.Commit(); } }
I'm working on something similar at home where I also use C#. Can't give you any feedback until I do return home - no Visual Studio to compile it here at work.
Thanks for your time quick and dirty
;;;inserts a block at specified station along a polyline, measured from start LPS 2009(defun c:test () (vl-load-com)(defun rtd (a) (/ (* a 180.0) pi)) (setq oldosnap (getvar "osmode")) (setvar "osmode" 0) (command "ucs" "w") (setq ob (entsel "Select curve: ") dist (getreal "\n Specify Distance from beginning of curve : ") obj (vlax-ename->vla-object (car ob)) pt1 (vlax-curve-getPointAtDist obj dist) param1 (vlax-curve-getParamAtPoint obj pt1) deriv1 (vlax-curve-getFirstDeriv obj param1) ang (rtd (angle '(0 0) deriv1)) ) ;_ end of setq (command "-insert" "BLOCKNAME" pt1 "" ang) (command "ucs" "p") (setvar "osmode" oldosnap) (princ)) ;_ end of defun Or even a more ancient style:
(defun c:mscopy (/ n d ln lc ss i en) (while (not n) (setq n (getstring "\nBLOCK To INSERT: ")) (cond ((not (snvalid n)) (princ "\nInvalid Block Name - " n) (setq n nil)) ((tblsearch "BLOCK" n)) ((findfile (strcat n ".DWG")) (command "_.INSERT" n) (command)) ((setq n nil)))) (initget 7) (setq d (getdist "\nMeasure Segment Length: ")) (setq ln "TEMP1" lc 1) (while (tblsearch "LAYER" ln) (setq lc (1+ lc) ln (strcat "TEMP" (itoa lc)))) (command "_.LAYER" "_M" ln "") (while (= (getvar "CMDACTIVE") 0) (command "_.MEASURE" pause)) (command "_B" n "_Y" d) (setq ss (ssget "X" (list (cons 8 ln)))) (command "_.CHANGE" ss "" "_P" "_E" 0.0 "" "_.ERASE" ss "") (setq i (sslength ss)) (while (not (minusp (setq i (1- i)))) (setq en (ssname ss i)) (entdel en) (getstring "\nPress Enter To Continue: ") (entdel en)) (prin1))-David Only being able to place a block from the start of the line means it's not really usable for my needs. Having to hard wire the block is also a fundamental draawback.
Any way we can address these two points? Maybe select an existing block in the drawing to move or choose a block from a file; and then choose a point on the polyline to move it from.
Sorry to be cheeky. http://www.afralisp.net/ LOL-David
页:
[1]
2