No Selecting of Elements via created FenceElement in MSTN-Connect Update 14

i'am trying to convert my Programms from MSTN 8i to MSTN Connect. Below is my Code for just Marking of Elements with overlapped FenceShapeElement .

The FenceShapeElement looks like a Line.

It worked really good in MSTN 8i and we need it in MSTN-Connect. My Accudraw is Enabled. I have no locks. View Depth is frm -1000 to 1000. 
My Elements have a Z-Koordinate=0. My Problem is, that no Elements will be found and marked. 

Later i will getting a IntersectionsPoints for a Creating a Textelements above this Points. 

I will be grateful for your the help. Thanks.

Hier is DGN with Elements
Neu6.dgn

Hier is a MVBA-File

ElementBeschrifTest.mvba

Public Function BeschriftungStarten()
On Error GoTo err
If Matrix3dIsXYRotation(CommandState.LastView.Rotation, dblRadians) Then
    FormatBeschriftungVariablen
    CommandState.StartDefaultCommand
    With ActiveSettings             'Zaunmodus auf Block Überlappung setzen
        .FenceClip = False
        .FenceOverlap = True
        .FenceVoid = False
    End With
    CommandState.StartPrimitive New clsFlaecheZaun
Else
    MsgBox MsgAnsVerdreht, vbInformation, "Programmabbruch - BoeKonstruieren"
End If

Exit Function
err:
    Select Case err
    Case Else
        MsgBox "Error in [mod1Haupt]\\BeschriftungStarten\\ " & _
        vbCrLf & err.Description, vbCritical, err.Number
'        Resume
    End Select
End Function


'HIER is the Code for "clsFlaecheZaun"

Option Explicit
Implements IPrimitiveCommandEvents
Dim Origin As Point3d, Shp(3) As Point3d
Dim Rot As Matrix3d, Plane As Plane3d, Sh As ShapeElement
Dim nPnts As Long, ElNum As ElementEnumerator

Private Sub IPrimitiveCommandEvents_Cleanup()
    'not used
End Sub

Private Sub IPrimitiveCommandEvents_DataPoint(Point As Point3d, ByVal View As View)
     If nPnts = 0 Then
         Origin = Point
         nPnts = 1
         Plane.Origin = Point
         ShowPrompt " 2-Punkt setzen"
         CommandState.StartDynamics
     ElseIf nPnts = 1 Then
        CommandState.StopDynamics
'        Set ElNum = Nothing
        Set ElNum = getElementsFromFenceOrSelectionSet()
        blnItemsHaveBeenSelected = SelectFromEnumerator(ElNum)
'        CommandState.StartLocate New clsBeschrSchnPkte
     End If
End Sub

Private Sub IPrimitiveCommandEvents_Dynamics(Point As Point3d, ByVal View As View, ByVal DrawMode As MsdDrawingMode)
    If DrawMode = msdDrawingModeTemporary Then
        If CommandState.AccuDrawHints.IsEnabled Then
            Rot = Matrix3dInverse(CommandState.AccuDrawHints.GetRotation(View))
        Else
            Rot = Matrix3dInverse(View.Rotation)
        End If
        Plane.Normal = Point3dFromMatrix3dColumn(Rot, 2)
        Point = Point3dProjectToPlane3d(Point, Plane)
        Shp(0) = Origin
        Shp(1) = Point3dInterpolate(Shp(0), 1, Point)
        Shp(2) = Point
        Shp(3) = Point3dInterpolate(Shp(0), 1, Shp(2))
        If (1 = nPnts) Then
           Set oFenceLine = CreateLineElement2(Nothing, Origin, Point)
        End If
        Set Sh = CreateShapeElement1(Nothing, Shp)
        Set oFence = ActiveDesignFile.Fence
        oFence.DefineFromElement View, Sh
    End If
    Sh.Color = 70: Sh.LineWeight = 1
    Sh.Redraw DrawMode
    oFence.Draw
End Sub

Private Sub IPrimitiveCommandEvents_Keyin(ByVal Keyin As String)
    'not used
End Sub

Private Sub IPrimitiveCommandEvents_Reset()
     CommandState.StopDynamics
     If Not oFence Is Nothing Then oFence.Undefine
     CommandState.StartDefaultCommand
End Sub

Private Sub IPrimitiveCommandEvents_Start()
     Set oFence = Nothing: Set oFenceLine = Nothing: Set Sh = Nothing: Erase Shp
     ShowCommand "Strich zur Elementauswahl "
     ShowPrompt " 1-Punkt setzen"
     CommandState.EnableAccuSnap
End Sub


Public Function getElementsFromFenceOrSelectionSet() As ElementEnumerator
'Returns the ElementEnumerator of the selected elements
'from either a fence or a selection set
Dim tmpFence As Fence
Dim oElEnum As ElementEnumerator
Dim element As element

