mitsuba2 icon indicating copy to clipboard operation
mitsuba2 copied to clipboard

Alembic support (www.alembic.io) - [✨ new feature]

Open SergeyShlyaev opened this issue 4 years ago • 7 comments

Description

Alembic is an open computer graphics interchange framework. (www.alembic.io) It is file format for exchanging 3D computer animation information between different platforms and applications. Any app can write their 3D information out in the Alembic format. Which can then be read in by any other app that supports Alembic, such as Maya, 3dsmax, Houdini, Katana, Nuke to name a few.

Alembic stores 3D geometry in a format that is very efficient with a small file size that is quick to read and unpack. Using alembics makes it a ton easier to get complex scenes into Mitsuba. Current plugin implementation supports arbitrary meshes made of triangles, quads or any n-gons with optional UV coordinates, vertex normals and other custom vertex or face attributes.

Mentioned in #211.

Testing

Tried with various types of geometry, including n-gons, degenerate geo, various vertex and face attributes. Tested on light, medium and very heavy geo. Test scene attached.

Questions

  1. How do I create multiple mesh shapes? Alembic may contain several separate meshes like serialized files, but now it only seem to create the last mesh in file or the one that is specified by shape_index. How can I create more then one?
  2. How can one assign material from inside cpp code? We can specify material assignment in alembic file, would be great to be able to use it in plugin. This may open the road to tighter integration cause we can specify bsdf assignment directly in DCC. Supposedly, I’ll need to manipulate m_bsdf somehow?
  3. Is there a concept of faceset/vertex set in Mitsuba? Faceset is a set (or group) of faces in an existing mesh. This is useful in order to more easily re-select them later when making shader, attribute, and visibility assignments to a sub-set of faces on a single mesh.

Prerequisities

Requires alembic git clone http://github.com/alembic/alembic

Checklist:

  • [+] My code follows the style guidelines of this project

  • [+] My changes generate no new warnings

  • [*] My code also compiles for gpu_* and packet_* variants. If you can't test this, please leave below. Packet variants – Yes. Gpu can't test as I'm on Mac.

  • [+] I have commented my code

  • [ ] I have made corresponding changes to the documentation Need help on how to do that. Doc for the plugin is included in cpp file.

  • [ ] I have added tests that prove my fix is effective or that my feature works Need help on how to do that

  • [+] I cleaned the commit history and removed any "Merge" commits

  • [+] I give permission that the Mitsuba 2 project may redistribute my contributions under the terms of its license

abc01 abc02

mitsuba_alembic_test.zip

SergeyShlyaev avatar Aug 21 '20 03:08 SergeyShlyaev

Hi @SergeyShlyaev,

Thanks a lot for this PR!

  1. How do I create multiple mesh shapes? Alembic may contain several separate meshes like serialized files, but now it only seem to create the last mesh in file or the one that is specified by shape_index. How can I create more then one?

For this you will need to use the mitsuba::Object::expand() method (see doc in object.h)

  1. How can one assign material from inside cpp code?

You will need to instanciate the BSDF yourself using the PluginManager and assign the returned pointer to Shape::m_bsdf.

  1. Is there a concept of faceset/vertex set in Mitsuba?

No there isn't. And we probably won't support this in the future. Mitsuba 2 being a research-oriented framework, it is unlikely that we will add support for "fancy" shaders to do things like "shader, attribute, and visibility assignments".

I am worried about the alembic dependency. is this library self-contained? Or will it pull a massive amount of code from its own dependencies as well? We would rather keep Mitsuba as lightweight as possible ;)

Speierers avatar Aug 26 '20 07:08 Speierers

Given the very heavy nature of Alembic, USD, and similar packages, I don't think that such a contribution can be merged directly into Mitsuba master. :(. (The policy of Mitsuba 2 is that all dependencies are automatically built using a self-contained build system)

wjakob avatar Aug 26 '20 11:08 wjakob

Hi guys,

Thank you for the tips. There are only two required dependencies. From https://github.com/alembic/alembic

  1. Required:
CMake (2.8.11+ newer is better for Windows builds) www.cmake.org
OpenEXR (2.2.0) www.openexr.com (for ilmbase)

