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

How to locate text near blockreference

8 REPLIES 8
Reply
Message 1 of 9
darrell.caldwell
933 Views, 8 Replies

How to locate text near blockreference

I have tried to use intersectwith to locate text (MText or DBText) near a block reference. Some times it works and some times it does not. The hard part for me is understanding why it occasionally works when most examples are just duplicates with modified text and attributes.

 

My block reference has 4 attributes  to the left (Right Justified) of a circle and 2 attributes inside the circle. The text objects are used by some CAD operators instead of the upper 2 lines of attributtes. (Guess they dont know how to modify attributes) I want to locate these texts and insert text into the corresponding attribute.

 

Block Reference:

 

Att 1   |'''''''|  <-- CAD User will insert a txt over Att 1 and Att 2, 

Att 2  |       | <--  both attributes are usally left blank or contain a space

Att 3  |       |

Att 4   |.....|

8 REPLIES 8
Message 2 of 9

Hi,

 

>> intersectwith to locate text (MText or DBText) near a block reference

Can you show the code that does what you described with this sentence? Because IntersectWith needs exact geometry and not "near to" any geom.

If you are working with geometric extents from your attribute-values then be careful, sometimes the extents of AttributeReferences are calculated wrong (the min- or max-point of the extents points to 0,0,0). If you use COM-GetBoundingBox it works.

Also if the AttributeReferences have no text in .TextString you may (you will) have difficulties with IntersectWith.


Show the code that does not do what you want to have and also upload a drawing for that situation. That will help us (and you) to come faster to a solution (hopefully 😉 )

 

- alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at ... blog.hollaus.at ... CDay 2024
------------------------------------------------------------------------------------
(not an Autodesk consultant)
Message 3 of 9

alfred,

 

Thanks for the quick response. I left my laptop at work and all the code is there and I will not be back till Teusday. If I remember correctly my statement looks something like this,

 

******************************************************

.... some code ....

myAttributeReference.TextString = "XXXXXXXX"

.... some code ....

Dim colInters As New Point3dCollection


myAttributeReference.IntersectWith(myMText, Intersect.OnBothOperands, colIntrs, 0, 0)

.... some code ....

******************************************************

Out of curiosity, which way would you attempt to locate MText or DBText arranged as stated.

 

Message 4 of 9

Hi,

 

>> Out of curiosity, which way would you attempt to locate MText or DBText arranged as stated

