Hi,
welcome @Anonymous.autodesk.com!
Please show us your code, so we know where you are and at which position you have difficulties.
- alfred -
Hi,
a dll-file is not attached ... and even if there would be one I would never open it (out of security reasons).
I meant to show the source code where you are at the moment.
- alfred -
/*ClassLibrary code*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
namespace ClassLibrary1
{
public class Class1
{
[CommandMethod("CalculateDefinedArea")]
public static void CalculateDefinedArea()
{
// Prompt the user for 5 points
Document acDoc = Application.DocumentManager.MdiActiveDocument;
PromptPointResult pPtRes;
Point2dCollection colPt = new Point2dCollection();
PromptPointOptions pPtOpts = new PromptPointOptions("");
// Prompt for the first point
pPtOpts.Message = "\nSpecify first point: ";
pPtRes = acDoc.Editor.GetPoint(pPtOpts);
colPt.Add(new Point2d(pPtRes.Value.X, pPtRes.Value.Y));
// Exit if the user presses ESC or cancels the command
if (pPtRes.Status == PromptStatus.Cancel) return;
int nCounter = 1;
while (nCounter <= 4)
{
// Prompt for the next points
switch (nCounter)
{
case 1:
pPtOpts.Message = "\nSpecify second point: ";
break;
case 2:
pPtOpts.Message = "\nSpecify third point: ";
break;
case 3:
pPtOpts.Message = "\nSpecify fourth point: ";
break;
case 4:
pPtOpts.Message = "\nSpecify fifth point: ";
break;
}
// Use the previous point as the base point
pPtOpts.UseBasePoint = true;
pPtOpts.BasePoint = pPtRes.Value;
pPtRes = acDoc.Editor.GetPoint(pPtOpts);
colPt.Add(new Point2d(pPtRes.Value.X, pPtRes.Value.Y));
if (pPtRes.Status == PromptStatus.Cancel) return;
// Increment the counter
nCounter = nCounter + 1;
}
// Create a polyline with 5 points
using (Polyline acPoly = new Polyline())
{
acPoly.AddVertexAt(0, colPt[0], 0, 0, 0);
acPoly.AddVertexAt(1, colPt[1], 0, 0, 0);
acPoly.AddVertexAt(2, colPt[2], 0, 0, 0);
acPoly.AddVertexAt(3, colPt[3], 0, 0, 0);
acPoly.AddVertexAt(4, colPt[4], 0, 0, 0);
// Close the polyline
//acPoly.Closed = true;
acPoly.Length.ToString();
// Query the area of the polyline
Application.ShowAlertDialog("Area of polyline: " +
acPoly.Area.ToString());
// Dispose of the polyline
}
}
[CommandMethod("CalulatePerimeter")]
public static void CalculateDefinedPerimeter()
{
// Prompt the user for 5 points
Document acDoc = Application.DocumentManager.MdiActiveDocument;
PromptPointResult pPtRes;
Point2dCollection colPt = new Point2dCollection();
PromptPointOptions pPtOpts = new PromptPointOptions("");
// Prompt for the first point
pPtOpts.Message = "\nSpecify first point: ";
pPtRes = acDoc.Editor.GetPoint(pPtOpts);
colPt.Add(new Point2d(pPtRes.Value.X, pPtRes.Value.Y));
// Exit if the user presses ESC or cancels the command
if (pPtRes.Status == PromptStatus.Cancel) return;
int nCounter = 1;
while (nCounter <= 4)
{
// Prompt for the next points
switch (nCounter)
{
case 1:
pPtOpts.Message = "\nSpecify second point: ";
break;
case 2:
pPtOpts.Message = "\nSpecify third point: ";
break;
case 3:
pPtOpts.Message = "\nSpecify fourth point: ";
break;
case 4:
pPtOpts.Message = "\nSpecify fifth point: ";
break;
}
// Use the previous point as the base point
pPtOpts.UseBasePoint = true;
pPtOpts.BasePoint = pPtRes.Value;
pPtRes = acDoc.Editor.GetPoint(pPtOpts);
colPt.Add(new Point2d(pPtRes.Value.X, pPtRes.Value.Y));
if (pPtRes.Status == PromptStatus.Cancel) return;
// Increment the counter
nCounter = nCounter + 1;
}
// Create a polyline with 5 points
using (Polyline acPoly = new Polyline())
{
acPoly.AddVertexAt(0, colPt[0], 0, 0, 0);
acPoly.AddVertexAt(1, colPt[1], 0, 0, 0);
acPoly.AddVertexAt(2, colPt[2], 0, 0, 0);
acPoly.AddVertexAt(3, colPt[3], 0, 0, 0);
acPoly.AddVertexAt(4, colPt[4], 0, 0, 0);
// Close the polyline
//acPoly.Closed = true;
acPoly.Length.ToString();
// Query the area of the polyline
Application.ShowAlertDialog("Length of polyline:-" + acPoly.Length.ToString());
// Dispose of the polyline
}
}
}
}
I'm able to calculate Area, iPerimeter from this.ButI can't get exact vertices for marking to get the proper measurements. In addition i would like to have the output to be displayed in a pop-up text window like below
x= 66 x'=66
y=60 y'=60
Area= 3960
It is better to have an option to get this parameter in an Excel file too.
Hi,
>> open DWG file in this Cadsofttool.Or give me a solution to implement the above-mentioned function in CAD editor.
Please ask the vendor or that tool, or search for a forum that discusses development based on that tool.
I don't know their API and this forum (VB for AutoCAD) does not handle that tool.
This code here is not VB or VBA, it's C#.
Also it uses directly the AutoCAD API, maybe that the tool "Cadsofttool" works based on AutoCAD then it might work, but that's all guessing now.
Sorry, - alfred -
Hi, i'm not sure if your intention is to generate polylines and export values.
I'm making that task by inversing the process.
i will write pseudo code, if needed i can write the full one and deliver in few days.
dim POLYAREA as double
dim PERIMETER as double
dim stringpolydata as string
query polyline from model
select polyline
add to selection
lock document
open transaction
get id of selection
POLYAREA = polylineID.area
perimeter= by method or simple math iteration through vertices x,y deltas
stringdatapoly = polyarea & format delimiter & perimeter convert to string, round decimals, format the string etc.
close and dispose transaction
unlock document
use streamwriter to write the data in external txt file
embed variable into msgbox("data: " & stringpolydata)
in excel create file with data connection to point the path of streamwriter export txt (you can use csv formating here same as stringdata poly)
let me know if needed to work on code or this is enough for you.
Hello Kacarikalen
I'm glad to hear from you. It will be kind if you could help in this coding.
Here i can explain to you the Aim of my program
Case 1
1) Import the AutoCAD DWG file to open in developing software
2) Implement polyline function to calculate x,y, length , Area and Perimeter.(including the measurement of polygonal plan)
3) get the measurements of selected portions such as Bedroom /kitchen so on. In general, like on AutoCAD by using a polyline to get inner and outer measurements.
3)Display the output in a pop-up text file like on AutoCAD.
4) it is good to have the result to be download in excel file
if you still have any doubt, please feel free to ask me
Best Regards
Wintereskimo
Hello again wintereskimo,
thank you for providing me more details.
I will code that today/tomorrow for you. 🙂
Take care!
Hi, here is your code as i promised.
I'm sorry for slight delay, i was in rush and couldn't write it earlier.
Please let me know if you like it, however i'd extend the options more but i believe this is enough to get you going. I know the struggle and feel when you can't find the resources.
I've also added some extra options which you may find useful when working with this similar tasks.
please open blank dll project...
add winform item named form1 to solution and drop the savefiledialog from toolbox onto the form, add one button and one textbox.
you need to have a layer named "polylinelayer" in dwg and polylines on that layer but this can be changed in various ways to improve the usability
this is the code for dll ... class1.vb
Imports Autodesk.AutoCAD.ApplicationServices Imports Autodesk.AutoCAD.Colors Imports Autodesk.AutoCAD.ComponentModel Imports Autodesk.AutoCAD.DatabaseServices Imports Autodesk.AutoCAD.EditorInput Imports Autodesk.AutoCAD.Geometry Imports Autodesk.AutoCAD.GraphicsSystem Imports Autodesk.AutoCAD.Internal Imports Autodesk.AutoCAD.LayerManager Imports Autodesk.AutoCAD.PlottingServices Imports Autodesk.AutoCAD.Publishing Imports Autodesk.AutoCAD.Runtime Imports Autodesk.AutoCAD.Windows Imports System.Windows.Forms Imports System.IO Imports System.Math Imports System.Reflection Imports System.Resources Imports System.Runtime Imports System.Dynamic Imports System.Data Imports System.Globalization Imports System Imports System.Collections.Generic Imports System.Linq Imports System.Text Imports System.Threading Imports XYsourcecode.Form1 Public Class Class1 ' !!!!!!!!!! 'this is hardcoded layer name, this can be obtained by selecting iterations from layer records 'for the scope of this code in your working dwg there must be a layer with this name. !!! make a layer with name "polylinelayer" Public ply As String = "polylinelayer" 'number of polylines Public polycount As Integer = 0 'our value string, needs proper formating to get it more efficient i just wrote some description formatting Public Shared EXPORT_FORMATSTRING As String 'this is to make sure that PLarea is done, you can implement threads on this Public process_thread As Boolean = False 'this is your acad command <CommandMethod("areafrompolyline")> Public Sub areafrompolyline() 'main sub PLarea() 'if succeded open export form, i made this so you can move on after you get values If process_thread = True Then 'opens form, you can continue from there Dim export_form As New Form1 export_form.Show() Else MsgBox("haven't processed PLarea sub", MsgBoxStyle.Information) End If End Sub Private Sub PLarea() 'counts the polylines EntitiesOnLayer(ply) 'if there is a polyline get the values If polycount > 0 Then Dim doc As Document = Core.Application.DocumentManager.MdiActiveDocument Dim ed As Editor = doc.Editor Dim db As Database = doc.Database Using docloc As DocumentLock = doc.LockDocument() Dim PLINEidOBJdb As ObjectIdCollection = New ObjectIdCollection() 'dxf code Dim filterlistPOL As TypedValue() = New TypedValue(1) {} filterlistPOL(0) = New TypedValue(0, "LWPOLYLINE") filterlistPOL(1) = New TypedValue(8, ply) 'selection set Dim filterPOL As New SelectionFilter(filterlistPOL) Dim selPOLRes As PromptSelectionResult = ed.SelectAll(filterPOL) Dim POLids As ObjectId() = selPOLRes.Value.GetObjectIds() 'polyline id collection PLINEidOBJdb = New ObjectIdCollection(POLids) Using ts As Transaction = db.TransactionManager.StartTransaction Dim polilinije As New ObjectIdCollection(selPOLRes.Value.GetObjectIds()) 'some description EXPORT_FORMATSTRING = "Number of polylines: " & polycount & vbCrLf 'this is iterator to count polylines Dim j As Integer = 1 'for loop to iterate for every polyline For Each tid As ObjectId In polilinije If tid.ObjectClass.Name.Equals("AcDbPolyline") Then EXPORT_FORMATSTRING = EXPORT_FORMATSTRING Using polylocker As DocumentLock = doc.LockDocument() 'get polyline values Dim pl As Polyline = TryCast(ts.GetObject(tid, OpenMode.ForWrite), Polyline) Dim plArea As Double = Math.Round(pl.Area, 2) Dim plPerimeter As Double = Math.Round(pl.Length, 2) Dim plVertexcount As Integer = pl.NumberOfVertices Dim plSegment As Double 'using delimeters instead of vbclrf could increase productivity if you format your strings properly for upcoming processes 'notice the " " as delimiter so you can open it in excel EXPORT_FORMATSTRING = EXPORT_FORMATSTRING & "polyline" & j & vbCrLf & "Area:" & " " & plArea & vbCrLf & "Perimeter:" & " " & plPerimeter & vbCrLf 'iterate through polyline segments between vertices and get distance value For i As Integer = 0 To plVertexcount - 2 Dim ln As LineSegment2d = pl.GetLineSegment2dAt(i) 'this is the polyline segment value plSegment = ln.Length 'round it to 2 decimal places, or more ofc plSegment = Math.Round(plSegment, 2) 'format string for polyline segments EXPORT_FORMATSTRING = EXPORT_FORMATSTRING & "l" & (i + 1) & ":" & " " & plSegment & vbCrLf 'move on next polylines segment Next End Using End If j = j + 1 'this just counts polylines 'moves on next polyline Next 'we didnt stored any changed so it is important to abort the transaction ts.Abort() End Using 'close transaction End Using Else MsgBox("There are no polylines on this layer", MsgBoxStyle.Information) End If 'this is just for showing, it will open form process_thread = True End Sub Public Sub EntitiesOnLayer(ByVal ply As String) 'this sub returns polyline entities count on layer where desired polylines are living Dim ents As ObjectIdCollection = GetEntitiesOnLayer(ply) 'number of polylines polycount = ents.Count End Sub Private Function GetEntitiesOnLayer(ByVal ply As String) As ObjectIdCollection 'this function returns ids of polylines on layer with name stored in ply string variable Dim doc As Document = Core.Application.DocumentManager.MdiActiveDocument Dim ed As Editor = doc.Editor ' Build a filter list so that only entities ' on the specified layer are selected ' this is the DXF code specification '0 = DxfCode.entity '8 = DxfCode.LayerName Dim tvs As TypedValue() = New TypedValue(1) {} tvs(0) = New TypedValue(0, "LWPOLYLINE") tvs(1) = New TypedValue(8, ply) Dim sf As New SelectionFilter(tvs) Dim psr As PromptSelectionResult = ed.SelectAll(sf) 'this is writen just to click ok If psr.Status = PromptStatus.OK Then Return New ObjectIdCollection(psr.Value.GetObjectIds()) Else Return New ObjectIdCollection() End If End Function End Class
this is the code for form1 class
i made it this way for you to get it easier, so you can export excel and move on winforms functions with that
just note about delimiters and you will be fine.
Imports Autodesk.AutoCAD.ApplicationServices Imports Autodesk.AutoCAD.Colors Imports Autodesk.AutoCAD.ComponentModel Imports Autodesk.AutoCAD.DatabaseServices Imports Autodesk.AutoCAD.EditorInput Imports Autodesk.AutoCAD.Geometry Imports Autodesk.AutoCAD.GraphicsSystem Imports Autodesk.AutoCAD.Internal Imports Autodesk.AutoCAD.LayerManager Imports Autodesk.AutoCAD.PlottingServices Imports Autodesk.AutoCAD.Publishing Imports Autodesk.AutoCAD.Runtime Imports Autodesk.AutoCAD.Windows Imports System.Windows.Forms Imports System.IO Imports System.Math Imports System.Reflection Imports System.Resources Imports System.Runtime Imports System.Dynamic Imports System.Data Imports System.Globalization Imports System Imports System.Collections.Generic Imports System.Linq Imports System.Text Imports System.Threading Imports XYsourcecode.Class1 Public Class Form1 Public dr As DialogResult 'you can define additional dialog options Public export As String = XYsourcecode.Class1.EXPORT_FORMATSTRING 'notice that in class1 EXPORT_FORMATSTRING is shared declared Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load TextBox1.Text = export End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'opens dialog dr = SaveFileDialog1.ShowDialog SaveFileDialog1.Filter = "spreadsheet|*.xls|All files|*.*" ' PUT .xls AS FORMAT If dr = DialogResult.OK Then 'gets path to save a file Dim savepath As String = SaveFileDialog1.FileName Dim file As StreamWriter file = My.Computer.FileSystem.OpenTextFileWriter(savepath, False) file.WriteLine(export) 'here in brackets goes the string file.Close() MsgBox("File at destination " & vbCrLf & savepath & vbCrLf & " successfully saved!") Else 'if you exit the dialog without saving MsgBox("Export cancelled by user", MsgBoxStyle.Information) End If End Sub End Class
i hope you find this usefull.
This app could be done in many various ways, i've done it like this and still can be improved a lot, just a basic working example, now it is up to you to extend it how you like more. If you need coordinates x,y of vertices let me know, however you can get them in vertex iterations.
If you have any additional questions don't hesitate to ask, i'll help if i can and don't forget to kudo or solution accept please im here active just from 2 days ago but having account long time.
Have a nice day and please let me know your thoughts. 🙂
hello
thanks a lot for your immediate help. I will get back to you soon after test it.
will keep in contact with you !!
Best Regard
Winter
Hello,
Can't find what you're looking for? Ask the community or share your knowledge.