Cannot change the classification type by polygon vertically and dynamically

Hello there,

My ultimate goal is to change the classification color on the CesiumTileset object withing the selected vertical area. Just like below but it is not changed actually:

image

I want to make it like this by selecting vertical area dynamically.
image

I know polygon entity can change the classification type of the surrounded area of CesiumTileset horizontally.
However, I do not know how to do that vertically in polygon.
Extruding the polygon sounds confusing to change dynamically?
I can think of applying the box entity or like ClassificationPrimitive.
example below:

This question here has the similar objective as mine.

Best regards,
Hiroshi

Hello Hiroshi,

I don’t believe it’s possible to use a “vertical” polygon to classify a tileset. Polygons, even if extruded, will always follow the surface of the ellipsoid. The photogrammetry example you’ve linked to is using a box classification. It just appears “vertical” because of the overhang.

Like in that other thread you link to, I would recommend using a box to classify the tileset as it is the most straightforward. Would it perhaps be possible to simplify the UI to restrict the user to boxes or ellipses? A complete list of geometries available for classification are documented here.

Thanks!
Gabby

1 Like

Hello @Gabby_Getz

I appreciate your advice.
I will try the box geometry out to classify the tileset.

Also, I couldn’t access to the url you have provided.
I assumed you have sent me something like this in the gallery?

Anyway, I will give your back the result of my trials.

Best,
Hiroshi

Hello Hiroshi,

Great!

My link was to ClassificationPrimitive - Cesium Documentation. I fixed the linked in my previous comment.

Thanks!

Thanks @Gabby_Getz

I have tried your the ClassificationPrimitives and I was able to classify the point cloud with adding a color.

However, there are two issues I am facing, may I ask an advice?

  1. I also wanted to show the geometry visually so I added a appearance object then it gave me an error which does not make sense for me.
DeveloperError: Materials on ClassificationPrimitives are not supported except via GroundPrimitives
Error
    at new DeveloperError (https://sandcastle.cesium.com/CesiumUnminified/Cesium.js:7971:13)
    at ClassificationPrimitive.update (https://sandcastle.cesium.com/CesiumUnminified/Cesium.js:72004:15)
    at PrimitiveCollection.update (https://sandcastle.cesium.com/CesiumUnminified/Cesium.js:136305:21)
    at updateAndRenderPrimitives (https://sandcastle.cesium.com/CesiumUnminified/Cesium.js:197792:23)
    at executeCommandsInViewport (https://sandcastle.cesium.com/CesiumUnminified/Cesium.js:197644:5)
    at Scene4.updateAndExecuteCommands (https://sandcastle.cesium.com/CesiumUnminified/Cesium.js:197462:7)
    at render (https://sandcastle.cesium.com/CesiumUnminified/Cesium.js:198098:11)
    at tryAndCatchError (https://sandcastle.cesium.com/CesiumUnminified/Cesium.js:198112:7)
    at Scene4.render (https://sandcastle.cesium.com/CesiumUnminified/Cesium.js:198164:7)
    at CesiumWidget.render (https://sandcastle.cesium.com/CesiumUnminified/Cesium.js:208761:19)
  1. I want to align the classifier box in parallel with the plane but what kind of modelMatrix should I give to the ClassificationPrimitive.
    I might be able to do the math on my hand but it will take time and I don’t know the Cesium library well yet so I would like to ask for your support.

Thanks a lot!

Best,
Hiroshi

Hi @Marco13
I have a mathematical issue at my second question.
I was hoping if you could also give me some suggestion for it as well.
Thanks.

I had a short look at the sandcastle, but am not sure what the question is.

For the error regarding the Material: Omitting the appearance from the classification primitive avoids the error, but I don’t know what this part of the code is supposed to accomplish. I assume that you wanted to visualize the classification volume in some way.

For the “mathematical” question: In the sandcastle, something should happen. It is possible to click something. After some clicks, something happens. What happens there involves a modelMatrix. And … the question seems to indicate that the model matrix is wrong, or more specifically: What this model matrix is supposed to look like to make sure that the thing that does happen is the thing that should happen. This is not a question that can sensibly be answered.


An aside: People generally appreciate it when questions have an associated sandcastle. A sandcastle allows to quickly understand the core of the question. But this only works when the sandcastle is on point, and makes clear what the question is.

In the following Sandcastle, I removed everything from your sandcastle of which I thought that it might not be relevant (and tried to clean up the remaining part). You can click at two points on the plane. This creates a classification primitive, and a primitive for visualizing the classification volume. If there are more specific questions (e.g. regarding the model matrix), maybe they can be discussed based on this sandcastle.

1 Like

Thanks @Marco13
the sandcastle made my understanding more clear.

I guess my question is:
How do I create a side of box(both class primitive and entity for visualization) that always align in parallel with the plane?

So in your sandcastle, you create your plane here but I want this to be more dynamic.

const planePosition = new Cesium.Cartesian3(
  4401701.62273646,
  224990.69903236366,
  4595444.281601433
);
const plane = new Cesium.Plane(Cesium.Cartesian3.UNIT_Y, 0);

Given that, I want to change Cesium.Cartesian3.UNIT_Y to cameraVectorNegate in the code below for example.

lineVector = Cesium.Cartesian3.subtract(positions[1], positions[0], new Cesium.Cartesian3());
                            Cesium.Cartesian3.normalize(lineVector, lineVector);

  midPosition = Cesium.Cartesian3.midpoint(positions[0], positions[1], new Cesium.Cartesian3());

  ellipsoidNormal = Cesium.Ellipsoid.WGS84.geodeticSurfaceNormal(midPosition, new Cesium.Cartesian3());
  Cesium.Cartesian3.normalize(ellipsoidNormal, ellipsoidNormal);
  let cameraVector = Cesium.Cartesian3.cross(ellipsoidNormal, lineVector, new Cesium.Cartesian3());
  Cesium.Cartesian3.normalize(cameraVector, cameraVector);
  // let cameraPosition = Cesium.Matrix4.getTranslation(matrix, new Cesium.Cartesian3());
  const scalarOffset = Cesium.Cartesian3.multiplyByScalar(cameraVector, 50, new Cesium.Cartesian3());
  const cameraPosition = Cesium.Cartesian3.add(midPosition, scalarOffset, new Cesium.Cartesian3());
  const cameraVectorNegate = Cesium.Cartesian3.negate(cameraVector, new Cesium.Cartesian3());

What happen to my code in my work looks like is this.
I guess I need to do something with the modelMatrix of the box.

In order to align the box with the plane, you can rotate the box. And you can achieve this by modifying the modelMatrix.

One approach for that could be to multiply the modelMatrix with a matrix that describes a rotation that aligns the Y-axis with the plane normal. This is sketched in the computeAlignmentRotation function in this sandcastle:

But note: At some point, you might have to think about the input. I can imagine that the next question will be: “I also want the box to be aligned in […some particular way of aligning the box…]”, and it might be that for certain alignments, just “clicking two points on the plane” may not be enough.

But I think that the computeAlignmentRotation function is versatile, in this regard: Whatever alignment you want to achieve, it should be possible to compute it with this function.

(With a disclaimer: The function does not do any error handling. When you want to use it to compute alignment for two parallel vectors, the result will be undefined. You’ll have to add the appropriate checks before calling it…)

1 Like

Thank you @Marco13
Your advise has been very helpful