Can Ogre be used to build a 3d printing simulator

Problems building or running the engine, queries about how to use features etc.
Post Reply
User avatar
JasperR
Gnoblar
Posts: 5
Joined: Thu Jun 17, 2021 4:33 pm

Can Ogre be used to build a 3d printing simulator

Post by JasperR »

Ogre Version: :?: 1.12.11
Operating System: :?: Mac Os 11.2.1 (20D74)
Render System: :?: Mac OS X OpenGL Subsystem

Code: Select all

Ogre.log (optional)
I am trying to build a simulator for a 3d printer using Ogre. The task at a high level is: given a list of direction vectors in 3d space (which will change depending on the object being built), move the nozzle mesh along the path, and create material (no shadows or anything fancy necessary) along the path so that it looks like the printer is printing. The material does not need to move once it has been placed.

I used this https://wiki.ogre3d.org/Intermediate+Tutorial+1 Tutorial to work out smooth movement of the printer, but I am struggling to create the material for each frame without slowing down the application a lot. I have been experimenting with the Manul object class (using indices) trying to create a cube mesh and just lay down cubes at the location of the nozzle for each frame but the simulation can be well over 5000 frames before it finishes and so this strategy is likely not going to work. While researching I found out about static geometry and the Ogre Procedural library, but am unsure if these could be used to solve my problem. Is Ogre capable of accomplishing a task like this smoothly and am I on the right track? Are there better strategies than creating a new mesh for each frame? I am very new to Ogre and Computer Graphis so please forgive me if I am leaving import information out I would be happy to add it to this post if necessary.

Ogre is awesome, really hope I can continue to use it in my project!
Thank you in advance!
User avatar
sercero
Bronze Sponsor
Bronze Sponsor
Posts: 449
Joined: Sun Jan 18, 2015 4:20 pm
Location: Buenos Aires, Argentina
x 155

Re: Can Ogre be used to build a 3d printing simulator

Post by sercero »

Can you give a better description of what you are doing?

Do you have screenshots?

Are you using always the same material or different ones?
The more materials you use the less performant any engine is going to get (due to draw calls).

If you have enabled SDK Trays check the number of batches in the performance panel, with more batches the performance is reduced more.

Also, besides static geometry check this out: viewtopic.php?t=59902 (instancing).

Static geometry might not be the best fit for your case.
User avatar
JasperR
Gnoblar
Posts: 5
Joined: Thu Jun 17, 2021 4:33 pm

Re: Can Ogre be used to build a 3d printing simulator

Post by JasperR »

Thank you for your quick response!
Can you give a better description of what you are doing? Do you have screenshots?
Sure I can try. I am trying to create an animation showing how a 3d printer would create an object layer by layer.


Image

Above is an image of the 1st layer.

Image

Above is an image of layer 3 or 4. In this example, the printer is creating a rectangular structure with curved edges.
Are you using always the same material or different ones?
At this time I am always using the same material which just colors the cube grey:

Code: Select all

material MyMaterial1
{
    technique
    {
        pass
        {
            texture_unit
            {
                colour_op_ex source1 src_manual src_current 0.52 0.52 0.48
            }
        }
    }
}
If you have enabled SDK Trays check the number of batches in the performance panel
I don't have SDK Trays set up but I can look into that and update the post later if that would be helpful.

Currently, I am creating this animation by placing a grey cube under the nozzle each frame.
I create the cube using the manual object class in a setup method and convert the manual object to a mesh:

Code: Select all

Ogre::ManualObject* manual = mSceneMgr->createManualObject("Cube");
    manual->begin("MyMaterial1", Ogre::RenderOperation::OT_TRIANGLE_LIST);

    Ogre::Real len = 1;
    Ogre::Real z = len;

    // Define first 4 points that we will use as the first 4 vertices of the cube
    Ogre::Vector3 topLeft(-len/2, len, z);
    Ogre::Vector3 topRight(len/2, len, z);
    Ogre::Vector3 botRight(len/2, 0.0, z);
    Ogre::Vector3 botLeft(-len/2, 0.0, z);

    // Create first 4 vertexes, which make a plane at z = 0.
    manual->position(topLeft);
    manual->position(topRight);
    manual->position(botRight);
    manual->position(botLeft);

    z = 0;
    topLeft = Ogre::Vector3(-len/2, len, z);
    topRight = Ogre::Vector3(len/2, len, z);
    botRight = Ogre::Vector3(len/2, 0.0, z);
    botLeft = Ogre::Vector3(-len/2, 0.0, z);

    // Create last 4 vertexes, a copy of the first 4 but now at z = len.
    manual->position(topLeft);
    manual->position(topRight);
    manual->position(botRight);
    manual->position(botLeft);

    // Create the 5 faces we need to make the cube
    // front
    manual->quad(0, 3, 2, 1);
    // back
    manual->quad(4, 5, 6, 7);
    // top
    manual->quad(4, 0, 1, 5);
    // right side
    manual->quad(1, 2, 6, 5);
    // left side
    manual->quad(0, 4, 7, 3);

    manual->end();
    manual->convertToMesh("Cube");
