mestar Posted July 22, 2010 Share Posted July 22, 2010 Hi everybody! This is my first post ever, I hope of some feedback... I am not an expert in lisp, but with a lot of searching I can manage to find and modify what I need. But in this case I don understand why in this code (which repeats inserting one block until user hits enter) the block is not visible on crosshair: (defun c:MyBlock (/ pt) (while (setq pt (getpoint "\nPick Insertion point.")) (command "-insert" "BlockName" "_non" pt "" pause) ) (princ) ) I have made also one with repeat, and then is the block visible on crosshair: (repeat 3000 (princ "\nPick Insertion point.") (command "insert" "BlockName" pause "" "" "") );end repeat But I would prefer not to use ESC to break repeat (before it makes the same 3000 times), as an user. Thanks very much, and have a nice day! Quote Link to comment Share on other sites More sharing options...
gile Posted July 22, 2010 Share Posted July 22, 2010 Hi, the block isn't visible on the crosshair because the point is specified in the (getpoint ...) expression which is evaluated before the (command "_insert"... ) statement. Quote Link to comment Share on other sites More sharing options...
mestar Posted July 22, 2010 Author Share Posted July 22, 2010 Hi, the block isn't visible on the crosshair because the point is specified in the (getpoint ...) expression which is evaluated before the (command "_insert"... ) statement. Hi Gile, Thanks! So there is no other way to see the block except with "repeat"? Quote Link to comment Share on other sites More sharing options...
gile Posted July 22, 2010 Share Posted July 22, 2010 Here's a way using grread. Inconvenient: you can't use osnaps. (defun c:MyBlock (/ InsertBlock elst gr loop) (defun InsertBlock () (entmake '((0 . "INSERT") (10 0.0 0.0 0.0) (2 . "BlockName") ) ) ) (InsertBlock) (setq elst (entget (entlast)) loop T) (while (and (setq gr (grread T 4 0)) loop) (cond ((= (car gr) 5) (entmod (subst (cons 10 (cadr gr)) (assoc 10 elst) elst)) ) ((= 3 (car gr)) (InsertBlock) (setq elst (entget (entlast))) ) (T (entdel (entlast)) (setq loop nil)) ) ) (princ) ) Quote Link to comment Share on other sites More sharing options...
alanjt Posted July 22, 2010 Share Posted July 22, 2010 Still have to hit escape to exit... (defun c:Test (/) (while t (command "_.-insert" "BlockName" "_s" 1.) (princ "\nSpecify insertion point: ") (command PAUSE) (princ "\nSpecify rotation: ") (command PAUSE) ) (princ) ) Quote Link to comment Share on other sites More sharing options...
mestar Posted July 22, 2010 Author Share Posted July 22, 2010 Thanks Gile, For your time, but without "osnap" I am dead man! Quote Link to comment Share on other sites More sharing options...
mestar Posted July 22, 2010 Author Share Posted July 22, 2010 Thanks Alan, For your time too, I have to consider ESC as a slolution. Have a nice day! Quote Link to comment Share on other sites More sharing options...
gile Posted July 22, 2010 Share Posted July 22, 2010 (edited) Here's a .NET solution: Command: MULTINSERT Prompt the user for a block name (or a dwg name, have to specify the full path if the the file isn't in AutoCAD search path), displays the bloc during insert, allows osnaps using, hit Enter or Space or right click to break the loop. C# code using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; namespace MultiInsertSample { public class MyBlockClass { class BlockJig : EntityJig { BlockReference m_blkRef; Point3d m_insPt; public BlockJig(BlockReference br) : base(br) { m_insPt = br.Position; m_blkRef = br; } protected override SamplerStatus Sampler(JigPrompts prompts) { JigPromptPointOptions jigOpts = new JigPromptPointOptions(); jigOpts.UserInputControls = (UserInputControls.Accept3dCoordinates | UserInputControls.NullResponseAccepted); jigOpts.Message = "\nEnter insert point: "; PromptPointResult ppr = prompts.AcquirePoint(jigOpts); if (m_insPt == ppr.Value) return SamplerStatus.NoChange; else m_insPt = ppr.Value; return SamplerStatus.OK; } protected override bool Update() { m_blkRef.Position = m_insPt; return true; } } [CommandMethod("MULTINSERT")] public void MultiInsert() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; PromptStringOptions opts = new PromptStringOptions("\nEnter block name: "); PromptResult pr = ed.GetString(opts); if (pr.Status != PromptStatus.OK) return; Transaction tr = doc.TransactionManager.StartTransaction(); using (tr) { BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); ObjectId blockId = ObjectId.Null; string name = pr.StringResult; if (bt.Has(name)) blockId = bt[name]; else { try { string filename = HostApplicationServices.Current.FindFile( name.EndsWith(".dwg") ? name : name + ".dwg", db, FindFileHint.Default); using (Database source = new Database(false, true)) { source.ReadDwgFile(filename, System.IO.FileShare.None, false, null); blockId = db.Insert(name, source, false); } } catch { ed.WriteMessage("\nBlock not found."); return; } } while (pr.Status == PromptStatus.OK) { Point3d pt = new Point3d(0, 0, 0); using (BlockReference br = new BlockReference(pt, blockId)) { BlockJig entJig = new BlockJig(br); pr = ed.Drag(entJig); if (pr.Status == PromptStatus.OK) { BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[blockTableRecord.ModelSpace], OpenMode.ForWrite); btr.AppendEntity(br); tr.AddNewlyCreatedDBObject(br, true); doc.TransactionManager.QueueForGraphicsFlush(); } } } tr.Commit(); } } } } MultInsert.zip Edited July 22, 2010 by gile Corrected error handling if the block (or file) is not found Quote Link to comment Share on other sites More sharing options...
alanjt Posted July 22, 2010 Share Posted July 22, 2010 Thanks Alan, For your time too, I have to consider ESC as a slolution. Have a nice day! You're welcome. It's about the best you can get, using LISP. Here's a .NET solution: Command: MULTINSERT Prompt the user for a block name (or a dwg name, have to specify the full path if the the file isn't in AutoCAD search path), displays the bloc during insert, allows osnaps using, hit Enter or Space or right click to break the loop. C# code using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; namespace MultiInsertSample { public class MyBlockClass { class BlockJig : EntityJig { BlockReference m_blkRef; Point3d m_insPt; public BlockJig(BlockReference br) : base(br) { m_insPt = br.Position; m_blkRef = br; } protected override SamplerStatus Sampler(JigPrompts prompts) { JigPromptPointOptions jigOpts = new JigPromptPointOptions(); jigOpts.UserInputControls = (UserInputControls.Accept3dCoordinates | UserInputControls.NullResponseAccepted); jigOpts.Message = "\nEnter insert point: "; PromptPointResult ppr = prompts.AcquirePoint(jigOpts); if (m_insPt == ppr.Value) return SamplerStatus.NoChange; else m_insPt = ppr.Value; return SamplerStatus.OK; } protected override bool Update() { m_blkRef.Position = m_insPt; return true; } } [CommandMethod("MULTINSERT")] public void MultiInsert() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; PromptStringOptions opts = new PromptStringOptions("\nEnter block name: "); PromptResult pr = ed.GetString(opts); if (pr.Status != PromptStatus.OK) return; Transaction tr = doc.TransactionManager.StartTransaction(); using (tr) { BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); ObjectId blockId = ObjectId.Null; string name = pr.StringResult; if (bt.Has(name)) blockId = bt[name]; else { string filename = HostApplicationServices.Current.FindFile( name.EndsWith(".dwg") ? name : name + ".dwg", db, FindFileHint.Default); if (filename == string.Empty) { ed.WriteMessage("\nBlock not found."); return; } using (Database source = new Database(false, true)) { source.ReadDwgFile(filename, System.IO.FileShare.None, false, null); blockId = db.Insert(name, source, false); } } while (pr.Status == PromptStatus.OK) { Point3d pt = new Point3d(0, 0, 0); using (BlockReference br = new BlockReference(pt, blockId)) { BlockJig entJig = new BlockJig(br); pr = ed.Drag(entJig); if (pr.Status == PromptStatus.OK) { BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[blockTableRecord.ModelSpace], OpenMode.ForWrite); btr.AppendEntity(br); tr.AddNewlyCreatedDBObject(br, true); doc.TransactionManager.QueueForGraphicsFlush(); } } } tr.Commit(); } } } } Nice work, Gile! Quote Link to comment Share on other sites More sharing options...
mestar Posted July 22, 2010 Author Share Posted July 22, 2010 Thanks Gile, But how can I start it? What shall I do with "MultiInsertSample.dll" ? I am not so good, guys! I have never seen something like that! Quote Link to comment Share on other sites More sharing options...
gile Posted July 22, 2010 Share Posted July 22, 2010 I corrected the error handling when the block (or file) is not found, so reload the new version. To use it, load the DLL from AutoCAD with the NETLOAD command (the DLL is loaded for the whole session) and type MULTINSERT. Quote Link to comment Share on other sites More sharing options...
mestar Posted July 22, 2010 Author Share Posted July 22, 2010 I corrected the error handling when the block (or file) is not found, so reload the new version. To use it, load the DLL from AutoCAD with the NETLOAD command (the DLL is loaded for the whole session) and type MULTINSERT. All right men! Excellent stuff!!! I owe you a beer! By the way, where is the new version? Thanks! "France 10 Points!" Quote Link to comment Share on other sites More sharing options...
gile Posted July 22, 2010 Share Posted July 22, 2010 By the way, where is the new version? In the first message, it replaces the old one. Quote Link to comment Share on other sites More sharing options...
mestar Posted July 22, 2010 Author Share Posted July 22, 2010 In the first message, it replaces the old one. Thanks again, I have learned something today, Have a nice day! Quote Link to comment Share on other sites More sharing options...
The Buzzard Posted July 24, 2010 Share Posted July 24, 2010 (edited) mestar, Here is a looping method that I use. Some might frown on it, But its really not bad. I have seen well known programmers use this method before. I create a function for the loop instead of using while allowing prompting of two choices, R or Enter for repeating insertion or E for program Exit. Give this a try. You will also see the block on insertion. The block name must be called MyBlock.dwg and must be in the ACAD Search Support Path or you can use findfile and specify the path. I included a line for this if you decide to use it. It is commented out temporary for now. I indicate instructions for this. See the attached Zip file. Sorry about that, But I am having trouble posting this code with code brackets. MyBlock.zip Edited July 24, 2010 by The Buzzard Quote Link to comment Share on other sites More sharing options...
Tharwat Posted July 24, 2010 Share Posted July 24, 2010 Here's a .NET solution: Hello gile. How do you make the .dll file ? .... and is it better than .vlx file ? Many thanks Tharwat Quote Link to comment Share on other sites More sharing options...
gile Posted July 24, 2010 Share Posted July 24, 2010 (edited) tharwhat313, This DLL is compiled from a .NET (C#) code, not LISP. And yes, "it's better than vlx" because .NET is more powerfull than LISP (this example shows it). Edited July 24, 2010 by gile Quote Link to comment Share on other sites More sharing options...
mestar Posted July 24, 2010 Author Share Posted July 24, 2010 mestar, Here is a looping method that I use. Some might frown on it, But its really not bad. I have seen well known programmers use this method before. I create a function for the loop instead of using while allowing prompting of two choices, R or Enter for repeating insertion or E for program Exit. Give this a try. You will also see the block on insertion. The block name must be called MyBlock.dwg and must be in the ACAD Search Support Path or you can use findfile and specify the path. I included a line for this if you decide to use it. It is commented out temporary for now. I indicate instructions for this. See the attached Zip file. Sorry about that, But I am having trouble posting this code with code brackets. Thanks Buzzard, It's OK, but there is a one klick too much (for my user who is to be my boss, and does not know anything about it...) I supose "repeat" could not be a default option and ESC as an exit? Thanks for your time! Quote Link to comment Share on other sites More sharing options...
The Buzzard Posted July 24, 2010 Share Posted July 24, 2010 Thanks Buzzard, It's OK, but there is a one klick too much (for my user who is to be my boss, and does not know anything about it...) I supose "repeat" could not be a default option and ESC as an exit? Thanks for your time! Thats Ok, I just want to put another option out there for you. I did setup R (Repeat) as a default so all you needed to do was right click the mouse for enter. You do not need to enter R each time, And when you were done click E for (Exit). As I mentioned not everyone cares for this method. If you are changing settings in the program it would pay to have an error trap so that ESC will not screw the settings up. I think the program works cleaner this way than using ESC. Quote Link to comment Share on other sites More sharing options...
The Buzzard Posted July 24, 2010 Share Posted July 24, 2010 (edited) I modified MyBlock.lsp to MyBlock2.lsp. I used you suggestion looping the insert command and allowing you to use ESC to exit. Its up to you, But as I said its sort of tacky. I would prefer the first lisp better. By the way, I had retested the first code comparing the amount of steps required to operate. There are no extra steps. You must hit enter to finish out the insert command in any event. So what is the difference between hitting enter in the loop or at the end of each insert which is the same thing. I mentioned before that you do not have to hit the R for Repeat, But right click for enter as this is set as default or enter. The E for Exit is no different than hitting ESC except that E for Exit is a cleaner way to exit as it does not show an error. The amount of steps required will depend upon the insert command input such as Block Scale and rotation. I will make one more code and post to show you the difference in speed of insertion by supply default values for these as well. You need to move away from those rogue code habits. MyBlock2.lsp Edited July 24, 2010 by The Buzzard Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.