Transformation matrix XYZ to XZY

Hello.

I’m trying to export transformation matrix to octane render but Octane’s coordinate space is XZY from what I understand. Maybe it’s the same with .obj files. Anyhow, my question is how to modify a transformation matrix from xyz to xzy. And also from millimeters to meters.

Any help is appreciated!

How about this (in Python):

import Rhino

# Create scale transformation
us_from = Rhino.UnitSystem.Millimeters
us_to = Rhino.UnitSystem.Meters
scale = Rhino.RhinoMath.UnitScale(us_from, us_to)
xf_scale = Rhino.Geometry.Transform.Identity
xf_scale.M00 = scale
xf_scale.M11 = scale
xf_scale.M22 = scale

# Create rotation transformation
origin = Rhino.Geometry.Point3d.Origin
xaxis = Rhino.Geometry.Vector3d.XAxis
zaxis = Rhino.Geometry.Vector3d.ZAxis
plane_xz = Rhino.Geometry.Plane(origin, xaxis, zaxis)
plane_xy = Rhino.Geometry.Plane.WorldXY
xf_rotate = Rhino.Geometry.Transform.PlaneToPlane(plane_xy, plane_xz)

# Final transformation
xform = xf_scale * xf_rotate

#TODO: scale objects...

print xform

– Dale

Thanks, im not quite shure how to use your script though. What I need is something on the following format. But I’m lacking the geometry skills to understand how to translate the matrix or output to XZ-Y. Hope the screenshots can explain the issue better…

GH attached below:

Sample scene in Rhino:

Sample scene in octane - translation works but not scale and rotate:
imagescatter.gh (168.6 KB)

nothing wrong with the obj file, use unit meter and place your scene in the center of grid
and it’s better if you share your file maybe you did something wrong when exporting

The scene is just a sample.

What is want is this:

I’m working on architecture projects that are usually modelled in millimeter scale. I’m trying to find a way to use grasshopper to export a csv with only transformation data (placement, scale, rotation) and connect the transformation data, scatter node in octane standalone, to a separate obj / orbx. This would be very useful as a way to distribute placeholders for objects such as plants, people, cars and so on in rhino/grasshopper and then replace them with the actual textured meshes in octane.

CSV export works fine and xyz transformation works if I just swap Z for -Y. But rotation and scale is beyond my understanding of the transformation matrix.

reply above

octane don’t have scatter option? and i think there is a octane plugin for rhino

Octanes standalone’s scatter is limited to distribute geometries according to a csv file with transform data. No possibilities there do set up rules for the scattering.

Yes, the Rhino plugin for octane has something similar, but thats not what I’m looking for. It would be nice to have the full flexibility to design a custom script in GH and export it as a csv.

I’m not sure though if it’s a matter of formatting the export or apply transformations for the change of coordinate system with GH components before the export formatting.

Hi, currently working on this problem. Did you ever figure it out?

This VB script is what I’ve been using. I’m afraid i don’t remember where the original code came from so apologies for left out credit to the original author.

I think it works for most cases. You feed it with xform and it outputs in a format ready for csv export.

Hope it helps

Option Strict Off
Option Explicit On

Imports System
Imports System.Collections
Imports System.Collections.Generic

Imports Rhino
Imports Rhino.Geometry

Imports Grasshopper
Imports Grasshopper.Kernel
Imports Grasshopper.Kernel.Data
Imports Grasshopper.Kernel.Types

Imports System.IO
Imports System.Linq
Imports System.Data
Imports System.Drawing
Imports System.Reflection
Imports System.Windows.Forms
Imports System.Xml
Imports System.Xml.Linq
Imports Microsoft.VisualBasic
Imports System.Runtime.InteropServices

Imports Rhino.DocObjects
Imports Rhino.Collections
Imports GH_IO
Imports GH_IO.Serialization

''' <summary>
''' This class will be instantiated on demand by the Script component.
''' </summary>
Public Class Script_Instance
  Inherits GH_ScriptInstance

  #Region "Utility functions"
  ''' <summary>Print a String to the [Out] Parameter of the Script component.</summary>
  ''' <param name="text">String to print.</param>
  Private Sub Print(ByVal text As String)
    'Implementation hidden in Script Edit mode...
  End Sub
  ''' <summary>Print a formatted String to the [Out] Parameter of the Script component.</summary>
  ''' <param name="format">String format.</param>
  ''' <param name="args">Formatting parameters.</param>
  Private Sub Print(ByVal format As String, ByVal ParamArray args As Object())
    'Implementation hidden in Script Edit mode...
  End Sub
  ''' <summary>Print useful information about an object instance to the [Out] Parameter of the Script component. </summary>
  ''' <param name="obj">Object instance to parse.</param>
  Private Sub Reflect(ByVal obj As Object)
    'Implementation hidden in Script Edit mode...
  End Sub
  ''' <summary>Print the signatures of all the overloads of a specific method to the [Out] Parameter of the Script component. </summary>
  ''' <param name="obj">Object instance to parse.</param>
  Private Sub Reflect(ByVal obj As Object, ByVal method_name As String)
    'Implementation hidden in Script Edit mode...
  End Sub
#End Region

#Region "Members"
  ''' <summary>Gets the current Rhino document.</summary>
  Private Readonly RhinoDocument As RhinoDoc
  ''' <summary>Gets the Grasshopper document that owns this script.</summary>
  Private Readonly GrasshopperDocument as GH_Document
  ''' <summary>Gets the Grasshopper script component that owns this script.</summary>
  Private Readonly Component As IGH_Component
  ''' <summary>
  ''' Gets the current iteration count. The first call to RunScript() is associated with Iteration=0.
  ''' Any subsequent call within the same solution will increment the Iteration count.
  ''' </summary>
  Private Readonly Iteration As Integer
#End Region

  ''' <summary>
  ''' This procedure contains the user code. Input parameters are provided as ByVal arguments,
  ''' Output parameter are ByRef arguments. You don't have to assign output parameters,
  ''' they will have default values.
  ''' </summary>
  Private Sub RunScript(ByVal matrix As Transform, ByRef code As Object) 
    Dim segments() As String
    ReDim segments(11)

    Dim format As String = "0.00##"


    segments(0) = matrix.M00.ToString(format)
    segments(1) = matrix.M02.ToString(format)
    segments(2) = -matrix.M01.ToString(format)
    segments(3) = 0.001 * matrix.M03.ToString(format)
    segments(4) = matrix.M20.ToString(format)
    segments(5) = matrix.M22.ToString(format)
    segments(6) = -matrix.M21.ToString(format)
    segments(7) = 0.001 * matrix.M23.ToString(format)
    segments(8) = -matrix.M10.ToString(format)
    segments(9) = -matrix.M12.ToString(format)
    segments(10) = matrix.M11.ToString(format)
    segments(11) = 0.001 * -matrix.M13.ToString(format)


    code = String.Join(", ", segments)
  End Sub 

  '<Custom additional code> 

  '</Custom additional code> 
End Class