SketchUp entities mirrored with "flip along (axis)" not reflected in transform matrix

StackOverflow https://stackoverflow.com/questions/17936161

  •  04-06-2022
  •  | 
  •  

Вопрос

Question updates at the bottom....

I'm writing a custom SketchUp export plugin in Ruby. I then recreate the geometry in Three.js using the exported data.

I'm having troubles with some component/group transformations, and tracked it down to mirroring, or geometry that has "flip along" applied for some axis. Simply put, the flip along is not respected. I can not find any SU Ruby method to find out whether any given entity has this flip along applied.

I can get a transformation matrix, and convert it (see this question of mine how), however it does not work for these flipped objects. Here's an example result; the rest of the model is fine, but the boat is obviously created using flipped boat halves, and in this picture they appear all over the place:

messy boat

How can I properly take these flipped geometries into account? Do they have some kind of separate matrix, or entity flag in SU Ruby?

Note 1) I have observed similar buggy behaviour in the built-in SketchUp Collada exporter (when loading them with Three.js ColladaLoader).

Note 2) Although I believe this to be a SketchUp Ruby API issue, I tagged this with Three.js just in case there is something obvious I'm missing in regards to mirroring and Matrixes..

Note 3) If the geometries are flipped / mirrored using the scale tool instead of flip along tool (effectively the same result), they work correctly.

UPDATE:

Still struggling to apply this information, but getting closer based on this information: http://sketchucation.com/forums/viewtopic.php?f=6&t=3083

UPDATE #2:

Thanks to Thomthom, I was able to detect and apply correct flipping for objects that are not rotated. For a plain unrotated/unscaled/unflipped component the matrix is:

 1.0, 0.0, 0.0
 0.0, 1.0, 0.0
 0.0, 0.0, 1.0

For a flipped (mirrored) component the matrix can be:

-1.0, 0.0, 0.0
 0.0, 1.0, 0.0
 0.0, 0.0, 1.0

So I can detect that flip easily and all is fine.

But if I arbitrarily rotate the same component (unflipped) an a couple of axes, the matrix looks like this:

 -0.33, -0.58,  0,74
  0.87, -0.50,  0,00
  0.37,  0.64,  0,67

This works correctly in my exporter/importer, I can reapply this matrix on Three.js side.

But when that already rotated component is also mirrored, the matrix looks like this:

  0.33,  0.58, -0.74
  0.87, -0.50,  0.00
  0.37,  0.64,  0.67

I can't get this matrix work correctly in Three.js, and the component is never mirrored, resulting in the behaviour that can be seen in the picture.

So, I'm not sure what to do. I was able to get correct results by detecting the simpler case (only flipped, not rotated or scaled), then setting for example object.scale.x = object.scale.x * -1; in Three.js for such components. But no solution for items that are both flipped and otherwise rotated or scaled :(

Это было полезно?

Решение

Use my Transformation Inspector to visualize the SketchUp matrix in a 4x4 grid: http://extensions.sketchup.com/en/content/transformation-inspector

Using that I can tell which matrix entry changed as I flipped along any axis: * **Flip along X:** Index #1 * **Flip along Y:** Index #5 * **Flip along Z:** Index #10

Martin Rinehart has written a breakdown of the transformation in SketchUp: http://www.martinrinehart.com/models/tutorial/tutorial_t.html


Find flipped axis with orientation:

module TransformationHelper

  def flipped_x?
    dot_x, dot_y, dot_z = axes_dot_products()
    dot_x < 0 && flipped?(dot_x, dot_y, dot_z)
  end

  def flipped_y?
    dot_x, dot_y, dot_z = axes_dot_products()
    dot_y < 0 && flipped?(dot_x, dot_y, dot_z)
  end

  def flipped_z?
    dot_x, dot_y, dot_z = axes_dot_products()
    dot_z < 0 && flipped?(dot_x, dot_y, dot_z)
  end

  private

  def axes_dot_products
    [
      xaxis.dot(X_AXIS),
      yaxis.dot(Y_AXIS),
      zaxis.dot(Z_AXIS)
    ]
  end

  def flipped?(dot_x, dot_y, dot_z)
    dot_x * dot_y * dot_z < 0
  end

end


module Example

  def self.inspect_flipped
    tr = Sketchup.active_model.selection[0].transformation
    tr.extend(TransformationHelper)

    puts "X Flipped: #{tr.flipped_x?.inspect}"
    puts "Y Flipped: #{tr.flipped_y?.inspect}"
    puts "Z Flipped: #{tr.flipped_z?.inspect}"
  end

end
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top