Box/Lasso selection
#2
Your question was a little bit more complicated so I needed to find some more free time to answer it.

I have created a sample that demonstrates how to render object ids to a bitmap.

To test the sample, add the attached two files to the DXEngine samples project into the DXEngineAdvanced folder.
Then open the samples.xml file (on the root) and add the following line under the DXEngineAdvanced section:
<Sample Page="DXEngineAdvanced/ObjectIdRendering.xaml" Title="ObjectId rendering" Description=""/>

Start the samples.

The sample is using a custom rendering step that renders each object with a SolidColorEffect where the color is set from the object index. This way you can get the rendered object back from the color - see the comment in the same for more info.


Instead of using objects id map, you could also convert all 3D positions into 2D positions with Camera.Point3DTo2D method. When you have all positions in 2D space, then it is much easier to solve the problem of determining which positions are inside the lasso or box region. Note that you would need to calculate the 2D positions only after the camera is changed; and if you have your meshes prepared in such a way (Frozen, or have copies of positions), then you could do that in a background thread while the user is drawing the lasso.

Instead of using SolidColorEffect, you could also use some other custom shader defined by you - see the advanced section of the DXEngine samples for more samples on how to do that (for example the CustomShaderMaterialSample).


To detect if mesh is partially on a side of a plane, I would first do a BoundingBox / Plane intersection test (Ab3d.Utilities.Plane.GetIntersectionType method). If this returns PlaneIntersectionType.Spanning, then you would need to go through all positions of the mesh and check if some points are in front of the plane and some are behind - you can use the Plane.GetDistance method (positive value: position is in front of the plane; negative: back; zero: on the plane).

To speed up things you can inline the GetDistance method:
Code:
       /// <summary>
       /// Returns signed distance of the specified position from this Plane.
       /// If distance is positive, then position is in front of the plane (determined by the direction of the plane's normal).
       /// If distance is negative, then position is behind the plane.
       /// If distance is zero, then position lies on the plane.
       /// </summary>
       /// <param name="position">position as Point3D</param>
       /// <returns>signed distance of the specified position from this Plane</returns>
       public double GetDistance(Point3D position)
       {
           //return Vector3D.DotProduct(Normal, position) + d; // this cannot be used because Vector3D.DotProduct takes only two Vector3D parameters
           return A * position.X + B * position.Y + C * position.Z + D;
       }
EDITED:
After some additional checks I have found out that the GetObjectIdColor4 method in the attached ObjectIdRendering.xaml.cs file was not correct. The method did not correctly transformed the renderingQueueIndex into Color. This has been fixed.
I have also added a method that converts the Color4 back into the renderingQueueIndex and objectIndex.


Attached Files
.xaml   ObjectIdRendering.xaml (Size: 2.92 KB / Downloads: 3)
.cs   ObjectIdRendering.xaml.cs (Size: 11.49 KB / Downloads: 0)
Andrej Benedik
  


Messages In This Thread
Box/Lasso selection - by janovrom - 03-05-2020, 10:38 AM
RE: Box/Lasso selection - by abenedik - 03-09-2020, 04:51 PM
RE: Box/Lasso selection - by janovrom - 03-17-2020, 11:22 AM
RE: Box/Lasso selection - by abenedik - 03-17-2020, 02:09 PM

Forum Jump:


Users browsing this thread:
1 Guest(s)