Then each frame I get the position of the nozzle of the printer and place one of these cubes under it with this code:

Code: Select all

virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt) {
	SceneNode* cartNode = mSceneMgr->getSceneNode("cart_node");
	
	// Grab the position of the cart in Ogre coordinates.
      cartPositionOgre = cartNode->convertLocalToWorldPosition(Ogre::Vector3(0, 0, 0));
      //  Translate into World_Node coordinates.
      cartPositionWorld = Ogre::Vector3(cartPositionOgre.x, -cartPositionOgre.z, cartPositionOgre.y);
      
      // Create a block under the nozzle
      Ogre::Entity * ent = mSceneMgr->createEntity("Cube");
      Ogre::SceneNode* node = mSceneMgr->getSceneNode("world_node")->createChildSceneNode(cartPositionWorld);
      node->attachObject(ent);
      node->translate(-5.497, 7.05, -47.654 + amt, Ogre::Node::TS_PARENT);
}
On top of the performance issues, the other flaw in this strategy is that if the frame rate drops low enough there will be visible gaps in the structure, like this:

Image

I know there must be a better way to do this, one thing I am currently trying is to use manualObject::beginUpdate to extend the Cube mesh each frame but I am not sure if this will impact performance when I finish (It will stop the gap problem at least).

Hopefully, now you have a better idea of what I am trying to do (sorry for the long post). If you have any ideas/suggestions/direction on a better way to do this, or if OGRE is simply not suited for this task please let me know!

Things I am considering: manualObject::beginUpdate, OgreProcedural::Extrudehttps://wiki.ogre3d.org/Ogre+Procedural ... ry+Library, maybe some kind of animation?

Again, thank you for the help!
User avatar
sercero
Bronze Sponsor
Bronze Sponsor
Posts: 449
Joined: Sun Jan 18, 2015 4:20 pm
Location: Buenos Aires, Argentina
x 155

Re: Can Ogre be used to build a 3d printing simulator

Post by sercero »

If you don't want to use the SDK Trays here is how to get the Framestats:

Code: Select all

    Ogre::RenderTarget::FrameStats frameStats = mWindow->getStatistics();

    unsigned short precision = 4;
    mFPS->setCaption(Ogre::StringConverter::toString(frameStats.lastFPS, precision));
    mAverageFPS->setCaption(Ogre::StringConverter::toString(frameStats.avgFPS, precision));
    mBestFPS->setCaption(Ogre::StringConverter::toString(frameStats.bestFPS, precision));
    mWorstFPS->setCaption(Ogre::StringConverter::toString(frameStats.worstFPS, precision));
    mTriangles->setCaption(Ogre::StringConverter::toString(frameStats.triangleCount));
    mBatches->setCaption(Ogre::StringConverter::toString(frameStats.batchCount));
You can use some GUI system (I use MyGUI) to show the stats they are very useful, because you don't know yet what is causing the slowdown.

Regarding the cubes that you are creating, did you check the solutions I proposed?

Static Geometry or Instancing?
paroj
OGRE Team Member
OGRE Team Member
Posts: 1993
Joined: Sun Mar 30, 2014 2:51 pm
x 1073
Contact:

Re: Can Ogre be used to build a 3d printing simulator

Post by paroj »

JasperR wrote: Mon Jun 21, 2021 10:57 pm On top of the performance issues, the other flaw in this strategy is that if the frame rate drops low enough there will be visible gaps in the structure, like this:
there is "evt.timeSinceLastFrame" - use it to compute where to place the cubes.

As for the performance issues: you should create all the cubes at once and only change how many of them are drawn based on the elapsed time.

The fastest way would be to override indexCount:
https://ogrecave.github.io/ogre/api/lat ... 5532dd89c5

However, ManualObject wont give you that. You will have to create the index buffer yourself instead:
https://ogrecave.github.io/ogre/api/lat ... ation.html
User avatar
JasperR
Gnoblar
Posts: 5
Joined: Thu Jun 17, 2021 4:33 pm

Re: Can Ogre be used to build a 3d printing simulator

Post by JasperR »

If you don't want to use the SDK Trays here is how to get the Framestats:
Great, thank you, I integrated these into my GUI, looks like you were right the batch count steadily increases as the cubes are placed so I am guessing this is a big part of why my frame rate also steadily decreases down to as low as 4FPS as more cubes are placed in the scene but increase back to ~50-60 FPS if I turn the camera away from the cubes and look at the sky where no cubes are in view of the camera.

Here are some screenshots:
Image

Image

Image

Image
did you check the solutions I proposed?
Not yet but I plan to soon (The above screenshots are not using static Geometry or instancing, just regular Entities and Scene Node) and I will let you know if that fixes the problem, if this does not work then I think I am going to attempt paroj's advice and try to render all the cubes before the main loop and then somehow dynamically decide which cubes to show as the Nozzle passes over them.

