I resume this old discussion of 2016 and I ask .... in the event that we find a complex form (MSDelementtyPecomplexshape) how the function should be changed to be able to elevate a shape that contains two arches and two lines.
Option Explicit Sub TestMoveShape() Dim elemId As DLong elemId = DLongFromLong(1307192) Dim el As Element Set el = ActiveModelReference.GetElementByID(elemId) If (msdElementTypeShape = el.Type) Then processShape el.AsShapeElement End If End Sub Private Sub processShape(shape As ShapeElement) Dim numOfVertices As Long numOfVertices = shape.VerticesCount Dim index As Long For index = 1 To numOfVertices shape.vertex(index) = moveVertex(shape.vertex(index)) Next shape.Rewrite End Sub Private Function moveVertex(vertex As Point3d) As Point3d Const zVal = 53.65 moveVertex = vertex moveVertex.Z = zVal End Function
Hi Tiziano,
Tiziano Sapora said:how the function should be changed to be able to elevate a shape that contains two arches and two lines.
in my opinion you choose wrong approach:
I do not know a context of original discussion and code, but as Jon wrote, it is wrong to move vertices individually, when an element offers Transform method.
Also, another wrong assumption is that code used for simple shape can be easily transformed to be used with complex shape. Sometimes yes, but often not. The shape is simple element, whereas ComplexShape is complex element, consisting from more different elements internally. It means to access the content works in a different way.
And it is situation where Transform method makes sense, because it allows to manipulate with the whole element in a uniform way, regardless its type.
Or you are interested in some internal modifications, so not to simple move the whole element in Z axis direction?
With regards,
Jan
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
Tiziano Sapora said:From what I seemed to understand with "transform3d"
Transforms are not specific to MicroStation VBA: they are a widely-used mathematical concept. Matrix3d and Transform3d are MicroStation VBA representations of common objects. Take a look at this page and follow links to other sites.
Matrix3d
Transform3d
Regards, Jon Summers LA Solutions
Hey Jon, first of all, thank you for your advices, I've found them super useful.Taking Tiziano's problem a bit further, I think we have 2 distinct situations, when trying to translate a ComplexChain or ComplexShape along the Z axis:
1) flattening the element in the process - that is the easy part. The following code will do the job (will flatten the element and elevate it to 10m) : ele.Transform Transform3dFromMatrix3dPoint3d(Matrix3dFromScaleFactors(1, 1, 0), Point3dFromXYZ(0, 0, 10))2) non-flattening transform. In theory, the following code should do : ele.Transform Transform3dFromMatrix3dPoint3d(Matrix3dFromScaleFactors(1, 1, 1), Point3dFromXYZ(0, 0, 10))However, instead of translating it to the specified elevation (10, in this case), it will simply add 10 to the existing elevation.What am I missing ?Best regards,Paul
Paul Mitache said:Transform3dFromMatrix3dPoint3d(...)However, instead of translating it to the specified elevation (10, in this case), it will simply add 10 to the existing elevation
From VBA help: Returns a transformation from given matrix and translation parts. So, yes, in your example it does what is expected.
There are a lot of methods that work with Transform3d: search for Transform3d Type in VBA help. Perhaps Transform3dFromMatrix3dAndFixedPoint3d will do what you want?
Transform3dFromMatrix3dAndFixedPoint3d
Thanks, Jon. That confirms to me that I was on the right path, but got lost in the woods.
The general syntax of that method is :trns = Transform3dFromMatrix3dAndFixedPoint3d(matrix, origin), where origin is the pivot (3D point). The problem is with the "matrix" component, which is a placeholder for a transformational matrix (or a Matrix3d type), if I understand correctly.
But when I am referring to the Microstation VBA help, looking up "Matrix3d Type" returns a wall of text, with a bunch of matrix subtypes. And I am completely lost there. Could you please tell me which one is the best one to be used for translation operations ? I am guessing one of two : - Matrix3dFromVectorAndRotationAngle (however, I've tried changing the Z vector values and didn't work)- Matrix3dFromMatrix3dTimesMatrix3d, which returns the product of two matrices.
Regards,
Paul
Paul Mitache said: The problem is with the "matrix" component
If you're not interested in rotation, then supply the identity matrix Matrix3dIdentity.
Matrix3dIdentity
I've tried using an example of IdentityMatrix I've found on your site (slightly adapted), but it does not work. No errors, just not doing anything. What am I doing wrong, please ? Dim m1 As Matrix3d Dim m2 As Matrix3d Dim multiplication As Matrix3d ZAxis = 10 'this is the elevation value the element needs to be translated to origin = Point3dFromXYZ(0, 0, ZAxis) m1 = Matrix3dFromAxisAndRotationAngle(ZAxis, 0) 'no rotation angle, just translation m2 = Matrix3dIdentity multiplication = Matrix3dFromMatrix3dTimesMatrix3d(m1, m2) trns = Application.Transform3dFromMatrix3dAndFixedPoint3d(multiplication, origin)
Hi Paul,
at first, please use Insert > Insert Code tool, when you want to share any code snippet (even one line only). It ensures it's displayed better.
Paul Mitache said:Matrix3dFromAxisAndRotationAngle(ZAxis, 0) 'no rotation angle, just translation
What looks like a bug to me is that you use variable named ZAxis, but it's used to define rotation around X (0), not about Z (value should be 2).
Also, it's not clear where ZAxis comes from and what is its value.
Hey Jan,
Thank you for your quick reply. I do apologize for not formatting the code properly - will keep that in mind.You are probably right, I might have used the wrong 3dMatrix component. I am just looking for something that would do a translation along the Z axis (no rotation or scaling) and I was trying different things, in hope that something will work. I know I should multiply the Matrix3dIdentity by a translation matrix, but I am not sure what is the exact matrix that does that.
Best regards, Paul
Paul Mitache said:m1 = Matrix3dFromAxisAndRotationAngle(ZAxis, 0) 'no rotation angle, just translation
m1 = Matrix3dFromAxisAndRotationAngle(ZAxis, 0) 'no rotation angle, just translation
You're failing to understand the mechanics of matrices. A Matrix3d can convey rotation, scaling or skew but not translation.
Paul Mitache said:I am just looking for something that would do a translation
You need a Transform3d to perform translation.
Paul Mitache said:I should multiply the Matrix3dIdentity by a translation matrix
Why do you think that? You need a transformation matrix. If you want only to translate then rotation and scaling don't enter the equation, and no rotation matrix is required. Where the Transform3d API requires a rotation matrix, use the no-op Matrix3dIdentity. In some cases, the identity matrix is supplied invisibly...
Transform3d = Transform3dFromPoint3d (translation) ' Returns a transformation with identity matrix part
That's the same as writing this...
Transform3d = Transform3dFromMatrix3dPoint3d (Matrix3dIdentity, translation)
Jon, thank you for your patience. By using the method you suggested I've managed to get the code working, but it's doing the same thing as the previous method (see below), which is adding the specified value (10 in this case) to the current elevation of the element. What I am trying to achieve is translate the element to that specific elevation, not add up to the existing one. Does it make sense ?
ele.Transform Transform3dFromMatrix3dPoint3d(Matrix3dFromScaleFactors(1, 1, 1), Point3dFromXYZ(0, 0, 10))