src/glRenderer.cpp

changeset 1057
3c7782ec3753
parent 1056
27b7991b3bea
child 1061
273333700685
equal deleted inserted replaced
1056:27b7991b3bea 1057:3c7782ec3753
924 // ============================================================================= 924 // =============================================================================
925 // 925 //
926 void GLRenderer::pick(const QRect& range, bool additive) 926 void GLRenderer::pick(const QRect& range, bool additive)
927 { 927 {
928 makeCurrent(); 928 makeCurrent();
929 929 QSet<LDObject*> priorSelection = selectedObjects().toSet();
930 // Clear the selection if we do not wish to add to it. 930 QSet<LDObject*> newSelection;
931 if (not additive) 931
932 { 932 // If we're doing an additive selection, we start off with the existing selection.
933 LDObjectList oldSelection = selectedObjects(); 933 // Otherwise we start selecting from scratch.
934 currentDocument()->clearSelection(); 934 if (additive)
935 935 newSelection = priorSelection;
936 for (LDObject* object : oldSelection)
937 compileObject(object);
938 }
939 936
940 // Paint the picking scene 937 // Paint the picking scene
941 setPicking(true); 938 setPicking(true);
942 drawGLScene(); 939 drawGLScene();
943 940
960 pixelData.resize(4 * numpixels); 957 pixelData.resize(4 * numpixels);
961 958
962 // Read pixels from the color buffer. 959 // Read pixels from the color buffer.
963 glReadPixels(x0, m_height - y1, areawidth, areaheight, GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data()); 960 glReadPixels(x0, m_height - y1, areawidth, areaheight, GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data());
964 961
965 LDObject* unselectedObject = nullptr;
966 QSet<int32_t> indices; 962 QSet<int32_t> indices;
967 963
968 // Go through each pixel read and add them to the selection. 964 // Go through each pixel read and add them to the selection.
965 // Each pixel maps to an LDObject index injectively.
969 // Note: black is background, those indices are skipped. 966 // Note: black is background, those indices are skipped.
970 for (unsigned char *pixelCursor = pixelData.begin(); pixelCursor < pixelData.end(); pixelCursor += 4) 967 for (unsigned char *pixelCursor = pixelData.begin(); pixelCursor < pixelData.end(); pixelCursor += 4)
971 { 968 {
972 int32_t index = pixelCursor[0] * 0x10000 + 969 int32_t index = pixelCursor[0] * 0x10000 +
973 pixelCursor[1] * 0x100 + 970 pixelCursor[1] * 0x100 +
974 pixelCursor[2] * 0x1; 971 pixelCursor[2] * 0x1;
975 if (index != 0) 972 if (index != 0)
976 indices.insert(index); 973 indices.insert(index);
977 } 974 }
978 975
976 // For each index read, resolve the LDObject behind it and add it to the selection.
979 for (int32_t index : indices) 977 for (int32_t index : indices)
980 { 978 {
981 LDObject* object = LDObject::fromID (index); 979 LDObject* object = LDObject::fromID(index);
982 980
983 if (object == nullptr) 981 if (object != nullptr)
984 continue; 982 {
985 983 // If this is an additive single pick and the object is currently selected,
986 // If this is an additive single pick and the object is currently selected, 984 // we remove it from selection instead.
987 // we remove it from selection instead. 985 if (additive and newSelection.contains(object))
988 if (additive) 986 newSelection.remove(object);
989 { 987 else
990 if (object->isSelected()) 988 newSelection.insert(object);
991 { 989 }
992 object->deselect(); 990 }
993 unselectedObject = object; 991
994 break; 992 // Select all objects that we now have selected that were not selected before.
995 } 993 for (LDObject* object : newSelection - priorSelection)
996 } 994 {
997
998 object->select(); 995 object->select();
999 } 996 compileObject(object);
1000 997 }
1001 // Update everything now. 998
999 // Likewise, deselect whatever was selected that isn't anymore.
1000 for (LDObject* object : priorSelection - newSelection)
1001 {
1002 object->deselect();
1003 compileObject(object);
1004 }
1005
1002 m_window->updateSelection(); 1006 m_window->updateSelection();
1003
1004 // Recompile the objects now to update their color
1005 for (LDObject* obj : selectedObjects())
1006 compileObject (obj);
1007
1008 if (unselectedObject)
1009 compileObject(unselectedObject);
1010
1011 setPicking(false); 1007 setPicking(false);
1012 repaint(); 1008 repaint();
1013 } 1009 }
1014 1010
1015 // 1011 //

mercurial