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 ElementsNeu6.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
Hi Mikha,
Mikha Zaslavskiy said:with overlapped LineFence
What is LineFence? Fence in MicroStation is always shape.
Mikha Zaslavskiy said: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?
Mikha Zaslavskiy said: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
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
Hi Jan, i just added more Informations about my Problem. Thanks.
Mikha Zaslavskiy said:i just added more Informations
thanks for details. I am too busy to do any real analysis, but a few notes...
Mikha Zaslavskiy said: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).
Mikha Zaslavskiy said: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:
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,
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.
Mikha Zaslavskiy said: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.
Mikha Zaslavskiy said: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.
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.
Mikha Zaslavskiy said: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.
ShapeElement
_Datapoint
Mikha Zaslavskiy said: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.
IPrimitiveCommandEvents
Mikha Zaslavskiy said: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
Artur Goldsweer said: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.