Export 3D objects to Wavefront .obj format

Hello,
I’d like to say a few words about a new command I wrote these last days, namely output_obj.

This basically implements an export feature from G’MIC 3D meshes to the Wavefront .obj file format, which is a text format that many 3D viewers / modelers can import (including Blender, which was my target here).


A few things to know about this new feature:

  • This export feature should work with G’MIC 2.9.0+, and be available after a filter update: $ gmic update.

  • For the user, this means the .obj format is now accepted when invoking the generic command output in a G’MIC pipeline. So, a typical example of use would be:

$ gmic gmic3d output gmic3d.obj

(here, gmic3d is a G’MIC command that generates a 3D mesh).

I personnally use meshlab for a quick visualization of the generated .obj file:

$ meshlab gmic3d.obj

But, you can import it in Blender as well (with File / Import / Wavefront (.obj)):

  • Before that, G’MIC was only able to export 3D meshes into .off files (Geomview), which is not easy to import into Blender and which does not support texture mapping. So having export to .obj is a nice addition.

  • .obj export supports face materials, so colors/textures are exported.

Example: Using G’MIC to generate a textured 3D elevation from an input image:

gmic sp colorful,64 b 2 elevation3d 0.1 sp colorful t3d.. . rm. o colorful.obj

and you get this:

  • G’MIC, with its script language, is actually quite good at generating 3D procedural objects, from scratch or from image data. Of course, Blender has a lot of modeling options, as well as scriptable procedures to generate objects, but it’s pretty cool to have another way of generating procedural 3D objects. For instance, consider this small G’MIC script:
antoine3d :
  R,N=1,18
  torus3d 1,0.3
  repeat 3,scale
    repeat $N
      ang={$>*360/$N}
      +rotate3d[0] 0,1,0,{90*$>%2} +3d. {4*$R},0,0 rotate3d. 0,0,1,$ang
      color={${-math_lib};hsv2rgb([$ang,1,1])}
      if {!$scale} color3d. $color else l. split3d +[4] '$color' /[4] 2 a y endl fi
    done
    rm[0] +3d R*=4
  done

It takes a torus, creates a loop of interlaced torii from it, and do this recursively with the new shape obtained.

$ gmic antoine3d o antoine3d.obj

This generates a 1679616-primitives object, that looks like this:

  • Another example of procedural generation of 3D object, done by recursively interlacing torii
    (I don’t show the G’MIC script here, it’s still a bit dirty :slight_smile: ):

  • From G’MIC 2.9.5, you will be able to specify an output option save_materials that can take values 0=no or 1=yes. It allows to not save face material if it’s not wanted (it reduces the generated file size).

Things that have not been done, and limitations:

  • No equivalent import feature of .obj files into G’MIC. G’MIC is actually not very good at processing 3D meshes, so it’s not really that useful to have an import function for .obj files. Not saying it wouldn’t be nice, but the export has more priority (because, on the contrary, G’MIC is quite flexible to generate objects from scratch or from images).

  • The export does not support (yet) transparent primitives. It just export them fully opaque. I haven’t found a “standard” way in .obj materials to specify a level of opacity, so I gave up for the moment. There are apparently some material properties to set, but this doesn’t seem to be taken into account, both by meshlab and blender.

  • As .obj is basically a non-compressed text format, it produces large files when the 3D object to export is big. I’ve been able to export a 30-millions face object with G’MIC (this requires quite a lot of memory, but it works), as a 1.5 Gb .obj file. meshlab was able to read it, but not Blender (it tooks all my 32Gb of RAM before starting to swap). More a Blender limitation here, but it’s good to know.


That’s it for now. I hope this will be useful for some people in the future (it will for me, without any doubts).
Cheers,

David.

6 Likes

I have allread some ideas how to use this. When is the new release planed?

It’s actually working for current stable version 2.9.4, after a filter update.
Also, I’ve uploaded a new pre-release of 2.9.5 today, for Windows, in the pre-release page

Hmm, theoretically someone could code a landscape heightmap generation filter and export a 3D version with this.

If I have height map turned into a surface, that is like pyramid top (or chocolate bar top & side-bevel faces), how would you add bottom faces and make it a manifold mesh in G’MIC?

Simplified example: take gmicky the tiger, make it a relief plane… how do you have it as a relief cube, where the top face is the relief surface, and the the bottom face is flat like a plane?
In Blender, by hand, I would extrude the relief plane on Z negatively, and scale on Z to 0 the bottom face’s vertices, then uniformize all normals…

Not that easy with the existing commands, but actually I’m working on a new one to do exactly that : a kind of 3d elevation, with a solid base.
This is what I get :

Let me know if you think that could be useful for you.

1 Like

Is it possible to turn a 3d image into a 3D object via threshold? I feel like I can finally open up to creating 3D fractal.

EDIT: To expand, each pixels are boxes. And I would like the united boxes in 3D. Then export.

Could you provide a visual example?

That’s a example if I were to create a 3d sphere model using threshold. Each boxes are pixel.

There is something more advanced in G’MIC, to convert volumetric images with dimensions w\times h\times d to a 3D mesh : command isosurface3d.
Example for a 3D sphere:

$ gmic 100,100,100 set 1,50%,50%,50% distance 1 lt 50% isosurface3d 0.5

gives:

isosurface3d uses the well-known Marching Cubes method to extract a 3D surface from an isovalue in a volumetric image.

And if you blur the volumetric image a bit, you’ll get more smooth surfaces:

$ gmic 100,100,100 set 1,50%,50%,50% distance 1 lt 50% b 3 isosurface3d 0.5

2 Likes

Another example:

metaballs3d :
  100,100,100,1,"
    const s = 10;
    pot(cx,cy,cz) = gauss(x - cx,s,0)*gauss(y - cy,s,0)*gauss(z - cz,s,0);
    pot(30,30,50) + pot(50,50,30) + pot(60,30,70)"
  isosurface3d 30%

gmic_000001

1 Like

Now, I got another idea. rep_dla+skeleton+distance=fractal landscape. Brilliant idea and good for this, right? I should try multithreading rep_dla first though.

@myselfhimself, in current developpement branch of G’MIC 2.9.5, command elevation3d has been re-implemented as a custom command (rather than a native one as before).
It has a new option (second argument) to allow the generated 3D elevation to have a solid base , which is something you were looking for.

In your case, I guess that your elevation factor should be negative. Example:

$ gmic 0 text Chocolate,0,0,48,1,1 b 1 n 0,255 elevation3d -0.02,10 o output.obj

generates the following 3D mesh:

If you want to test it, let me know if you get into troubles (or not :slight_smile: ).

1 Like

This is beautiful for adding floor thickness !!! Thank you for fiddling!!!
For my target application (mold negatives or positives for chocolate and pastry 3d printing or CNC machining) colors are not very important but it can be for other people. In such an application, the simplest similar tool name is lithophane http://3dp.rocks/lithophane/ , targetted at showing a picture trough light sub surface scattering, and is a technique fancied by many makers and DIYers.
Feel free to upload or send me a .obj of your mesh somewhere so that I can check its mesh for 3d printing.
I can also send your proper heightmaps with or without vacuum forming vents and various levels of “complexity” for my target application… I feel like you are doing free development for me… :slight_smile: My apologies for being so specific in the use case I describe…

Sorry just missed that message!! Let me try that out this week thanks!!!