Author Topic: Point Selection  (Read 6390 times)

0 Members and 1 Guest are viewing this topic.

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: Point Selection
« Reply #15 on: June 20, 2011, 03:37:54 PM »
I have used several methods in the past. The most successful for on screen selection was pretty complex. What I did was:

1) Store the user selected point
2) Generate another point at X distance and 0 degrees from user selected point
3) Repeat #2 substituting an incrementing value for 0 (i.e. 1, 2, 3, etc)
4) Use a selection set with a fence.
5) If the selection set contained no entities, I incremented the value of X and looped back to #2

This approach isn't really useful though and is certainly not the easiest or best approach. One might consider simply obtaining all the points for every entity in the block and calculate which one is closest.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

cadpro

  • Guest
Re: Point Selection
« Reply #16 on: June 20, 2011, 04:22:18 PM »

One might consider simply obtaining all the points for every entity in the block and calculate which one is closest.

But getting to capture the block is where I'm stuck up with. If I get the block within which the point selection is, then I can loop through the block, get all polylines, get the polylines GeometricExtents, compare with the point X and Y values, find the nearest one, then loop through all the attributes inside the polyline and that's done. But don't know how to capture the nearest entity of the point.

Thanks

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Point Selection
« Reply #17 on: June 20, 2011, 09:27:35 PM »
Begin doubleclick gives you a point. If you check for no entity returned you can make a selection set  using 2 corners created by offsetting the picked point the min required distance to trap the blocks, also filter for the blocks you want.

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: Point Selection
« Reply #18 on: June 21, 2011, 12:57:16 AM »

One might consider simply obtaining all the points for every entity in the block and calculate which one is closest.

But getting to capture the block is where I'm stuck up with. If I get the block within which the point selection is, then I can loop through the block, get all polylines, get the polylines GeometricExtents, compare with the point X and Y values, find the nearest one, then loop through all the attributes inside the polyline and that's done. But don't know how to capture the nearest entity of the point.

Thanks

There are two options that come to mind:

1) Use an on-screen selection method using the user selected point as a base and some arbitrary second point calculated as an offset from the selected point. Then use the crossing or fence selection to find the items

2) Select ALL blocks references that are in the drawing filtered by name, build a list of all the insertion points of all block references then compare the insertion point to the selected point using a distance method. This will tell you which block reference is closest to the selection point.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

cadpro

  • Guest
Re: Point Selection
« Reply #19 on: June 21, 2011, 02:16:23 PM »
I'm almost close to what Bryco and Keith suggested. I did get the offset of the picked point, did a SelectionCrossingWindow, found the blocks in it, looped through the blocks to get the polylines inside the block. So far it's fine. Now I have to find out which polyline is close to the point picked. Coded to get the vertex of all the polylines if the NumberOfVertices = 4. Will a GetDistAtPoint work for this? Or is there any solution?

Thanks

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Point Selection
« Reply #20 on: June 21, 2011, 06:11:04 PM »
Just to make sure; you are using the blocktransform matrix to transform the picked pt to the block layout, and then using the distance from each att to find which att you want?

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: Point Selection
« Reply #21 on: June 21, 2011, 09:20:06 PM »
Just to make sure; you are using the blocktransform matrix to transform the picked pt to the block layout, and then using the distance from each att to find which att you want?

+1
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Point Selection
« Reply #22 on: June 23, 2011, 11:32:11 PM »
Here is a start maybe???

but use a blk1 from test.dwg that you loaded since blk has nested blockreference

This is just an idea or example things are hard-coded and probably will not do you much good just copying and pasting.


This prompts you for point and will turn the rectangle red of which ever rectangle you select a point inside.

Code: [Select]
        <CommandMethod("GetNestedRec")> _
        Public Sub GetNestedRec()
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor

            Using trx As Transaction = db.TransactionManager.StartTransaction()
                Try

                    Dim bt As BlockTable = trx.GetObject(db.BlockTableId, OpenMode.ForRead)


                    Dim getPnt As Point3d = ed.GetPoint("Pick Point").Value

                    Dim psr As PromptSelectionResult = ed.SelectCrossingWindow(getPnt, New Point3d(getPnt.X + 3, getPnt.Y, 0))

                    If psr.Value.Count = 0 Then
                        Exit Sub
                    End If

                    For Each objId As ObjectId In psr.Value.GetObjectIds

                        If Not objId.ObjectClass.Name = "AcDbBlockReference" Then
                            Continue For
                        End If

                        Dim bref As BlockReference = trx.GetObject(objId, OpenMode.ForRead)
                        Dim blk As BlockTableRecord = trx.GetObject(bref.BlockTableRecord, OpenMode.ForRead)

                        For Each entId As ObjectId In blk

                            If Not entId.ObjectClass.Name = "AcDbPolyline" Then
                                Continue For
                            End If

                            Dim poly As Polyline = trx.GetObject(entId, OpenMode.ForRead)

                            Dim tempExtents As Extents3d
                            Dim polyExtents As Extents3d = poly.GeometricExtents
                            polyExtents.TransformBy(bref.BlockTransform)

                            tempExtents = polyExtents
                            tempExtents.AddPoint(getPnt)

                            If polyExtents.IsEqualTo(tempExtents) Then
                                poly.UpgradeOpen()
                                poly.Color = Color.FromColorIndex(ColorMethod.ByAci, 1)
                            End If
                        Next

                    Next

                Catch ex As System.Exception
                    MsgBox("Error")
                End Try
                trx.Commit()
            End Using
            ed.Regen()
        End Sub







