How to set normal of face with C API?

Hey, all:

I have all the information of mesh exported from 3DS Max, including the normal of faces. Especially, the normal changed by smooth group of 3DS Max is special, and I want to export it into Sketchup through C API completely.

The flowing function is getting normal of face:
http://extensions.sketchup.com/developer_center/sketchup_c_api/sketchup/face_8h.html#ae0f5f461defab7f229c52b7b5bd25061

My question:

  1. Is there a function could set the normal of face directly with C API?
  2. If not, how can I handle the ‘informal’ normal changed by smooth group in 3DS Max with Sketchup C API?

Thanks very much, and welcome any proposal :slight_smile:

You can use SUFaceReverse to re-orient a face. Other than the orientation (winding order) SketchUp stores no normal information.

Thanks eneroth3. I understand the SUFaceReverse function could reverse a face, and there is no function in C API could set the normal of face directly.

However, it maybe a smooth and soften issue just described in the following link: https://help.sketchup.com/en/sketchup/softening-smoothing-and-hiding-geometry

So, appreciate for any suggestion about how can I smooth normals depending on the angle and soften the edge with C API.

Smooth and soften are properties of Edges in SketchUp. SUEdgeSetSmooth and SUEdgeSetSoft appears to be the C API methods for controlling this.

You could get the angle from the dot product of the normals of the adjacent faces.

Normals are never manipulated in SketchUp directly, other than reversing the direction of faces. And face normals are always perpendicular to the Face’s plane.

Vertex normals are implicitly controlled by its connected edges. Only smooth edges affect the vertex normals. More details: http://www.thomthom.net/thoughts/2012/06/soft-vs-smooth-vs-hidden-edges/

If you want to read them you can use SUMeshHelper.

We should probably document how the normals are calculated so it’s possible to reproduce this yourself manually.

Thanks, tt. And yep, it’s better if the developers could know how to reproduce the normals manually. At least, it’s flexible for us to create the mesh more accurately.

Looking forward to see that soon.

Thanks, eneroth3.
I know corresponding API about how to soften and soft an edge. However, is there any function contains the input with the angle between normals as a threshold just like what the Sketchup application has?

Not that I know of. Generally speaking the SketchUp APIs implement lower level access as it is more versatile than mimicking what’s available in the GUI. It means though a little extra code is sometimes needed.

module Example
  # @param [Enumerable<Sketchup::Entity>] entities
  # @param [Float] max_angle In radians
  def self.soft_by_angle(entities, max_angle)
    entities.grep(Sketchup::Edge) { |edge|
      next unless edge.faces.size == 2
      face1, face2 = edge.faces
      next if face1.normal.angle_between(face2.normal) > max_angle
      edge.soft = true
      edge.smooth = true
    }
  end
end

Example.soft_by_angle(Sketchup.active_model.active_entities, 10.degrees)

To perfectly mimic the Smooth/Soften eges in the UI, already smooth/soften edges should be unsmoothed/unsoftened if above the threshold.

module Example
  # @param entities [Enumerable<Sketchup::Entity>]
  # @param max_angle [Float] In radians
  def self.soft_by_angle(entities, max_angle)
    entities.grep(Sketchup::Edge) { |e| e.soft = e.smooth = soften?(e, max_angle) }
  end

  # @param edge [Sketchup::Edge]
  # @param max_angle [Float] In radians
  def self.soften?(edge, max_angle)
    return false unless edge.faces.size == 2

    face1, face2 = edge.faces

    face1.normal.angle_between(face2.normal) <= max_angle
  end
end

Happy cakeday btw!

1 Like

Cakeday…?

That’s what it’s called on the internets!