Suppose you have a big set of Quads (hundreds of thousands) like in the following image:
If you add individual Quad entities to the Eyeshot control you would get a very bad framerate due to the huge number of entities.
A better approach is to create a single Mesh object from the big set of Quads, this way you would gain the benefits of using hardware acceleration by creating a single display list (or vertex buffer object as shown below) for the whole set of Quads.
If you want to individually select the quad entities (in order to transform, delete, or perform some other actions on them), you should override some methods (as shown below) to allow the selection of the quads inside the mesh.
For this purpose, you should keep a list of the selected quads inside the mesh and, in order to draw them, override the Draw method so that it first draws all the quads and then draws the selected ones over it.
In the attachment there are projects with the code: these samples create a single Mesh object made of two quads and implement the selection independently for each quad.
The main part is the MyMesh class derived from Mesh, created for this purpose.
It uses the Vertex Buffer Objects (if they are available on the graphics card) to speed up the Entity.Compile() and it overrides the following methods to support the drawing of the Quads and their selection
- Compile(), Draw(), DrawSelected(),
-
IsCrossing(), InsideOrCrossingFrustum(), ThroughTriangle(), IsCrossingScreenPolygon(), InsideOrCrossingScreenPolygon(), ThroughTriangleScreenPolygon(), AllVerticesInFrustum(), AllVerticesInScreenPolygon(): to compute the quads selected by the various selection modes.
- DrawForSelection(): necessary for the Quads selection in the SelectVisiblebyPick and SelectVisibleByBox selection modes.
using devDept.Eyeshot.Control;
class MyDesign : Design
{
private bool processQuads = false;
public override void ProcessSelectionVisibleOnly(Rectangle selectionBox, bool firstOnly, bool invert,
SelectionChangedEventArgs eventArgs, bool selectableOnly = true, bool temporarySelection = false)
{
processQuads = true;
base.ProcessSelectionVisibleOnly(selectionBox, firstOnly, invert, eventArgs, selectableOnly, temporarySelection);
processQuads = false;
}
protected override int[] GetVisibleEntitiesFromBackBuffer(Viewport viewport, byte[] rgbValues, int stride, int bpp, Rectangle selectionBox,
bool firstOnly)
{
if (!processQuads)
return base.GetVisibleEntitiesFromBackBuffer(viewport, rgbValues, stride, bpp, selectionBox, firstOnly);
// Reads the visible Quads from the back buffer and selects them
for (int i = 0; i < Entities.Count; i++)
{
if (Entities[i] is MyMesh)
{
MyMesh myMesh = Entities[i] as MyMesh;
int[] indices = base.GetVisibleEntitiesFromBackBuffer(viewport, rgbValues, stride, bpp, selectionBox, firstOnly);
// Select the quads
myMesh.SelectQuads(indices);
break;
}
}
return new int[0];
}
}
Finally create the MyMesh object with the quads vertices, triangles, and normals:
private void Form1_Load(object sender, EventArgs e)
{
CreateQuadsVBO(design1);
}
private void CreateQuadsVBO(Design design)
{
List vertices = new List();
List triangles = new List();
List normals = new List();
// Create a mesh with n quads
int n = 20;
bool b = false;
for (int i = 0, countVertices = 0; i < n; i++)
for (int j = 0; j < n; j++, countVertices += 4)
{
var pt1 = new Point3D(i*2, j*2, 0);
var pt2 = new Point3D(i*2 +1.5, j *2 +1.5,0);
vertices.Add(new Point3D(pt1.X, pt1.Y, 0));
vertices.Add(new Point3D(pt2.X, pt1.Y, 0));
vertices.Add(new Point3D(pt2.X, pt2.Y, 0));
vertices.Add(new Point3D(pt1.X, pt2.Y, 0));
b = !b;
var col = b ? Color.Cyan : Color.Magenta;
triangles.Add(new ColorTriangle(countVertices, countVertices + 1, countVertices + 2, col));
triangles.Add(new ColorTriangle(countVertices, countVertices + 2, countVertices + 3, col));
Vector3D normal = Vector3D.AxisZ;
normal.Normalize();
normals.Add(normal); // Add just one normal because I'm using quads internally
}
// Create the MyMesh object and add it to the Design.
Mesh mesh = new MyMesh(design, Mesh.natureType.Plain);
mesh.Vertices = vertices.ToArray();
mesh.Triangles = triangles.ToArray();
mesh.Normals = normals.ToArray();
mesh.ColorMethod = devDept.Eyeshot.Entities.colorMethodType.byEntity;
mesh.Color = Color.White;
mesh.LightWeight = true;
design.Entities.Add(mesh);
design.ZoomFit();
}
Comments
Would I be able to use this and also be able to to selectively turn off (make invisible) some of the quads?
To turn off some of the quads you should rebuild the display list or the VBO without them (Compile method).
We remade this example for version 8.0.321.
After updating to version 8.0.367, example don't work
Whether it is possible to receive a working example for the new version?
Is there a way to force OpenGL to draw quad primitives from VBO instead of simulating quad drawing two triangles?
I want to use this feature in eyeshot 2022, but it is very diffcult to convert to project.
Please sign in to leave a comment.