Bonjour,
I try to round off several lineelement
Dim Sc As ElementScanCriteria Dim Ee As ElementEnumerator Set Sc = New ElementScanCriteria Sc.ExcludeAllTypes Sc.IncludeType msdElementTypeLine Set Ee = ActiveModelReference.Scan(Sc) Dim LLanc As LineElement Dim PtLL1 As Point3d Dim PtLL2 As Point3d Dim Ar() As Element Do While Ee.MoveNext Dim LLNew As LineElement Set LLanc = Ee.Current With LLanc.startPoint PtLL1 = Point3dFromXYZ(Round(.X, 3), Round(.Y, 3), Round(.Z, 3)) End With With LLanc.EndPoint PtLL2 = Point3dFromXYZ(Round(.X, 3), Round(.Y, 3), Round(.Z, 3)) End With Set LLNew = CreateLineElement2(LLanc, PtLL1, PtLL2) ActiveModelReference.RemoveElement LLanc 'ActiveModelReference.AddElement LLNew ' doesn't work if ee > 1024 Loop RedrawAllViews
Doesn't work if the number of lines is up to 1024... 210
So I made a trick not very academic with « if..then.. end if » and « goto »
Suite: If Ee.MoveNext Then Set LLanc = Ee.Current With LLanc.startPoint PtLL1 = Point3dFromXYZ(Round(.X, 3), Round(.Y, 3), Round(.Z, 3)) End With With LLanc.EndPoint PtLL2 = Point3dFromXYZ(Round(.X, 3), Round(.Y, 3), Round(.Z, 3)) End With Set LLNew = CreateLineElement2(LLanc, PtLL1, PtLL2) ActiveModelReference.RemoveElement LLanc ActiveModelReference.AddElement LLNew Ee.MoveNext GoTo Suite End If RedrawAllViews
I’d like tu use addelements method but i don’t see a example,
I ‘ve tried namedgroup, elementenumerator , arrays seems to be the best way but i failed
Does anyone have an example? Or help
What version (e.g. v10.x.y.z) of MicroStation, or other product, are you using?
LaurentD said:Doesn't work if the number of lines is up to 1024... 210
I suspect that your problem is caused by creating new elements within your scan loop. The scanner continues to enumerate each new line that you add.
Here are a couple of suggestions:
ScanCriteria
LineElements
ElementEnumerator
Regards, Jon Summers LA Solutions
Hi Laurent,
with all respect, you approach (and consequently your code) is wrong from several reasons.
As Jon explained, it's not good idea to create new elements in element enumerator. The scan enumerator caches only a few elements and when it's necessary, it reads a next part of DGN file. So when you create a new element (or you modify existing element in such way it has to be moved the end of the file; because of its size change), the enumerator will read also this newly created element, which is never correct.
But what is more important: To create a new element and to remove the old one is completely wrong in my opinion. In fact you do not round line elements, but you create lines copies with rounded vertices. But the result elements are not the same, e.g. ElementIDs are different ... which can be a critical issue in some scenarios.
This code (structured to single response subs and functions, which I prefer), should work:
Option Explicit Public Sub RoundLineVerticesInActiveModel() Dim esc As ElementScanCriteria Set esc = CreateScanCriteria ProcessAllLinesInActiveModel esc, 3 End Sub Private Function CreateScanCriteria() As ElementScanCriteria Dim esc As New ElementScanCriteria esc.ExcludeAllTypes esc.IncludeType msdElementTypeLine Set CreateScanCriteria = esc End Function Private Sub ProcessAllLinesInActiveModel(esc As ElementScanCriteria, precision As Integer) Dim ee As ElementEnumerator Set ee = ActiveModelReference.Scan(esc) Do While ee.MoveNext RoundLineVertices ee.Current.AsLineElement, precision ee.Current.Rewrite Loop End Sub Private Function RoundLineVertices(line As LineElement, precision As Integer) As LineElement Dim startRounded As Point3d startRounded = Round3dCoordinate(line.StartPoint, precision) line.ModifyVertex 0, startRounded Dim endRounded As Point3d endRounded = Round3dCoordinate(line.EndPoint, precision) line.ModifyVertex 1, endRounded End Function Private Function Round3dCoordinate(coordinate As Point3d, precision As Integer) Dim rx As Double rx = Round(coordinate.X, precision) Dim ry As Double ry = Round(coordinate.Y, precision) Dim rz As Double rz = Round(coordinate.Z, precision) Round3dCoordinate = Point3dFromXYZ(rx, ry, rz) End Function
With regards,
Jan
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
Answer Verified By: LaurentD
i thought scancriteria only ran onceI learn
Thank you both
LaurentD said:i thought scancriteria only ran once
this is very widespread mistake. In fact, your formulation makes no sense, because Scan Criteria does not run anything ;-)
To be precise (because we are in developers' community):
Main features of enumerator (it's common to many programming languages) are:
So the definition is not "it will run once only", but "it will stop at the end of the model". But "end of the model" is not fixed, so when you add elements during scanning or modify existing element and change its size, so it has to be rewritten to the end of the file, the end is moving.