Issue with Applying Face and Line Colors to Custom Polygon Mesh in HOOPS Communicator

Hello TechSoft3D,

I’ve created a polygon mesh by manually defining six individual face meshes. I’m trying to apply both face and edge (line) colors using the APIs in below code snippet. However, neither the face colors nor the line colors are getting applied.

What could be the possible reasons for the colors not being applied? Also, what is the correct way to apply face and edge colors to custom meshes in HOOPS Communicator?

export const createBoxWithParent: CreateBoxWithParent = async (
position,
width,
height,
depth,
faceColor,
hwv,
parentId,
resizedNodeId,
) => {
let parentNodeId = resizedNodeId
? hwv.model.createNode(parentId, hwv.model.getNodeName(resizedNodeId)!)
: hwv.model.createNode(parentId, box-${globalBoxCounter++});

for (let face = 0; face < 6; face++) {
const meshData = createBoxFaceMeshData(position, width, height, depth, face);
meshData.setBackfacesEnabled(true);
const meshId = await hwv.model.createMesh(meshData);

const meshInstanceData = new MeshInstanceData(meshId, new Matrix(), `face-${face}`, faceColor);
meshInstanceData.setFaceColor(faceColor)
meshInstanceData.setLineColor(faceColor)
meshInstanceData.setOpacity(0.4);

await hwv.model.createMeshInstance(meshInstanceData, parentNodeId);

}

return parentNodeId;
};

const boundingBoxNodeId = await createBoxWithParent(
  corner,
  width,
  height,
  depth,
  Color.createFromFloat(1, 0, 0),
  hwv,
  folderNodeId,
);

Hello @cad-developer,

It does not look like you are creating a MeshData object, that is:

const meshData = new Communicator.MeshData();

Please see the topic of Meshes in our docs which provides an example.

Thanks,
Tino

I forgot to paste here below function where I created meshData.

// Create the face mesh data for one side of a box
export const createBoxFaceMeshData: CreateBoxFaceMeshData = (pos, width, height, depth, face) => {
const p0 = new Point3(pos.x, pos.y, pos.z);
const p1 = new Point3(pos.x + width, pos.y, pos.z);
const p2 = new Point3(pos.x + width, pos.y + height, pos.z);
const p3 = new Point3(pos.x, pos.y + height, pos.z);
const p4 = new Point3(pos.x, pos.y + height, pos.z + depth);
const p5 = new Point3(pos.x + width, pos.y + height, pos.z + depth);
const p6 = new Point3(pos.x + width, pos.y, pos.z + depth);
const p7 = new Point3(pos.x, pos.y, pos.z + depth);

let triangles: Point3 = ;

switch (face) {
case 0:
triangles = [p0, p2, p1, p0, p3, p2];
break; // Front
case 1:
triangles = [p2, p3, p4, p2, p4, p5];
break; // Top
case 2:
triangles = [p1, p2, p5, p1, p5, p6];
break; // Right
case 3:
triangles = [p0, p7, p4, p0, p4, p3];
break; // Left
case 4:
triangles = [p5, p4, p7, p5, p7, p6];
break; // Back
case 5:
triangles = [p0, p6, p7, p0, p1, p6];
break; // Bottom
default:
throw new Error(‘Invalid face number.’);
}

const positions: number = ;
triangles.forEach((point) => positions.push(point.x, point.y, point.z));
const uvs: number = new Array(triangles.length * 2).fill(0);
const normals: number = new Array(triangles.length * 3).fill(0);

const meshData = new MeshData();
meshData.addFaces(positions, normals, undefined, uvs);
meshData.setFaceWinding(FaceWinding.CounterClockwise);
return meshData;
};

As a quick suggestion, instead of:

meshData.setFaceWinding(FaceWinding.CounterClockwise);

Can you try:

meshData.setFaceWinding(FaceWinding.Clockwise);

I made the change you suggested but Its still not working.

What color is always being rendered in the Web Viewer? Is it always black? Color is rangebound from 0 to 255. It looks like you are using normalized values from 0 to 1. So in your function:

const boundingBoxNodeId = await createBoxWithParent(
  corner,
  width,
  height,
  depth,
  Color.createFromFloat(1, 0, 0),
  hwv,
  folderNodeId,
);

…the color is basically black. You can try Color.createFromFloat(255, 0, 0) to make it red.

I tried this and other colors too, but it’s not working — no matter what value I set, it always displays black.

Let’s try the following:

  • Open the developer console in the web browser
  • Paste the following in the console (you may have to change the hwv alias for the Web Viewer):
hwv.setCallbacks({
  selectionArray: async function (selections) {
    if (selections.length > 0) {
      for (const selectionEvent of selections) {
        let selection = selectionEvent.getSelection();
        let nodeid = selection.getNodeId();
        let face = selection.getFaceEntity().getCadFaceIndex();
        let color = await hwv.model.getNodeEffectiveFaceColor(nodeid, face);
        let md = await hwv.model.getNodeMeshData(nodeid);

        console.log("Selected Node: " + nodeid);
        console.log("Face ID: " + face);
        console.log("Color: " + JSON.stringify(color));
        console.log("meshData: " + JSON.stringify(md));
      }
    }
  },
});
  • Select a face on the model
  • Deselect such that no face is no longer highlighted
  • Do a screenshot and post it in your next reply

This is what I get in console…

Thanks for screenshot. Can you also provide the actual rendering in the Web Viewer?

For Red color

Can you provide a screenshot of the actual rendering of the black faces as shown in the Web Viewer?

meshInstanceData.setOpacity(0.4);

this is working as you can see in screenshots.

Let’s try removing the opacity or set it to 1.0. And also set the red value back to 255 instead of 65025. Now with these changes, the cube is rendered black. Does the color change when rotating the camera?

const boundingBoxNodeId = await createBoxWithParent(
  corner,
  width,
  height,
  depth,
  Color.createFromFloat(255, 0, 0),
  hwv,
  folderNodeId,
);

When I set color 255 as above but in conosle it is giving 65025. I set Opacity to 1.0 and now it gives black color. On moving the camera it is still black.

const boundingBoxNodeId = await createBoxWithParent(
  corner,
  width,
  height,
  depth,
  Color.createFromFloat(1, 0, 0),
  hwv,
  folderNodeId,
);

When I set 1 as above it is giving 255 in console.

The face normals array you are passing to the MeshData object is a bit wonky given that it’s just an array of zeroes.

Please try passing normals similar to this:

const faceNormals = [
    [0, 0, -1], // Front
    [0, 1, 0],  // Top
    [1, 0, 0],  // Right
    [-1, 0, 0], // Left
    [0, 0, 1],  // Back
    [0, -1, 0], // Bottom
  ];

  const normal = faceNormals[face];
  const normals = [];
  for (let i = 0; i < 6; i++) {
    normals.push(...normal);
  }

While not a required parameter for addFaces(), your uvs array is also just zeroes. Please see an example of passing uvs in our docs.

I added the normals and uvs properly now its working. Thanks!

1 Like