now i have the polyline object id, but i don't know how to create a revcloud by select a object by code, and generate a revcloud entity.
public static void drawRevCloudLine(ObjectId polyId, double scale) { //最小弧长 string smallArc = Math.Ceiling(2.0 / scale).ToString(); //最大弧长 string largeArc = Math.Ceiling(6.0 / scale).ToString(); //运行命令 ResultBuffer rb = new ResultBuffer(); rb.Add(new TypedValue(5005, "_revcloud")); rb.Add(new TypedValue(5005, "_a")); rb.Add(new TypedValue(5005, smallArc)); rb.Add(new TypedValue(5005, largeArc)); rb.Add(new TypedValue(5006, polyId)); rb.Add(new TypedValue(5005, "_n")); try { acedCmd(rb.UnmanagedObject); Document doc = Application.DocumentManager.MdiActiveDocument; Editor editor = doc.Editor; Polyline rev=new Polyline(); editor.Command("_revcloud", "_a", smallArc, largeArc, polyId, "_n"); } catch (System.Exception ex) { AcadApp.ShowAlertDialog(ex.StackTrace + "\n" + ex.Message); } finally { rb.Dispose(); } }
the following is the support code
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Linq.Expressions; using System.Reflection; using Autodesk.AutoCAD.ApplicationServices; namespace Autodesk.AutoCAD.EditorInput { public static class EditorInputExtensionMethods { public static PromptStatus Command(this Editor editor, params object[] args) { if (editor == null) throw new ArgumentNullException("editor"); return runCommand(editor, args); } static Func<Editor, object[], PromptStatus> runCommand = GenerateRunCommand(); static Func<Editor, object[], PromptStatus> GenerateRunCommand() { MethodInfo method = typeof(Editor).GetMethod("RunCommand", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); var instance = Expression.Parameter(typeof(Editor), "instance"); var args = Expression.Parameter(typeof(object[]), "args"); return Expression.Lambda<Func<Editor, object[], PromptStatus>>( Expression.Call(instance, method, args), instance, args) .Compile(); } } }
Solved! Go to Solution.
Solved by _gile. Go to Solution.
It seems you're confusing.
Use acedCmd or runCommand but not both
P/Invoking acedCmd
private void drawRevCloudLine(ObjectId polyId, double scale) { ResultBuffer args = new ResultBuffer( new TypedValue((int)LispDataType.Text, "_revcloud"), new TypedValue((int)LispDataType.Text, "_arc"), new TypedValue((int)LispDataType.Double, 2.0 / scale), new TypedValue((int)LispDataType.Double, 2.0 / scale), new TypedValue((int)LispDataType.Text, "_object"), new TypedValue((int)LispDataType.ObjectId, polyId), new TypedValue((int)LispDataType.Text, "_no")); Command(args); }
Using runCommand wrapper
private void drawRevCloudLine(ObjectId polyId, double scale) { Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; ed.Command("_revcloud", "_arc", 2.0 / scale, 6.0 / scale, "_object", polyId, "_no"); }
Hi,Gilles:
I tried several times, but not joy. So i made an entire sample, please check for me, and point out where the code is wrong.
autocad2013+framwork4.0+vs2010
regards
swaywood
Your code does not work beacause you try to add to the current space and the transaction the polyligne created by the revcloud command.
You don't have to matter for this while you're calling AutoCAD commands, AutoCAD will do all this stuff for you.
Here's a way using the runCommand route and some other extension methods.
using System; using System.Linq.Expressions; using System.Reflection; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; using AcAp = Autodesk.AutoCAD.ApplicationServices.Application; namespace Acad2013CsTemplate { public class Commands { [CommandMethod("CLOUD")] public void Cloud() { Document doc = AcAp.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; PromptPointResult ppr = ed.GetPoint("\nSpecify the first corner: "); if (ppr.Status != PromptStatus.OK) return; Point3d pt1 = ppr.Value; ppr = ed.GetCorner("\nSpecify the opposite corner: ", pt1); if (ppr.Status != PromptStatus.OK) return; Point3d pt2 = ppr.Value; ObjectId id; using (Transaction tr = db.TransactionManager.StartTransaction()) using (Polyline pline = new Polyline(4)) { pline.AddVertexAt(0, new Point2d(pt1.X, pt1.Y), 0.0, 0.0, 0.0); pline.AddVertexAt(1, new Point2d(pt2.X, pt1.Y), 0.0, 0.0, 0.0); pline.AddVertexAt(2, new Point2d(pt2.X, pt2.Y), 0.0, 0.0, 0.0); pline.AddVertexAt(3, new Point2d(pt1.X, pt2.Y), 0.0, 0.0, 0.0); pline.Closed = true; id = db.GetCurrentSpace(OpenMode.ForWrite).Add(pline); tr.Commit(); } ed.Command("_revcloud", "_arc", 2.0, 6.0, "_object", id, "_no"); } } public static class Extension { public static PromptStatus Command(this Editor ed, params object[] args) { if (ed == null) throw new ArgumentNullException("ed"); return runCommand(ed, args); } static Func<Editor, object[], PromptStatus> runCommand = GenerateRunCommand(); static Func<Editor, object[], PromptStatus> GenerateRunCommand() { MethodInfo method = typeof(Editor).GetMethod( "RunCommand", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); ParameterExpression instance = Expression.Parameter(typeof(Editor), "ed"); ParameterExpression args = Expression.Parameter(typeof(object[]), "args"); return Expression.Lambda<Func<Editor, object[], PromptStatus>>( Expression.Call(instance, method, args), instance, args) .Compile(); } public static T GetObject<T>(this ObjectId id, OpenMode mode) where T : DBObject { return (T)id.GetObject(mode); } public static BlockTableRecord GetCurrentSpace(this Database db, OpenMode mode) { return db.CurrentSpaceId.GetObject<BlockTableRecord>(mode); } public static ObjectId Add(this BlockTableRecord owner, Entity ent) { ObjectId id = owner.AppendEntity(ent); owner.Database.TransactionManager.AddNewlyCreatedDBObject(ent, true); return id; } } }
Hi Gilles:
Unfortunatelly, I failed again.
Is there any systemvalue shall be set in AutoCAD?
I only got the Rectangle again.
And when I test by step, I found when run to line
'id = db.GetCurrentSpace(OpenMode.ForWrite).Add(pline);'
the code swith to func GenerateRunCommand.
And when the code run to line 'ed.Command("_revcloud", "_arc", 2.0, 6.0, "_object", id, "_no");'
It can run to 'return RunCommand(ed, args);'
but can not run into 'func GenerateRunCommand'
at last quit step by step.
Were you got the 'RevCloud' successfully?
PS:I found some 'runCommand', I changed it to 'RunCommand', but it seems no influence.
thanks
swaywood
Hi Gilles:
I found the problem where was, in autocad2013 there is a systemvalue 'nextfiberworld', I changed it to '0' before, so all the methods can not works fine, After change the value to 1, I got it both.
now i can draw the revsion cloud, but i do not know why the 'nextfiberworld' can control the both mthods?
thanks so much!
swaywood
Here is another one using command way:
//ads_queueexpr [DllImport("accore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl, EntryPoint = "ads_queueexpr")] extern static private int ads_queueexpr(byte[] command); public void CurveCloud(string hdl){ UnicodeEncoding uEncode = new UnicodeEncoding(); string hand= string.Format("(handent \"{0}\")",hdl); ads_queueexpr(uEncode.GetBytes("(command \"_.revcloud\" \"_arc\" \"2.54\" \"7.62\" \"_Ob\" " + hand + " \"N\"" + ")")); } [CommandMethod("revc")] public void MakeRevCloud() { var doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; var ed = doc.Editor; using (var tr = doc.TransactionManager.StartTransaction()) { ObjectId id = ed.GetEntity("\nSelect Closed curve").ObjectId; if (id != ObjectId.Null) { DBObject obj = tr.GetObject(id, OpenMode.ForRead); string hdl = obj.Handle.ToString(); obj.UpgradeOpen(); CurveCloud(hdl); tr.Commit(); } } }
Can't find what you're looking for? Ask the community or share your knowledge.