I’m making a paint program to paint on 3D meshes using a circular brush. Because of the way I’m specifying the area to change to the brush color, I believe that the MouseMove Events are firing off quicker than the program can finish drawing, thus instead of just changing a circle to a different color, it’s overflowing and ends up painting the entire mesh.
The following gets called on mouseMove:
void Mesh::setCircle(Face *face, int radius, Color color) {
for (unsigned int i = 0; i < mouseOvers.size(); i++)
faceList[mouseOvers[i]].mouseOver = false;
mouseOvers.clear();
...
// finds the faces on the mesh around the centerIndex on the circle (just the outline of the circle)
// calls face->mouseOver = true; for each of those faces
// adds the indices of the faces to mouseOvers
}
The above is used to give the outline of the brush on the mesh so that users know what they’re about to paint. When the user clicks on the mouse button, the following is called:
void Mesh::getAdjacent(Face *face, vector<Face *> &adjacent) {
for (unsigned int i = 0; i < mouseOvers.size(); i++)
adjacent.push_back(&faceList[mouseOvers[i]]);
int currentUp = face->listIndex;
int currentDown = currentUp;
helperGetAdjacent(currentUp, adjacent);
while (!faceList[currentUp].mouseOver) {
//up
if (currentUp >= numCols) {
currentUp -= numCols;
helperGetAdjacent(currentUp, adjacent);
}
else
break;
}
while (!faceList[currentDown].mouseOver) {
//down
if (currentDown < numCols * (numRows-1)) {
currentDown += numCols;
helperGetAdjacent(currentDown, adjacent);
}
else
break;
}
}
void Mesh::helperGetAdjacent(int trunk, vector<Face *> &adjacent) {
int currentRight = trunk;
int currentLeft = trunk;
adjacent.push_back(&faceList[trunk]);
while (!faceList[currentRight].mouseOver) {
// check right
if (currentRight % numCols != numCols - 1) {
adjacent.push_back(&faceList[currentRight + 1]);
currentRight++;
}
else
break;
}
while (!faceList[currentLeft].mouseOver) {
//check left
if (currentLeft % numCols != 0) {
adjacent.push_back(&faceList[currentLeft - 1]);
currentLeft--;
}
else
break;
}
}
Short summary of the code above, I’m using the mouseOver property in the faces to determine when to stop adding faces to adjacent (which is returned and colored in another function).
Now, this works when the user just clicks on the mouse. When the user drags it while holding it down, I just call that getAdjacent function again. If the user moves the mouse slow enough, the expected behaviour (the faces get colored by the mouse like a brush), but if the user drags faster (and this isn’t really fast), the entire mesh will be colored.
My suspicion is that the mousemove event is being called in a different thread, causing the setCircle function to be called before the getAdjacent function has finished. The mouseOver member in Face changes to false and the getAdjacent doesn’t stop at the right place.
How can I remedy this problem?
Thanks very much!
Your suspicion is incorrect… Qt only uses a single thread (the main thread) for its GUI stuff. So your problem is somewhere else. It could be a bug in your code (I won’t try to debug the logic here, since I don’t think I could do a decent job of it), or it could be that Qt is combining MouseMove events when possible (to avoid an ever-lengthening queue of events if the callbacks are slow in returning), which might be not what your code expects.