.NET
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic to the Top
- Bookmark
- Subscribe
- Printer Friendly Page
Area, Length and Width of last object created
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
Hey guys,
I'm trying to prompt a user to create a rectangle to use as a selection box to later layout blocks. The native rectangle command in AutoCAD 2012 is perfect but i need to get the area, length and width of the rectangle...is there a way that i could use something like editor.selectlast to figure this out?
Cheers
Vince
Solved! Go to Solution.
Re: Area, Length and Width of last object created
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
Not sure about A2012 but maybe this helps
<CommandMethod("Selast")> _
Public Sub testbox()
Dim doc As Document = Application.DocumentManager.MdiActiveDocument()
Dim db As Database = doc.Database
Dim ed As Editor = doc.Editor
Dim res As PromptSelectionResult
res = ed.SelectLast
Try
Using tr As Transaction = db.TransactionManager.StartTransaction
Dim ent As Entity = tr.GetObject(res.Value.GetObjectIds(0), OpenMode.ForRead)
Dim ecs As Extents3d = ent.GeometricExtents
Dim leng As Double = ecs.MaxPoint.X - ecs.MinPoint.X
Dim wid As Double = ecs.MaxPoint.Y - ecs.MinPoint.Y
Dim ar As Double = leng * wid
ed.WriteMessage(vbCr + "Length: {0}; Width: {1}; Area: {2}", leng, wid, ar)
End Using
Catch exs As System.Exception
ed.WriteMessage(exs.Message & vbLf & exs.StackTrace)
Finally
End Try
End Sub
~'J'~
C6309D9E0751D165D0934D0621DFF27919
Re: Area, Length and Width of last object created
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
Thanks Hallex, i'm going to try this out now and i'll report back. Would it be easier to just use the "area" command in autoCAD as my selection box as it provides all the info right away as well as a nice interface? If so, is it still possible to return the values for area, length and width into my code?
Cheers
Vince
Re: Area, Length and Width of last object created
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
I've just worked this back into C# but am running into an error on this line:
Entity ent = tr.GetObject(resr.Value.GetObjectIds(0), OpenMode.ForRead) as Entity;
The error I get is that "No overload for method 'GetObjectIDs' takes 1 arguments" and "Argument 1: cannot convert from 'Autodesk.AutoCAD.DatabaseServices.ObjectId[] to 'Autodesk.AutoCAD.DatabaseServices.ObjectId'
Is this something ridiculously simple??
Cheers
Vince
// Option 1 ... User Selects Rectangle as Shape
if (sres.StringResult == "rect")
{
Document docr = Autodesk.AutoCAD.ApplicationServices.Application.D ocumentManager.MdiActiveDocument;
Database dbr = doc.Database;
Editor edr = doc.Editor;
Document acDoc = Autodesk.AutoCAD.ApplicationServices.Application.D ocumentManager.MdiActiveDocument;
PromptSelectionResult resr = new PromptSelectionResult();
resr = ed.SelectLast();
acDoc.SendStringToExecute("._rectangle ", true, false, false);
Transaction tr = db.TransactionManager.StartTransaction();
using (tr)
{
//Entity ent = tr.GetObject(resr.Value.GetObjectIds(0), OpenMode.ForRead) as Entity;
Entity ent = tr.GetObject(resr.Value.GetObjectIds(0), OpenMode.ForRead) as Entity;
Extents3d ecs = ent.GeometricExtents;
double leng = ecs.MaxPoint.X - ecs.MinPoint.X;
double wid = ecs.MaxPoint.Y - ecs.MinPoint.Y;
double ar = leng * wid;
edr.WriteMessage("Length = " + leng);
edr.WriteMessage("Width = " + wid);
edr.WriteMessage("Area = " + ar);
}
Re: Area, Length and Width of last object created
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
You can stay avoid SendStringToExecute I think
Perhaps it will help as well:
<CommandMethod("Selast")> _
Public Sub testbox()
Dim doc As Document = Application.DocumentManager.MdiActiveDocument()
Dim db As Database = doc.Database
Dim ed As Editor = doc.Editor
Dim res As PromptSelectionResult
res = ed.SelectLast
Try
Using tr As Transaction = db.TransactionManager.StartTransaction
Dim ent As Entity = tr.GetObject(res.Value.GetObjectIds(0), OpenMode.ForRead)
Dim ecs As Extents3d = ent.GeometricExtents
Dim leng As Double = ecs.MaxPoint.X - ecs.MinPoint.X
Dim wid As Double = ecs.MaxPoint.Y - ecs.MinPoint.Y
Dim ar As Double = leng * wid
ed.WriteMessage(vbCr + "Length: {0}; Width: {1}; Area: {2}", leng, wid, ar)
Dim pres As PromptSelectionResult
'pres = ed.SelectCrossingWindow(ecs.MinPoint, ecs.MaxPoint) ''<-- you can add the filter there, e.g.:
''------------------------------------------------ -------------------------------------------------- --''
Dim filterList(,) As Object = New Object(,) {{-4, "<or"}, {0, "Line"}, {0, "Polyline"}, {0, "Insert"}, {0, "Circle"}, {0, "Circle"}, {-4, "or>"}} '' и т. д.
Dim tvs(filterList.GetUpperBound(0)) As TypedValue
For i As Integer = 0 To filterList.GetUpperBound(0)
tvs(i) = New TypedValue(Convert.ToInt32(filterList(i, 0)), filterList(i, 1))
Next
Dim filt As SelectionFilter = New SelectionFilter(tvs)
pres = ed.SelectCrossingWindow(ecs.MinPoint, ecs.MaxPoint, filt) ''<-- the filter added
''------------------------------------------------ -------------------------------------------------- --''
If pres IsNot Nothing Then
For Each selobj As SelectedObject In pres.Value
Dim obj As Entity = tr.GetObject(selobj.ObjectId, OpenMode.ForRead)
ed.WriteMessage(vbLf + obj.GetRXClass().DxfName)
Next
End If
End Using
Catch exs As System.Exception
ed.WriteMessage(exs.Message & vbLf & exs.StackTrace)
Finally
End Try
End Sub
~'J'~
C6309D9E0751D165D0934D0621DFF27919
Re: Area, Length and Width of last object created
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
Hi,
You may avoid using SendStringToexecute because it doesn't run synchronously.
You can define a 'Rectangle' Type with the properties and method you need.
Here's an example:
public class Rectangle { // constructor public Rectangle(Point3d p1, Point3d p2) { LowerLeft = new Point3d(Math.Min(p1.X, p2.X), Math.Min(p1.Y, p2.Y), 0.0); UpperRight = new Point3d(Math.Max(p1.X, p2.X), Math.Max(p1.Y, p2.Y), 0.0); Length = UpperRight.X - LowerLeft.X; Width = UpperRight.Y - LowerLeft.Y ; Area = Length * Width; } // public read only properties public Point3d LowerLeft { get; private set; } public Point3d UpperRight { get; private set; } public double Length { get; private set; } public double Width { get; private set; } public double Area { get; private set; } public SelectionSet CrossingSelectionSet { get { return Select(true); } } public SelectionSet WindowSelectionSet { get { return Select(false); } } // public method, draws the rectangle in the curre nt space. public void Draw() { Database db = HostApplicationServices.WorkingDatabase; using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite); using (Polyline pline = new Polyline()) { pline.AddVertexAt(0, new Point2d(LowerLeft.X, LowerLeft.Y), 0.0, 0.0, 0.0); pline.AddVertexAt(1, new Point2d(UpperRight.X, LowerLeft.Y), 0.0, 0.0, 0.0); pline.AddVertexAt(2, new Point2d(UpperRight.X, UpperRight.Y), 0.0, 0.0, 0.0); pline.AddVertexAt(3, new Point2d(LowerLeft.X, UpperRight.Y), 0.0, 0.0, 0.0); pline.Closed = true; btr.AppendEntity(pline); tr.AddNewlyCreatedDBObject (pline, true); } tr.Commit(); } } // public static method, creates a new instance of Rectangle if the user specifies two points public static Rectangle Create() { Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; PromptPointResult ppr = ed.GetPoint("\nFirst corner: "); if (ppr.Status == PromptStatus.Cancel) return null; Point3d pt = ppr.Value; ppr = ed.GetCorner("\nSecond corner: ", pt); if (ppr.Status == PromptStatus.Cancel) return null; Matrix3d ucs = ed.CurrentUserCoordinateSystem; return new Rectangle(pt.TransformBy(ucs), ppr.Value.TransformBy(ucs)); } // private method, returns the selection set private SelectionSet Select(bool crossing) { Editor ed = AcAp.DocumentManager.MdiActiveDocument.Editor; Matrix3d wcs = ed.CurrentUserCoordinateSystem.Inverse(); return crossing ? ed.SelectCrossingWindow(LowerL eft.TransformBy(wcs), UpperRight.TransformBy(wcs)) .Value : ed.SelectWindow(LowerLeft.Tran sformBy(wcs), UpperRight.TransformBy(wcs)).Value; } }
Then, using this type, you can prompt the user to draw a rectangle the same wat as the native AutoCAD Command, get the data you need (length, width and area), use the rectangle to get a selection set.
Here's a little example:
[CommandMethod("test")] public void test() { Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; Rectangle rect = Rectangle.Create(); if (rect == null) return; SelectionSet ss = rect.WindowSelectionSet; ed.SetImpliedSelection(ss); rect.Draw(); ed.WriteMessage("\nLength = {0} Width = {1} Area = {2}", rect.Length, rect.Width, rect.Area); }
Re: Area, Length and Width of last object created
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
My shot:
<CommandMethod("DREC")> _
Public Sub DrawRect()
Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.D ocumentManager.MdiActiveDocument
Dim db As Database = HostApplicationServices.WorkingDatabase()
Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Edit or
Dim p1, p2 As Point3d
Using acTrans As Transaction = db.TransactionManager.StartTransaction()
Dim acSSPrompt As PromptPointResult = doc.Editor.GetPoint("Select First Point: ")
If acSSPrompt.Status = PromptStatus.OK Then
p1 = acSSPrompt.Value
acSSPrompt = doc.Editor.GetCorner(vbCrLf + "Select Second Point: ", p1)
If acSSPrompt.Status = PromptStatus.OK Then
p2 = acSSPrompt.Value
Else
MsgBox("Invalid point")
Exit Sub
End If
Else
MsgBox("Invalid point")
Exit Sub
End If
Dim v1 As Vector3d
Dim theta As Double
Dim p3, p4 As Point2D
Dim a, b, l, s As Double
Dim d As Double
v1 = p1.GetVectorTo(p2)
theta = v1.GetAngleTo(Vector3d.XAxis, Vector3d.ZAxis.Negate())
d = p1.DistanceTo(p2)
a = d * Math.Cos(theta)
b = d * Math.Sin(theta)
l = 2 * (Math.Abs(a) + Math.Abs(b))
s = Math.Abs(a * b)
If s <= 0.001 Then
MsgBox("Degenerated Rectangle, try again", vbCritical)
Exit Sub
End If
p3 = New Point3d(p1.X + a, p1.Y)
p4 = New Point3d(p1.X, p1.Y + b)
Dim pl As New Polyline
pl.AddVertexAt(0, New Point2d(p1.X, p1.Y), 0, 0, 0)
pl.AddVertexAt(1, p3, 0, 0, 0)
pl.AddVertexAt(2, New Point2d(p2.X, p2.Y), 0, 0, 0)
pl.AddVertexAt(3, p4, 0, 0, 0)
pl.Closed = True
Dim acBlkTbl As BlockTable
acBlkTbl = acTrans.GetObject(db.BlockTableId, OpenMode.ForRead)
Dim acBlkTblRec As BlockTableRecord
acBlkTblRec = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelS pace), OpenMode.ForWrite)
acBlkTblRec.AppendEntity(pl)
acTrans.AddNewlyCreatedDBObject(pl, True)
ed.WriteMessage(vbCrLf + "Rectangle length:=" + l.ToString + vbCrLf)
ed.WriteMessage("Rectangle Area:=" + s.ToString + vbCrLf)
ed.WriteMessage("Width:=" + Math.Abs(a).ToString + vbCrLf)
ed.WriteMessage("Height:=" + Math.Abs(b).ToString + vbCrLf)
acTrans.Commit()
End Using
End Sub
Re: Area, Length and Width of last object created
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
Thanks to everyone for their input! _gile thank you very much, with your example i got it working perfectly, much appreciated!!!!