I did not yet check intersections of text-like objects. What I would do (just one idea) is to create a line in the mid of the text-height (and the angle of the text and check then if the lines intersect.

 

- alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at ... blog.hollaus.at ... CDay 2024
------------------------------------------------------------------------------------
(not an Autodesk consultant)
Message 5 of 9

OK,

here is the code and I have attached a drawing with examples.

I rewrote the code to draw a polyline around the geometricextents of the BlockReference. Then itereate all TEXT or MTEXT object in model space and check for intersects.

 

I have the origianl blockreference that I am working with, run "DPL" to text the code. it should draw a polyline within the extents of the blockreference. Then attempt to check intersects with the MTEXT object right next to it. It want find any, although it should.

 

Example two, is the smaller polyline with MTEXT object on top of it. Type "inters" and you will see that intersections exist. These objects where drawn manually using normal polyline and mtext commands.

 

Example three is the larger polyline with the MTEXT object on top. Type "inters" and you will see that no intersections exist. The polyline was drawn by code from the "DPL" command. So, my code drawn polyline does not intersect with the MTEXT variable.

 

Why not. ????

 

Option Explicit On
Option Strict On

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

Imports System.IO
Imports Microsoft.Win32
Imports System.Reflection

Public Class Class1

<CommandMethod("inters", CommandFlags.UsePickSet)> _
Public Sub GetInters()
Dim doc As Document = Application.DocumentManager.MdiActiveDocument
Dim db As Database = doc.Database

Dim ed As Editor = doc.Editor
Dim tr As Transaction = db.TransactionManager.StartTransaction
Try
Using tr
Dim acBT As BlockTable = CType(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
Dim acMS As BlockTableRecord = CType(tr.GetObject(acBT(BlockTableRecord.ModelSpace), OpenMode.ForRead), BlockTableRecord)
Dim opt As New PromptEntityOptions(vbLf & "Select entity: ")
opt.SetRejectMessage(vbLf & "Error selecting entity")
opt.AllowNone = False
'opt.AddAllowedClass(GetType(BlockReference), True)
Dim res As PromptEntityResult = ed.GetEntity(opt)
If res.Status <> PromptStatus.OK Then Return
Dim lid As ObjectId = res.ObjectId
opt = New PromptEntityOptions(vbLf & "Select entity: ")
opt.SetRejectMessage(vbLf & "Error selecting entity")
'opt.AddAllowedClass(GetType(MText), True)
'opt.AddAllowedClass(GetType(DBText), True)
res = ed.GetEntity(opt)
If res.Status <> PromptStatus.OK Then Return
Dim pid As ObjectId = res.ObjectId
Dim pts As Point3dCollection = New Point3dCollection()
ed.WriteMessage(vbLf & "{0} <> {1};", lid, pid)
Dim ent1 As Entity = CType(tr.GetObject(lid, OpenMode.ForRead), Entity)
Dim ent2 As Entity = TryCast(tr.GetObject(pid, OpenMode.ForRead), Entity)

'Dim plane As Plane = New Plane(ed.CurrentUserCoordinateSystem.CoordinateSystem3d.Origin, ed.CurrentUserCoordinateSystem.CoordinateSystem3d.Zaxis)
'ent1.IntersectWith(ent2, Intersect.OnBothOperands, Plane, pts, 0, 0)
ent1.IntersectWith(ent2, Intersect.OnBothOperands, pts, 0, 0)
ed.WriteMessage(vbLf & "Number of intersections: {0}", pts.Count)

Dim i As Integer = 1
For Each pt As Point3d In pts
ed.WriteMessage(vbLf & "Point number {0}: ({1}, {2}, {3})", i, pt.X, pt.Y, pt.Z)
i += 1
Next
tr.Commit()
End Using
Catch ex As Autodesk.AutoCAD.Runtime.Exception
ed.WriteMessage(vbLf & "{0}", ex.Message)
End Try
End Sub

''' <summary>
''' Draws a box around the extents of selected object
''' </summary>
''' <remarks></remarks>
<CommandMethod("DPL", CommandFlags.UsePickSet)> _
Public Sub DrawPolyLine()
Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
Dim acDB As Database = acDoc.Database

Dim acDocEd As Editor = acDoc.Editor
Dim tr As Transaction = acDB.TransactionManager.StartTransaction
Try
Using tr
Dim acBT As BlockTable = CType(tr.GetObject(acDB.BlockTableId, OpenMode.ForRead), BlockTable)
Dim acMS As BlockTableRecord = CType(tr.GetObject(acBT(BlockTableRecord.ModelSpace), OpenMode.ForRead), BlockTableRecord)
Dim opt As New PromptEntityOptions(vbLf & "Select block: ")
opt.SetRejectMessage(vbLf & "Only Block Reference allowed...")
opt.AllowNone = False
opt.AddAllowedClass(GetType(BlockReference), True)

Dim res As PromptEntityResult = acDocEd.GetEntity(opt)
If res.Status <> PromptStatus.OK Then Return

Dim blkID As ObjectId = res.ObjectId
Dim acAttID As ObjectId
Dim acBlkRef As BlockReference = CType(tr.GetObject(blkID, OpenMode.ForRead), BlockReference)
Dim acAttRef As New AttributeReference
Dim strAttTemp As String = ""
Dim attIDs As AttributeCollection = acBlkRef.AttributeCollection
For Each attID As ObjectId In attIDs
acAttRef = CType(tr.GetObject(attID, OpenMode.ForRead), AttributeReference)
If acAttRef.Tag = "1" Then
acAttID = attID
strAttTemp = acAttRef.TextString
acAttRef.UpgradeOpen()
acAttRef.TextString = "XXXXXXXXXX"
acAttRef.DowngradeOpen()
End If
Next

Dim ext3D As Extents3d = acBlkRef.GeometricExtents
Dim dWidth As Double = (ext3D.MaxPoint.Y - ext3D.MinPoint.Y)
Dim plStartPnt As Point2d = New Point2d(ext3D.MinPoint.X, ext3D.MinPoint.Y + dWidth / 2)
Dim plEndPnt As Point2d = New Point2d(ext3D.MaxPoint.X, ext3D.MinPoint.Y + dWidth / 2)
Dim pl As Polyline = New Polyline
pl.AddVertexAt(0, plStartPnt, 0, dWidth, dWidth)
pl.AddVertexAt(0, plEndPnt, 0, dWidth, dWidth)

'If acAttRef IsNot Nothing Then
acAttRef.UpgradeOpen()
acAttRef.TextString = strAttTemp
acAttRef.DowngradeOpen()
'End If

acMS.UpgradeOpen()
acMS.AppendEntity(pl)
tr.AddNewlyCreatedDBObject(pl, True)
acMS.DowngradeOpen()
acDocEd.Regen()

'' Create a TypedValue array to define the filter criteria of Text or MText
Dim acTypValAr(3) As TypedValue
acTypValAr.SetValue(New TypedValue(DxfCode.Operator, "<or"), 0)
acTypValAr.SetValue(New TypedValue(DxfCode.Start, "TEXT"), 1)
acTypValAr.SetValue(New TypedValue(DxfCode.Start, "MTEXT"), 2)
acTypValAr.SetValue(New TypedValue(DxfCode.Operator, "or>"), 3)
'' Assign the filter criteria to a SelectionFilter object
Dim acSelFtr As SelectionFilter = New SelectionFilter(acTypValAr)
'' Request for objects to be selected in the drawing area
Dim acSSPrompt As PromptSelectionResult
acSSPrompt = acDocEd.SelectAll(acSelFtr)
'' If the prompt status is OK, objects were selected
If acSSPrompt.Status = PromptStatus.OK Then
Dim acSSet As SelectionSet = acSSPrompt.Value
Dim acObjIDs As ObjectId() = acSSet.GetObjectIds
For Each acObjID As ObjectId In acObjIDs
If acObjID.ObjectClass.Name = "AcDbText" Then
Dim acText As DBText = CType(tr.GetObject(acObjID, OpenMode.ForRead), DBText)
Dim colPnts As New Point3dCollection
pl.IntersectWith(CType(acText, Entity), Intersect.OnBothOperands, colPnts, 0, 0)
If colPnts.Count > 0 Then
acDocEd.WriteMessage(acText.TextString)
End If
Else
Dim acMText As MText = CType(tr.GetObject(acObjID, OpenMode.ForRead), MText)
Dim colPnts As New Point3dCollection
pl.IntersectWith(CType(acMText, Entity), Intersect.OnBothOperands, colPnts, 0, 0)
If colPnts.Count > 0 Then
acDocEd.WriteMessage(acMText.Text)
End If
End If
Next

End If

tr.Commit()
End Using
Catch ex As Autodesk.AutoCAD.Runtime.Exception
acDocEd.WriteMessage(vbLf & "{0}", ex.Message)
End Try
End Sub

End Class

Message 6 of 9

Hi,

 

Example 1:

>> Then attempt to check intersects with the MTEXT object right next to it. It want find any, although it should.

If I run your DPL-Code (with AutoCAD 2010 currently) I get a polyline as one result and I get the AttributeReference "1" filled with "XXXXXXXXXX"

So isn't that working as it should be?

 

Example 2:

I see 4 intersections and also 4 points if intersections listed

 

Example 3:

I see also 4 intersections and also 4 points listed

 

 

I think the next question is: what AutoCAD release (and may be what vertical product) are you using that does not return the same results at your system?

 

And just one shortening to your code 😉

 

Dim acTypValAr() As TypedValue = {New TypedValue(DxfCode.Start, "TEXT,MTEXT")}

 to be used for filtering a selectionset to TEXT or MTEXT objects.

 

- alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at ... blog.hollaus.at ... CDay 2024
------------------------------------------------------------------------------------
(not an Autodesk consultant)
Message 7 of 9

Thanks Alfred,

 

Question, will this work using your shortening example

 

Dim acTypValAr() As TypedValue = {New TypedValue(DxfCode.Start, "TEXT,MTEXT"), New TypedValue(DxfCode.LayerName, "GEN_TEXT_RU,CPC_TEXT")}

 

to replace the following

 

Dim acTypValAr(9) As TypedValue
acTypValAr.SetValue(New TypedValue(DxfCode.Operator, "<and"), 0)
acTypValAr.SetValue(New TypedValue(DxfCode.Operator, "<or"), 1)
acTypValAr.SetValue(New TypedValue(DxfCode.Start, "TEXT"), 2)
acTypValAr.SetValue(New TypedValue(DxfCode.Start, "MTEXT"), 3)
acTypValAr.SetValue(New TypedValue(DxfCode.Operator, "or>"), 4)
acTypValAr.SetValue(New TypedValue(DxfCode.Operator, "<or"), 5)
acTypValAr.SetValue(New TypedValue(DxfCode.LayerName, "GEN_TEXT_RU"), 6)
acTypValAr.SetValue(New TypedValue(DxfCode.LayerName, "CPC_TEXT"), 7)
acTypValAr.SetValue(New TypedValue(DxfCode.Operator, "or>"), 😎
acTypValAr.SetValue(New TypedValue(DxfCode.Operator, "and>"), 9)

Message 8 of 9

Hi,

 

>> will this work using your shortening example

Yes, but I think you would have tried/verified it faster than asked here 😉

 

- alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at ... blog.hollaus.at ... CDay 2024
------------------------------------------------------------------------------------
(not an Autodesk consultant)
Message 9 of 9

Back on track,

I am using AutoCAD Mechanical 2010

 

Command "DPL" does the following,

gets blockreference from user,

changes attRef1 text to "XXXXXXXXXX" ( this will assist in extending the geometricextents)

draws a polyline inside the geometric extents of the blockreference

iterate thru all MTEXT or TEXT objects looking for intersections if any are found, write its text to the editor

 

When I run it, the text is changed, polyline is drawn but no intersections are found.

 

On example 3, I determined that if I move the MTEXT down slightly, then it will return an intersection, but left at its current position it does not work (on my system). I am stumbed as to why it works on yours.

 

My assumption is that the polyline only compares intersection with the centerline if its width, not with the boundry of the object. In regards to this, I have rewritten my code to draw polyline with no width that zig-zags across the geometricextents of the block and then checks for intersections. So far this seems to be working.

 

I will post the code shortly.

 

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