Jeff H

  • Needs a day job
  • Posts: 6150
Re: Point Selection
« Reply #23 on: June 24, 2011, 10:45:21 AM »
Another thing for incrementing the value for crossing window like Keith mentioned you could

replace

Code: [Select]
                    Dim psr As PromptSelectionResult = ed.SelectCrossingWindow(getPnt, New Point3d(getPnt.X + 3, getPnt.Y, 0))

                    If psr.Value.Count = 0 Then
                        Exit Sub
                    End If


with

Code: [Select]

                    Dim increment As Vector3d = New Vector3d(0.5, 0, 0)
                    Dim otherPnt As Point3d = getPnt.Add(increment)
                    Dim counter As Integer = 0

                    Dim psr As PromptSelectionResult = ed.SelectCrossingWindow(getPnt, otherPnt)

                    While psr.Status <> PromptStatus.OK OrElse psr.Value.Count < 1
                        If HostApplicationServices.Current.UserBreak OrElse counter = 100 Then
                            Exit Sub
                        End If

                        otherPnt = otherPnt.Add(increment)
                        psr = ed.SelectCrossingWindow(getPnt, otherPnt)
                        counter += 1
                    End While

The counter is for ending while loop in case user selects a point that will not end up selecting any objects
The UserBreak is for ending loop so you will not get stuck in loop if they press escape
It just uses a Vector3d as a incrementing value and keeps adding to the point to increment the window 0.5 units.


Code: [Select]
                            Dim poly As Polyline = trx.GetObject(entId, OpenMode.ForRead)

                            Dim tempExtents As Extents3d
                            Dim polyExtents As Extents3d = poly.GeometricExtents
                            polyExtents.TransformBy(bref.BlockTransform)

                            tempExtents = polyExtents
                            tempExtents.AddPoint(getPnt)

                            If polyExtents.IsEqualTo(tempExtents) Then
                                poly.UpgradeOpen()
                                poly.Color = Color.FromColorIndex(ColorMethod.ByAci, 1)
                            End If


In case you have not figured it out
Once the crossing window selects a object it checks if it is a Blockreference and if it is it gets the BlockTableRecord and loops through it and checks for polylines
then get the polylines Extents.

Then it takes those extents and uses the Extents3d.TransformBy(BlockReference.BlockTransform) to transform it to the BlockReference insertion.

Then assigns a temp extents to same value as transformed extents and adds a point to to temp extents with Extents3d.AddPoint(SelectedPoint)

if that point is inside the extents then polyExtents.IsEqualTo(tempExtents) will be true.

Again there is probably a better way of figuring out if it falls inside a rectangle



cadpro

  • Guest
Re: Point Selection
« Reply #24 on: June 27, 2011, 05:08:26 PM »
The IsPointInside() is what I was exactly looking for!That works fine, but sadly only when the block's rotation angle is 180 degree. If I manually change the rotation angle to 180, it works fine. What could be the reason.

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Point Selection
« Reply #25 on: June 29, 2011, 02:15:08 AM »
why bother with the rectangle, aren't you looking for the att?

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2139
  • class keyThumper<T>:ILazy<T>
Re: Point Selection
« Reply #26 on: June 29, 2011, 04:46:01 AM »

Just an aside :

Why is the block insert so far away from the main block body ?

Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

cadpro

  • Guest
Re: Point Selection
« Reply #27 on: June 30, 2011, 07:03:15 AM »
Thanks all. That is solved.

Thanks

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2139
  • class keyThumper<T>:ILazy<T>
Re: Point Selection
« Reply #28 on: July 02, 2011, 04:48:34 AM »
Thanks all. That is solved.

Thanks

cadpro,
I'm sure a few people (here and elsewhere) would be interested is seeing the code solution that resolved this problem.
Would you post it.
Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Point Selection
« Reply #29 on: July 02, 2011, 09:12:00 AM »
why bother with the rectangle, aren't you looking for the att?
Look at earlier replies it is brought up and suggested to go just grab attributes, but OP needed that approach for his situation.

Ahhhh!
I just went back and looked and I missed that OP was taking this approach because the attribute might be empty.
If I am correct in OP's intent then all that could of been advoided.