Rhino.Geometry.Transform.Translation does not move all mesh vertices by the same amount

rhinocommon-v6
rhino6
unhandled
rhino-for-windows

#1

Hello

We are working with Rhino Version 6 (6.3.18090.471, 31.03.2018) on Windows 10 x64.

After processing the buildings near the coordinate system origin in order to avoid problems with the floating-point resolution, we have to move them back to the original location in our national spatial reference system.

For that move we use a translation:

xform = Rhino.Geometry.Transform.Translation(2621232.0,1259640.0,343.0)
rhino_object.Geometry.Transform(xform)

This screenshot shows the mesh near the coordinate system origin ( X=0, Y=0, Z=0)

RhinoTranslation

image

After executing the transformation, one vertex near the ridge of the roof jumped to another mesh edge. On the screenshot ther is an offset visible.

The behavior can be reproduced with the attached python script and the Rhino model.
TranslationMovesVertex.3dm (83.9 KB)

MoveGeometry.py (1.3 KB)

Any idea what goes wrong here?

Thanks in advance
Thomas


(Menno Deij - van Rijswijk) #2

This is, most likely, floating point resolution giving you problems. For compatibility reasons, the Mesh class uses single precision Vertices by default. You may have more luck if you call UseDoublePrecision on the vertex list before attempting any transformations.

https://developer.rhino3d.com/api/RhinoCommon/html/P_Rhino_Geometry_Collections_MeshVertexList_UseDoublePrecisionVertices.htm


#3

Thanks a lot for your support!

When I look in the debugger the meshVertexList actually consists of Single-precision floating point numbers (Point3f Structure)

Because whe have not yet the version 6.10 of Rhino installed there is no property UseDoublePrecisionVertices available and I am not able to verify if that helps.

Is there no global settig to tell the application do use double precision floating point numbers?


(Menno Deij - van Rijswijk) #4

Unfortunately there is no way to tell Rhino to use double precision globally.

Please verifiy that your version (6.3) does not have this property, I think it was introduced already at the beginning of Rhino 6, but I am not sure.


#5

In version 6.3, the property UseDoublePrecisionVertices does not exist. I have to look now how I can install the latest version of Rhino through the IT department. This could take a while.


#6

After installing the version 6.10 I tried to convert an existing mesh:

    mesh = rhino_object.Geometry
    mesh.Vertices.UseDoublePrecisionVertices = True

This did not convert the MeshVertexList points from Point3f to Point3d

Then I tried to build up a new mesh (I know there has to be an easier way):

    doublePresisionMesh = Rhino.Geometry.Mesh()
    doublePresisionMesh.Vertices.UseDoublePrecisionVertices = True
    point3dArray = mesh.Vertices.ToPoint3dArray()
    doublePresisionMesh.Vertices.AddVertices(point3dArray)
    for meshFace in mesh.Faces:
        if meshFace.IsQuad:
            doublePresisionMesh.Faces.AddFace(meshFace.A, meshFace.B, meshFace.C, meshFace.D)
        if meshFace.IsTriangle:
            doublePresisionMesh.Faces.AddFace(meshFace.A, meshFace.B, meshFace.C)

    doublePresisionMesh.FaceNormals.ComputeFaceNormals()
    doublePresisionMesh.Normals.ComputeNormals()
    doublePresisionMesh.Compact()

After that, the MeshVertexList points still consist of Point3f points.


(Menno Deij - van Rijswijk) #7

Yes, this is for API compatibility reasons and type information. The MeshVertexList is of type IEnumerable<Point3f> and nothing you can do will change it to Point3d. But, if you set UseDoublePrecisionVertices the vertices will be stored in double precision and all operations performed on the mesh will use these double precision vertices.

You can set the double precision vertices with AddVertices(IEnumerable<Point3d>) or Add(double,double,double) and get them with ToPoint3dArray(). There is no other way unfortunately.

The question is though, does using double precision vertices solve your problem during translation?


#8

Thank you for your explanations. Now I start to understand how it works.

Unfortunately, the double precision vertices do not solve the problem.

Here is the modified script and the Rhino document:

MoveGeometryDoublePrecision.py (2.2 KB)
TranslationMovesVertex.3dm (34.5 KB)


(Dale Fugier) #9

Hi @thomas.k,

Try this:

import Rhino
import rhinoscriptsyntax as rs
import scriptcontext as sc

def RunCommand():
    
    mesh_id = rs.GetObject("Select mesh")
    mesh = rs.coercemesh(mesh_id)
    
    xform = Rhino.Geometry.Transform.Translation(2621232.0,1259640.0,343.0)
    
    mesh_copy = mesh.DuplicateMesh()
    mesh_copy.Vertices.UseDoublePrecisionVertices = True
    mesh_copy.Transform(xform)

    sc.doc.Objects.AddMesh(mesh_copy);
    sc.doc.Views.Redraw()

if __name__ == "__main__":
  RunCommand()

– Dale


#10

Thanks @dale. This is an elegant way to make a copy of the mesh.

After translation, there is still this shift in the ridge.


(Giulio Piacentino) #11

@thomas.k

could you please send us a portion of this file to check?

Thanks,

Giulio


Giulio Piacentino
for Robert McNeel & Associates
giulio@mcneel.com


#12

@piac
In the attached file TranslationMovesVertex.3dm there is one building stored.
The building before the translation is stored in the layer “Building Solid Mesh”
The building after the translation is stored in the layer “Result”

TranslationMovesVertex.3dm (34.5 KB)

Thanks a lot for your support!


(Giulio Piacentino) #13

@thomas.k somehow the file did not upload properly. Can you try again?


#14

Second try to upload the file: TranslationMovesVertex.zip (8.5 KB)