Both of them are already part of Mitsuba I believe, so Alembic does not seem to bring any new dependencies.

While working on spectral video, found myself spending too much time preparing datasets for render and debugging why something does not work. I believe there should be simpler way to do it. Alembic looks like natural choice for it due to vast format capabilities and wide adoption.

Having it should reduce preparation time. And free time for actual research work in Mitsuba which is amazing.

~~2. Multiple meshes~~ Edit: Got it working, just need to use right Props and then expand()

Click to expand > For this you will need to use the mitsuba::Object::expand() method

Thanks, expand() works, it creates several meshes. But they do not seem to pick up material assignment from xml file or other properties like vertex normals.

Doing it like:

std::vector<ref<Object>> m_mesh_objects;
for (every polymesh)
{
     // read data from file
    // fill data arrays
    // create new mesh:
    Properties props;
    ref<Mesh<Float, Spectrum>>  mesh =
        new Mesh<Float, Spectrum>(m_mesh_name, m_vertex_count, m_face_count, 
                props, polymesh_has_vertex_normals, polymesh_has_uvs);
    mesh->parameters_changed();
    m_mesh_objects.push_back(mesh);
}
...
std::vector<ref<Object>> expand() const override {
    return m_mesh_objects;
}

What am I doing wrong? Need to make it pick up material specified in xml file as usual:

    <bsdf type="diffuse" id="my_diffuse_bsdf">
         <rgb name="reflectance" value="0.2, 0.25, 0.7"/>
    </bsdf>

    <shape type="abc">
        <string name="filename" value="mesh/abc/test.abc"/> 
	<ref id="my_diffuse_bsdf"/>
    </shape>

Tech question: Do you recommend inherit AlembicMesh class from Mesh or from Shape?

  1. Facesets

Mitsuba 2 being a research-oriented framework, it is unlikely that we will add support for "fancy" shaders to do things like "shader, attribute, and visibility assignments”.

Sure. Actually, Blender addon has very similar feature for exporting mesh with multiple materials assigned. For Alembics we could do it same way if needed, it answers the question. Visibility assignments are already supported, no need to do anything.

Cheers

SergeyShlyaev avatar Aug 28 '20 01:08 SergeyShlyaev

You will need to instanciate the BSDF yourself using the PluginManager and assign the returned pointer to Shape::m_bsdf

Thank you, found the example in shape.cpp:80 on how to create bsdf. But is there a way to specify bsdf by name, not to create bsdf? Similar to how it's done in xml:

<ref id="my_diffuse_bsdf"/>

This is for extra option to be able to follow material assignment from Alembic file. To make it probably I need to construct named reference somehow and use it in props?

SergeyShlyaev avatar Aug 29 '20 02:08 SergeyShlyaev

But is there a way to specify bsdf by name, not to create bsdf?

Would this name correspond to the id of a BSDF defined elsewhere in the XML file?

I suggest we focus on the "geometry" part of this plugin for now. Adding support for BSDF binding might require changes in the rest of the codebase which would make this PR quite heavy.

Speierers avatar Aug 31 '20 07:08 Speierers

Pushed new version with support for loading multiple objects from file. Added support for shape_name to specify object by name.

alembic_sweets

Would this name correspond to the id of a BSDF defined elsewhere in the XML file?

Yes, correct.

I suggest we focus on the "geometry" part of this plugin for now. Adding support for BSDF binding might require changes...

Agree, it looks slightly more complicated after deeper look. Probably to make it work, need to instantiate bsdf and all of it’s nested references manually and attach it via props. Similar to instantiate_node() function in xml.cpp

alembic_sweets.zip

SergeyShlyaev avatar Sep 01 '20 02:09 SergeyShlyaev

Added camera plugin to read camera data fom alembic file. Adding this fullfills the original intention of this PR, to have simpler way of getting complex datasets into renderer. With this one can export scene with geo, lights, cameras into single Alembic file and then read it into Mitsuba.

city

SergeyShlyaev avatar Sep 06 '20 22:09 SergeyShlyaev