Set tmpFence = ActiveDesignFile.Fence
If tmpFence.IsDefined = True Then
   Set oElEnum = tmpFence.GetContents(False, True)
Else
   Set oElEnum = ActiveModelReference.GetSelectedElements
End If
Set getElementsFromFenceOrSelectionSet = oElEnum
End Function


Public Function SelectFromEnumerator(oElEnum As ElementEnumerator) As Boolean
'Selected the element(s) in the ElementEnumerator variable
'Returns True if items selected False if items not selected
Dim oElement As element         'element currently being processed
    
SelectFromEnumerator = False
If ActiveModelReference.AnyElementsSelected Then
    Set oElEnum = ActiveModelReference.GetSelectedElements
End If
    
    oElEnum.Reset
    Do While oElEnum.MoveNext
        Set oElement = oElEnum.Current
        ActiveModelReference.SelectElement oElement, True
        SelectFromEnumerator = True
    Loop
End Function

Parents
  • Hi Mikha,

    with overlapped LineFence

    What is LineFence? Fence in MicroStation is always shape.

    It worked really good in MSTN 8i and we need it in MSTN-Connect.

    And? What is the problem? Do you really expect somebody in his free time will create test case, create MVBA macro, post the text and after these steps will start to investigate what can a reason of you question?

    I will be grateful for your the help.

    Please specify exactly what your problem is and what is expected.

    Also, share test DGN, because when any problem in code is discussed, test data has to be shared also.

    Regards,

      Jan

  • Hi Jan, i just added more Informations about my Problem. Thanks.

  • Hi Mikha,

    i just added more Informations

    thanks for details. I am too busy to do any real analysis, but a few notes...

    Hier is a MVBA-File

    With all respect, the code is weird (can happen, because every developer prefers own style), but in some cases clearly wrong in my opinion (e.g. to create fence in dynamic makes no sense).

    The FenceShapeElement looks like a Line.

    It seems to be the reason. In fact I am surprised it works in V8i, because the concept is incorrect. To create and use intentionally shape with 0 square units area, because it's created as a line, is about to use topologically not valid element (even when MicroStation allows to create such element, because it's fine geometrically).

    What you should try (but you probably did not do) is:

    • To modify the code to add the shape to design file.
    • To create fence from element manually. It works fine, because technically fence is shape.
    • To use e.g. Copy element tool with Fence. The result is clear: No elements are found, so MicroStation CE does not work with such "line fence". Whether it's bug or a consequence of topology implementation in MicroStation engine should be discussed with Bentley support.
    I will be grateful for your the help.

    I recommend to rewrite the code, because it's pretty dirty, to do not use fence. There is no reason for it. If the task is to find all elements, that are crossed by a line, why to do not simply check intersections, which I assume will be simpler and clearer code than to create fence as a step in a middle?

    With regards,

      Jan

  • Hi Jan, thanks for your recommendations. You have not enough Time for your analysis, but you see my code dirty, without anything to say, what is hier dirty. The Example of MSTN - Dokumentation "CopyFenceContents" crushes also by reading off Elements. So i think we have some Problems with our Configuration. I will think about your offer. Have a nice day.

  • but you see my code dirty, without anything to say, what is hier dirty

    It seems you did not bother to read my answer. I clearly mentioned what I think is the biggest fail: To create fence in dynamics. It clearly breaks main rule of dynamic: Do only minimum mandatory things, not more. And fence is not necessary at all in dynamics.

    There are a more issues in the code like overusing of global variables, using not used variables (oFenceLine), some variables assignment seem to be useless.

    But mostly it's a personal feeling: When I see a code for the first time, do I understand code structure and author's intention or not? I like what is written in Clean code book (which is a kind of bible of how to write right code, a good summary e.g. here): Code should be like a story. But to explain all "why I think it's not good" is out of available time capacity.

    So i think we have some Problems with our Configuration.

    MicroStation seems to work with fence in a different way than V8i, so the code has to be changed accordingly.

    My feeling is that CE is less tolerant and to create more correct (by its structure and also topologically) data is now preferred both by user tools and APIs.

    Regards,

      Jan

  • In my macros there is a certain sequence of actions that the user can cancel if he wants, otherwise what's the point of creating classes with dynamics? You suggest that I already create a shape in some way, without the possibility of deleting it by right clicking. I have not shown you the whole program, so you cannot judge whether there are extra variables. Yes, I have disadvantages, but I am a self-taught person who is trying to develop myself, concentrating on achieving the desired result. Thanks for your time Jan. Regards Mikha.

  • What's the point of creating classes with dynamics?

    To show the user the progress of their actions.

    As Jan wrote, it's unusual to create a fence in dynamics.  It's more usual to show a ShapeElement in dynamics, and convert that to a fence in your _Datapoint method.

    There is a certain sequence of actions that the user can cancel if he wants

    IPrimitiveCommandEvents (and therefore your class that implements that interface) is a state machine.  You can link a series of state machines together to make a bigger state machine.  It's that design that lets a user back out of (undo) a particular state.  That has nothing to do with MicroStation dynamics.

    I have not shown you the whole program, so you cannot judge

    Exactly!  But if you want us to help and to judge, then it would be helpful to publish your code.  Otherwise, any comment we make is guesswork.

     
    Regards, Jon Summers
    LA Solutions

  • Hi all,

    I have tested this VBA routine and compared the behavior of the fence commands between V8i and CONNECT Edition. 
    The issues experienced here is caused by an empty area of the shape. The fence manipulation commands in V8i accepted an empty area shape to select elements. In CONNECT Edition this is no longer possible.
    This means the behavior of the VBA routine works as designed related to the underlying MicroStation functionality.

    As workaround it would be possible to use slightly modified coordinates to allow a small tolerance to get non empty shapes and the desired elements selected like in V8i.
    I have tested to add this line just before creating the shape Sh in Sub IPrimitiveCommandEvents_Dynamics and it worked for me:

    Shp(1).Y = Shp(1).Y + 0.1

    I hope this helps?

    Best regards,
    Artur

  • In CONNECT Edition this is no longer possible.

    The element selection tool still does crossing line selection by creating a fence from 3 points (degenerate triangle) and using overlap mode...I'm surprised VBA would work differently...



  • Thank you very much Artur. I have a trouble with configuration of MSTN connect. I cannot understand why this possibility is no longer possible. Nobody wanted to create this shapes, but it was really good for selecting off overlapping Elements. With Regards. Mikha.

  • Hi all,

    i have modified my code for creating of shape for the Fence. It works fine.

    Private Sub IPrimitiveCommandEvents_Dynamics(Point As Point3d, ByVal View As View, ByVal DrawMode As MsdDrawingMode)
        Dim tmpDynLine As LineElement, Yv As Point3d
        If DrawMode = msdDrawingModeTemporary Then
            If CommandState.AccuDrawHints.IsEnabled Then
                Rot = Matrix3dInverse(CommandState.AccuDrawHints.GetRotation(View))
            Else
                Rot = Matrix3dInverse(View.Rotation)
            End If
            Plane.Normal = Point3dFromMatrix3dColumn(Rot, 2)
             Yv = Point3dFromMatrix3dColumn(Rot, 1)
             Point = Point3dProjectToPlane3d(Point, Plane)
             Shp(0) = Origin
             Shp(1) = Point3dInterpolate(Shp(0), 1, Point)
             Set tmpDynLine = CreateLineElement2(Nothing, Shp(0), Shp(1))
             Shp(2) = Point3dAddAngleDistance(Shp(1), LineAngle(tmpDynLine, Shp(1)) - Pi / 2, 0.01, 0)
             Shp(3) = Point3dInterpolate(Shp(0), 0.99, Point)
            If (1 = nPnts) Then
               Set oFenceLine = CreateLineElement2(Nothing, Origin, Point)
            End If
            Set Sh = CreateShapeElement1(Nothing, Shp)
        End If
        Sh.Color = 70: Sh.LineWeight = 1
        Sh.Redraw DrawMode
    End Sub

Reply
  • Hi all,

    i have modified my code for creating of shape for the Fence. It works fine.

    Private Sub IPrimitiveCommandEvents_Dynamics(Point As Point3d, ByVal View As View, ByVal DrawMode As MsdDrawingMode)
        Dim tmpDynLine As LineElement, Yv As Point3d
        If DrawMode = msdDrawingModeTemporary Then
            If CommandState.AccuDrawHints.IsEnabled Then
                Rot = Matrix3dInverse(CommandState.AccuDrawHints.GetRotation(View))
            Else
                Rot = Matrix3dInverse(View.Rotation)
            End If
            Plane.Normal = Point3dFromMatrix3dColumn(Rot, 2)
             Yv = Point3dFromMatrix3dColumn(Rot, 1)
             Point = Point3dProjectToPlane3d(Point, Plane)
             Shp(0) = Origin
             Shp(1) = Point3dInterpolate(Shp(0), 1, Point)
             Set tmpDynLine = CreateLineElement2(Nothing, Shp(0), Shp(1))
             Shp(2) = Point3dAddAngleDistance(Shp(1), LineAngle(tmpDynLine, Shp(1)) - Pi / 2, 0.01, 0)
             Shp(3) = Point3dInterpolate(Shp(0), 0.99, Point)
            If (1 = nPnts) Then
               Set oFenceLine = CreateLineElement2(Nothing, Origin, Point)
            End If
            Set Sh = CreateShapeElement1(Nothing, Shp)
        End If
        Sh.Color = 70: Sh.LineWeight = 1
        Sh.Redraw DrawMode
    End Sub

Children
No Data