Again thank you for taking the time to help me out!
User avatar
JasperR
Gnoblar
Posts: 5
Joined: Thu Jun 17, 2021 4:33 pm

Re: Can Ogre be used to build a 3d printing simulator

Post by JasperR »

paroj wrote: Wed Jun 23, 2021 2:34 pm
JasperR wrote: Mon Jun 21, 2021 10:57 pm On top of the performance issues, the other flaw in this strategy is that if the frame rate drops low enough there will be visible gaps in the structure, like this:
there is "evt.timeSinceLastFrame" - use it to compute where to place the cubes.

As for the performance issues: you should create all the cubes at once and only change how many of them are drawn based on the elapsed time.

The fastest way would be to override indexCount:
https://ogrecave.github.io/ogre/api/lat ... 5532dd89c5

However, ManualObject wont give you that. You will have to create the index buffer yourself instead:
https://ogrecave.github.io/ogre/api/lat ... ation.html
I like this idea a lot, thank you! Do you know of any examples (aside from the second link you posted) where indexCount is used with vertex and index buffers to accomplish something similar to this? I have never used these before and the more examples I can see the better! If not, no worries I really appreciate the help!

Thank you both for the advice!!
User avatar
JasperR
Gnoblar
Posts: 5
Joined: Thu Jun 17, 2021 4:33 pm

Re: Can Ogre be used to build a 3d printing simulator

Post by JasperR »

Sorry for the delayed update!
@sercero I looked into instancing and from what I found here: https://ogrecave.github.io/ogre-next/ap ... ncing.html HW Basic might be useful "HW Basic doesn't support skeletal animations at all, making it the preferred choice for rendering inanimate objects like trees, falling leaves, buildings, etc." - This sounds like it's on the right track although it's a little advanced for me (I don't have any experience with shaders and I think that knowledge is necessary to get this working) and I could not find any examples aside form HWInstancing.material but after reading this file I am still not sure how to use HW basic instancing for my task.

Thus I started out by messing around with Static Geometry. For my first attempt, I just replaced the scene node with a static geometry object that I rebuilt each frame to see if that would have any impact.

Code: Select all

virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt) {
	SceneNode* cartNode = mSceneMgr->getSceneNode("cart_node");
	
	// Grab the position of the cart in Ogre coordinates.
      cartPositionOgre = cartNode->convertLocalToWorldPosition(Ogre::Vector3(0, 0, 0));
      //  Translate into World_Node coordinates.
      cartPositionWorld = Ogre::Vector3(cartPositionOgre.x, -cartPositionOgre.z, cartPositionOgre.y);
      
      // Create a block under the nozzle
      Ogre::Entity * ent = mSceneMgr->createEntity("Cube");
      staticGeometry->addEntity(ent, cartPositionOgre + Vector3(xAmt, yAmt, zAmt));
      staticGeometry->build();
}
Here, staticGeometry is a (staticGeometry *) which is a member variable of the class that overrides frameRenderingQueued.

Batch size seems to have gone down but the frame rate still drops over time as more cubes are added to the scene:

Image

Image

So next, instead of dynamically creating these cubes each frame in frameRenderingQueued I created a fixed number of cubes (8,000) in my setup method and built the staticGeometry object once before the main rendering loop.

Code: Select all

  void setupContent(void) {
  int amt = 50;
  
  for(int i=0; i<amt; i++)
      for(int j=0; j<amt; j++)
        for(int k=0; k<amt; k++) {
          Ogre::Entity * ent = mSceneMgr->createEntity("Cube");
          staticGeometry->addEntity(ent, cartPositionOgre + Ogre::Vector3(i*2, j*2,k*2));
        }

    staticGeometry->build();
  }
With the previous code, the frame rate would drop to around 15FPS with around 640k triangles. But when the static geometry is built only once in the setup method, I can render almost 2million triangles with a constant 60 FPS like in the picture below.

Image

This gives me hope that paroj's idea, rendering all the cubes upfront might work. Is there a way to do this with StaticGemoetry and maybe something like Entity.setVisable instead of using (index buffer and index count)? I think that would be a little less difficult for me.

Thanks again, you guys have been very helpful and given some great insight!
User avatar
sercero
Bronze Sponsor
Bronze Sponsor
Posts: 449
Joined: Sun Jan 18, 2015 4:20 pm
Location: Buenos Aires, Argentina
x 155

Re: Can Ogre be used to build a 3d printing simulator

Post by sercero »

Hello,

From what you just said it seems that Instancing might be the best fit for you because you can control each entity separately because they are attached to nodes so you can set the visibility. Although with instancing you should not be required to create them beforehand so that might not be necessary.

You don't have to know about shaders to use instancing because OGRE has the RTSS (Realtime Shader System) and @paroj has done a lot of work to add features to that system. It generates the shaders you need automatically.

Check this material file: ogre\Samples\Media\materials\scripts\HWInstancing.material

And here to know more about the RTSS: https://ogrecave.github.io/ogre/api/1.1 ... ation.html
Post Reply