Announcement

Collapse
No announcement yet.

How to retrive material in SoCallbackAction or partition (split) a 3D model separator

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to retrive material in SoCallbackAction or partition (split) a 3D model separator

    Dear Mike and Dear Forum Users,
    Please, i'd like to put two questions:

    the first is how to retrive material information in a SoCallbackAction performing triangle vertex and normal collection as in the code below showed

    Code:
    void TriangleCallbackSimple(void *userData, SoCallbackAction *action, const SoPrimitiveVertex *v1, const SoPrimitiveVertex *v2, const SoPrimitiveVertex *v3)
    {
    SoMyCustomSahepNode* pToThis = (SoMyCustomSahepNode*)userData;
    ASSERT(pToThis != NULL);
    if (pToThis == NULL) return;
    
    SbVec3f v[3] = { v1->getPoint(), v2->getPoint(), v3->getPoint() };
    
    pToThis->m_vTriangleVertex.push_back(v[0]); pToThis->m_vTriangleVertex.push_back(v[1]); pToThis->m_vTriangleVertex.push_back(v[2]);
    pToThis->m_vTriangleNormal.push_back(v1->getNormal()); pToThis->m_vTriangleNormal.push_back(v2->getNormal()); pToThis->m_vTriangleNormal.push_back(v3->getNormal());
    }
    The second question is a little bit more complicated (as to me): is it possible to perform a partition or a part splitting starting from a complex shape node?

    These questions arise from the following neccesity:
    For example i have a inverntor or VRML 3d model file containing material informations, as the image below
    Immagine 2020-11-24 111805.jpg

    i'd like to split the main model into three pieces so i can be able to call the "TriangleCallbackSimpe" and apply the different material found to the three sub-nodes
    in order to have both triangle-normal and material informations.

    I hope my trouble is well explained; please ask if my request isn't clear.

    Many thanks in advance for Your help and suggestions.

    Best Regards,

    Vincenzo

  • #2

    Hi Vincenzo,
    Originally posted by [email protected] View Post
    the first is how to retrive material information in a SoCallbackAction performing triangle vertex and normal collection as in the code below showed
    You are on the right path with getting the coordinates and normals for the triangle. The documentation does not fully explain how to get the material applied to the triangle. Answer: SoPrimitiveVertex::getMaterialIndex() provides the material index and SoCallbackAction::getMaterial() returns the color values associated with that index.
    For example, if we only care about the diffuse color (typical for mechanical parts), we could write:
    Code:
    // Return diffuse color of a primitive vertex
    static SbColor getVertexDiffuseColor(SoCallbackAction* action, const SoPrimitiveVertex* vert)
    {
      SbColor ambient, diffuse, specular, emissive;
      float shininess, transparency;
      int matIndex = vert->getMaterialIndex();
      action->getMaterial(ambient, diffuse, specular, emissive, shininess, transparency, matIndex);
      return diffuse;
    }
    
    static void triangleCB(void *userData, SoCallbackAction *action,
                                       const SoPrimitiveVertex *v1, const SoPrimitiveVertex *v2, const SoPrimitiveVertex *v3)
    {
      const SbVec3f& coord1 = v1->getPoint();
      const SbVec3f& norm1  = v1->getNormal();
      SbColor diffuse1 = getVertexDiffuseColor(action, v1);
    }
    Conveniently, this works no matter how the materials are specified in the scene graph (SoMaterial node, SoVertexProperty node, etc).

    I am not sure to understand the second question. I understand that the "part" has three sub-parts (dark-blue, light-blue and green). I think you mean that the part is defined by a single shape node in which, somehow, a different material is assigned to each sub-part. Then you want to split this shape node into three separate shape nodes, one for each sub-part, based on the material. That should be possible. For example, you could define a "NewShape" class that contains vertices, normals and an SbColor. Initialize an empty list of NewShape. For each triangle, get the diffuse color (as above) and search the list of NewShape for a shape with the same color. If found, add the triangle to that shape, else create a new shape.
    Best regards,
    Mike

    Comment


    • #3
      Dear Mike,
      thank You very much for Your explanation and suggestions.

      I'll try to follow Your suggested ways.

      Many Thanks again!

      Best Regards,
      Vincenzo

      Comment

      Working...
      X