.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Findind closed area (Like hatch function does)

18 REPLIES 18
Reply
Message 1 of 19
Rurik
1507 Views, 18 Replies

Findind closed area (Like hatch function does)

Hi,

I would like to have function which works similar to hatch. Lets say we got a rectangle. I need to fill in this area using my own AutoCAD blocks. My problems are:

- How to find borders of closed area (eg. polyline, circle)?
- Is it possible to use hatch function (with own hatch style) to do that?
- I will be grateful for any code examples (C# or VB) of using hatch.
18 REPLIES 18
Message 2 of 19
mahersy
in reply to: Rurik

Have not tried it but use the boundary command to create a poly line, grab the last entity created (the polyline) and then cycle through the vertices.
look at this page for cycling through the verities.
http://through-the-interface.typepad.com/through_the_interface/2007/04/iterating_throu.html
Message 3 of 19
Anonymous
in reply to: Rurik

Hay Rurik
Here is what you wanted I hope
Just change block name "TREE" on what
you need
Hth

~'J'~

Imports System
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Colors

Namespace CustomUtils
Public Class HatchWithBlocks
_
Public Shared Sub FillWithBlocks()

Dim adoc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
Dim db As Database = adoc.Database
Dim ed As Editor = adoc.Editor
Dim res As PromptEntityResult = ed.GetEntity(vbNewLine & "Pick a polyline:")

If res.Status <> PromptStatus.OK Then
MsgBox("Bad news...You missed, buddy...")
Return
End If

Dim pID As ObjectId = res.ObjectId
Dim tr As Transaction = db.TransactionManager.StartTransaction()
Dim opline As Polyline = CType(tr.GetObject(pID, OpenMode.ForRead), Polyline)
Dim vxs As Point3dCollection = New Point3dCollection()
For i As Integer = 0 To opline.NumberOfVertices - 1 Step i + 1
Dim pt As Point3d = opline.GetPoint3dAt(i)
vxs.Add(pt)
Next

Dim ext As Extents3d = opline.GeometricExtents
Dim dres As PromptDoubleResult = ed.GetDouble(vbNewLine & "Enter gap between the first block and the boundary:")
If dres.Status <> PromptStatus.OK Then
Return
End If

Dim gap As Double = dres.Value
Dim pmin As Point3d = New Point3d(ext.MinPoint.X + gap, ext.MinPoint.Y + gap, ext.MinPoint.Z)
Dim pmax As Point3d = New Point3d(ext.MaxPoint.X - gap, ext.MaxPoint.Y - gap, ext.MaxPoint.Z)
Dim ires As PromptIntegerResult = ed.GetInteger(vbNewLine & "Enter the number of blocks per one row:")
If ires.Status <> PromptStatus.OK Then
Return
End If

Dim nrow As Integer = ires.Value
ires = ed.GetInteger(vbNewLine & "Enter the number of blocks per one column:")
Dim ncol As Integer = ires.Value
Dim lrow = pmax.X - pmin.X
Dim lcol = pmax.Y - pmin.Y
Dim stepx As Double = lrow / nrow
Dim stepy As Double = lcol / ncol

Dim bt As BlockTable = CType(tr.GetObject(db.BlockTableId, OpenMode.ForWrite), BlockTable)
Dim btr As BlockTableRecord = CType(tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)

If Not (bt.Has("TREE")) Then
Return
End If
Dim objIds As ObjectIdCollection = New ObjectIdCollection
Dim blkID As ObjectId = bt("TREE")
For n As Integer = 0 To nrow - 1
For m As Integer = 0 To ncol - 1
Dim inspt As Point3d = New Point3d(pmin.X + n * stepx, pmin.Y + m * stepy, pmin.Z)
Dim bref As BlockReference = New BlockReference(inspt, blkID)

btr.AppendEntity(bref)
tr.AddNewlyCreatedDBObject(bref, True)

objIds.Add(bref.ObjectId)
ed.WriteMessage(String.Format(vbNewLine & "ID = {0}", bref.ObjectId)) '// debug only
Next
Next
tr.Commit()
tr.Dispose()
tr = db.TransactionManager.StartTransaction()
Dim filList() As TypedValue = {New TypedValue(DxfCode.Start, "INSERT"), _
New TypedValue(DxfCode.BlockName, "TREE")}
Dim filter As SelectionFilter = New SelectionFilter(filList)
Dim opts As PromptSelectionOptions = New PromptSelectionOptions()
Dim sres As PromptSelectionResult = ed.SelectWindowPolygon(vxs, filter) 'ed.GetSelection(opts, filter)
If sres.Status <> PromptStatus.OK Then
Return
End If

Dim sset As SelectionSet = sres.Value
Dim blkIDs() As ObjectId = sset.GetObjectIds()

Dim delColl As ObjectIdCollection = New ObjectIdCollection
Dim id As ObjectId
Dim brefID As ObjectId
Dim enm As IEnumerator = objIds.GetEnumerator()
enm.Reset()
While enm.MoveNext()
id = enm.Current
For Each brefID In blkIDs
If Equals(brefID.Handle, id.Handle) Then
objIds.Remove(id)
End If
Next
End While

Dim entId As ObjectId
Dim denm As IEnumerator = objIds.GetEnumerator()
denm.Reset()
While denm.MoveNext()
entId = denm.Current()
Dim ent As Entity = tr.GetObject(entId, OpenMode.ForWrite, False, True)
If Not ent Is Nothing Then
ent.Erase()
ent.Dispose()
End If
End While

ed.Regen()
tr.Commit()
tr.Dispose()

End Sub
End Class
End Namespace
Message 4 of 19
Rurik
in reply to: Rurik

Hi Fatty,

Thanks for code. Works fine! But there are still some limitations. Usually I cant pick a polyline (area is "closed" by few separate objects, lines, circles). So I would like to have something like _BOUNDARY function implemented.

- What are the ways to find boundary?
- Is finding boundary necessary? Maybe there are other ways?
Message 5 of 19
Anonymous
in reply to: Rurik

I've tried to solve it but with no luck sorry

~'J'~
Message 6 of 19
Anonymous
in reply to: Rurik

try this to get your boundary

Private Declare Function acedCmd Lib "acad.exe" Alias "acedCmd" (ByVal vlist As System.IntPtr) As Integer

Public Sub HatchBoundary(ByVal pt As Point2d)
Dim rb As ResultBuffer = New ResultBuffer
Try
rb.Add(New TypedValue(5005, "._-BOUNDARY"))
rb.Add(New TypedValue(5005, "_AD"))
rb.Add(New TypedValue(5005, "_IS"))
rb.Add(New TypedValue(5005, "_Y"))
rb.Add(New TypedValue(5005, "_OB"))
rb.Add(New TypedValue(5005, "PO"))
rb.Add(New TypedValue(5005, ""))
rb.Add(New TypedValue(5005, (pt.X.ToString + ("," + pt.Y.ToString))))
rb.Add(New TypedValue(5005, ""))

acedCmd(rb.UnmanagedObject)
Catch ex As System.Exception
MsgBox("Hatch Boundary Error " & ex.Message)
Finally
rb.Dispose()
End Try
End Sub

then you can get your lastentity


pat
Message 7 of 19
Anonymous
in reply to: Rurik

> rb.Add(New TypedValue(5005, (pt.X.ToString + ("," + pt.Y.ToString))))

Consider using the right group code and the
native type (Point3d in this case), instead of
converting the point to string input.

That sort of practice is necessary in VBA or
VB6 when calling SendCommand(), but it is
not needed, and shouldn't be used when
you're calling acedCmd in .NET.

So, instead of the above, you can just do this:

rb.Add( New TypedValue(5009, pt) )



--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2008
Supporting AutoCAD 2000 through 2008
http://www.acadxtabs.com

wrote in message news:5578612@discussion.autodesk.com...
try this to get your boundary

Private Declare Function acedCmd Lib "acad.exe" Alias "acedCmd" (ByVal vlist As System.IntPtr) As Integer

Public Sub HatchBoundary(ByVal pt As Point2d)
Dim rb As ResultBuffer = New ResultBuffer
Try
rb.Add(New TypedValue(5005, "._-BOUNDARY"))
rb.Add(New TypedValue(5005, "_AD"))
rb.Add(New TypedValue(5005, "_IS"))
rb.Add(New TypedValue(5005, "_Y"))
rb.Add(New TypedValue(5005, "_OB"))
rb.Add(New TypedValue(5005, "PO"))
rb.Add(New TypedValue(5005, ""))
rb.Add(New TypedValue(5005, (pt.X.ToString + ("," + pt.Y.ToString))))
rb.Add(New TypedValue(5005, ""))

acedCmd(rb.UnmanagedObject)
Catch ex As System.Exception
MsgBox("Hatch Boundary Error " & ex.Message)
Finally
rb.Dispose()
End Try
End Sub

then you can get your lastentity


pat
Message 8 of 19
Anonymous
in reply to: Rurik

acedCmd doesn't require you to convert everything
to a string (like SendCommand() in VBA does), you
can pass coordinates directly using the appropriate
code (5009 for 3d coordinates):

Dim myPoint As Point3d = new Point3d(2.0, 2.0, 0.0)
rb.Add( New TypedValue(5009, myPoint))

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2008
Supporting AutoCAD 2000 through 2008
http://www.acadxtabs.com

wrote in message news:5578612@discussion.autodesk.com...
try this to get your boundary

Private Declare Function acedCmd Lib "acad.exe" Alias "acedCmd" (ByVal vlist As System.IntPtr) As Integer

Public Sub HatchBoundary(ByVal pt As Point2d)
Dim rb As ResultBuffer = New ResultBuffer
Try
rb.Add(New TypedValue(5005, "._-BOUNDARY"))
rb.Add(New TypedValue(5005, "_AD"))
rb.Add(New TypedValue(5005, "_IS"))
rb.Add(New TypedValue(5005, "_Y"))
rb.Add(New TypedValue(5005, "_OB"))
rb.Add(New TypedValue(5005, "PO"))
rb.Add(New TypedValue(5005, ""))
rb.Add(New TypedValue(5005, (pt.X.ToString + ("," + pt.Y.ToString))))
rb.Add(New TypedValue(5005, ""))

acedCmd(rb.UnmanagedObject)
Catch ex As System.Exception
MsgBox("Hatch Boundary Error " & ex.Message)
Finally
rb.Dispose()
End Try
End Sub

then you can get your lastentity


pat
Message 9 of 19
Anonymous
in reply to: Rurik

Thanks, I will test it tomorrow

pat
Message 10 of 19
mahersy
in reply to: Rurik

Just having a look around. How do you get the last entity added into the database IN .NET?
In vlisp, which is the way i have used it. You use the method "utl:entity:get:last"
In ObjectARX it is "acdbEntLast" Function.
In .NET Wraper???
Message 11 of 19
Anonymous
in reply to: Rurik

Dear Tony Tanzillo
How to convert this global function
on VB.NET or C#?

///////////////////////////
int
acdbEntLast
(ads_name result);
///////////////////////////

I tied to use BlockRecordEnumerator with no luck,
which did not return last entity after 'boundary' command
Thanks in advance

Regards

~'J'~
Message 12 of 19
Anonymous
in reply to: Rurik

I think the easiest to get the last entity is this approach

Dim editor As Editor = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor

Dim selecEnt As PromptSelectionResult = editor.SelectLast

pat
Message 13 of 19
Anonymous
in reply to: Rurik

Thanks for the reply, Patrick
This trick not working too
Try it on the polygon that was bounded
with lines
"SelectLast" method will select last created
line only...

Regards

~'J'~
Message 14 of 19
Anonymous
in reply to: Rurik

Actually, I am starting to look at this exact issue. Hatch that may have islands.

I have some ideas to think about and try.
If I get something working, will let you know.

pat
Message 15 of 19
Anonymous
in reply to: Rurik

Thanks again,
in my opinion there is one way only
to use "acdbEntLast" function to get
the really last object in this case
Maybe I am wrong though

~'J'~
Message 16 of 19
Luis Esquivel
in reply to: Rurik

I have seen and read many posts here and in other forums about the issue of not having to depend in the use of a built in command like bpoly.

But also have seen, that end up being the preference after all.

1. If it were available a function similar to bpoly, do you would used?

2. Do you prefer to have it for free? and if it was like that, how about the problems of not having it updated when a new release of AutoCAD came up?

3. If it where not for free, how much you would be willing to pay?

4. Or it does not matter, I will continue the way I been doing it for to long?

Your comments are welcome.

Regards,
Luis.
Message 17 of 19
Anonymous
in reply to: Rurik

Hi
Pardon me, if I don't understand you correct...
If it will be interesting to you, I anywhere do not work and not
I shall work, and I am engaged in programming exclusively
for my own pleasure
IOW, I am free bird
Of course, it is interesting to me to know that that I while
I do not know, but to pay for such knowledge I is not measured at all
Sooner or later I can find the answer to this
question without any advance payment for services

Regards,

~'J'~
Message 18 of 19
Luis Esquivel
in reply to: Rurik

Я понимаю, не пробуя продать кое-что здесь. В то время как я желаю иметь идею. Спасибо and cheers!
Message 19 of 19
Anonymous
in reply to: Rurik

Dear Luis
A causa de mí muy desagradable, porque mi nivel débil de los conocimientos
No permite mientras que hacer tales proyectos complicados.

Gracias,

Atentamente

~'J'~

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost