Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Qt3D: Create mirrored object
Forum Updated to NodeBB v4.3 + New Features

Qt3D: Create mirrored object

Scheduled Pinned Locked Moved Solved General and Desktop
qt3dqml
2 Posts 1 Posters 869 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    Jan80
    wrote on 17 Aug 2018, 09:47 last edited by
    #1

    Hi, I'm new to Qt3D and 3D programming in general, but using Qt for 6 years.

    Does anyone know a simple way to to mirror a mesh in Qt3D along the x-Axis?

    Right now I'm working on a 3D viewer (using QML) for my company. A similar viewer already exists, which was written in BabylonJS (by an external worker). So I already have the model and texture files, but the models contain only the objects from one side in the scene. The other side needs to be created by mirroring the existing models along the x axis.

    So far I have tried to use a Transform with scale3d: Qt.vector3d(-1,1,1), but now all the vertex windings are inverted. So all I'm seeing are the backfaces. See my code below.

    Entity{
        Mesh{
            id: zahnfleischMirrorMesh
            source: "file:///D:/3D_Models/Dental/Test/Zahnfleisch/zahnfleisch.obj"
        }
    
        TextureLoader{
            id: zahnfleischMirrorTexture
            source: "file:///D:/3D_Models/Dental/Test/Zahnfleisch/unterkieferFarbe.jpg"
            mirrored: true
        }
    
        DiffuseMapMaterial{
            id: zahnfleischMirrorMaterial
            diffuse: zahnfleischMirrorTexture
            ambient: Qt.rgba( 1, 1, 1, 1.0 )
            specular: Qt.rgba( 0.113561, 0.113561, 0.113561, 1.0 )
        }
    
        Transform{
            id: mirrorTransform
            scale3D: Qt.vector3d(-1,1,1)
        }
    
        components: [mirrorTransform, zahnfleischMirrorMesh, zahnfleischMirrorMaterial]
    }
    

    So far I have come up with the following ideas to solve my problem:

    1. Go to blender and mirror the models manually
      • I don't really like this option.
      • This would double the data, which will result in longer loading times and more memory usage
      • Also it's a lot of work... and the models might change in the future
    2. Try to manually reorder the vertices, obtained from the mesh's geometry
      • not sure how much work this would be or if this is the optimal solution

    Thank you in advance
    Jan

    1 Reply Last reply
    0
    • J Offline
      J Offline
      Jan80
      wrote on 20 Aug 2018, 09:49 last edited by
      #2

      Ok, solution 2 was simpler than i expected. I'll post my code below, in case someone else needs something similar. It flips a QEntity along the x-axis and the winding of the triangles. It only works with the primitive type QGeometryRenderer.Triangles.

      Jan

      void mirrorEntity(Qt3DCore::QEntity *entity)
      {
          for (QNode* node: entity->childNodes())
          {
              if (QEntity* e = dynamic_cast<QEntity*>(node))
                  mirrorEntity(e);
              if (QGeometryRenderer* r = dynamic_cast<QGeometryRenderer*>(node))
                  mirrorGeometryRenderer(r);
          }
      }
      
      void mirrorGeometryRenderer(QGeometryRenderer *geometryRenderer)
      {
          QGeometry* geometry = geometryRenderer->geometry();
          for (QAttribute* a : geometry->attributes())
          {
              if (a->name() == QAttribute::defaultPositionAttributeName())
              {
                  QByteArray data = a->buffer()->data();
      
                  // flip along x-axis
                  float *bufferContent = reinterpret_cast<float*>(data.data());
                  int chunkSize = a->byteStride()/sizeof(float);
                  int positionOffset = a->byteOffset();
                  for (uint i=0; i<a->count()*chunkSize; i+=chunkSize)
                  {
                      int offsetI = i + positionOffset;
                      bufferContent[offsetI] = -bufferContent[offsetI]; // invert x
                  }
      
                  // change winding
                  const int size = a->byteStride();
                  char* tmp = new char[size];
                  for (int i=0; i<data.length(); i+=a->byteStride()*3)
                  {
                      memcpy(tmp, &data.data()[i+size], size);
                      memcpy(&data.data()[i+size], &data.data()[i+size*2], size);
                      memcpy(&data.data()[i+size*2], tmp, size);
                  }
                  delete[] tmp;
      
                  a->buffer()->setData(data);
                  break;
              }
          }
      }
      
      
      1 Reply Last reply
      0

      1/2

      17 Aug 2018, 09:47

      • Login

      • Login or register to search.
      1 out of 2
      • First post
        1/2
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved