@@ -61,7 +61,8 @@ edgeColor( uniquePrefix() + "edgeColor", glm::vec3{0., 0., 0.
6161edgeWidth ( uniquePrefix() + "edgeWidth", 0.),
6262backFacePolicy( uniquePrefix() + "backFacePolicy", BackFacePolicy::Different),
6363backFaceColor( uniquePrefix() + "backFaceColor", glm::vec3(1 .f - surfaceColor.get().r, 1.f - surfaceColor.get().g, 1.f - surfaceColor.get().b)),
64- shadeStyle( uniquePrefix() + "shadeStyle", MeshShadeStyle::Flat)
64+ shadeStyle( uniquePrefix() + "shadeStyle", MeshShadeStyle::Flat),
65+ selectionMode( uniquePrefix() + "selectionMode", MeshSelectionMode::Auto)
6566
6667// clang-format on
6768{}
@@ -734,8 +735,7 @@ void SurfaceMesh::draw() {
734735 if (program == nullptr ) {
735736 prepare ();
736737
737- // do this now to reduce lag when picking later, etc
738- // FIXME
738+ // do this now to reduce lag when picking later
739739 // preparePick();
740740 }
741741
@@ -792,6 +792,22 @@ void SurfaceMesh::drawPick() {
792792 // Set uniforms
793793 setStructureUniforms (*pickProgram);
794794
795+ if (usingSimplePick) {
796+ float radVal;
797+ switch (selectionMode.get ()) {
798+ case MeshSelectionMode::Auto:
799+ radVal = 0.2 ;
800+ break ;
801+ case MeshSelectionMode::VerticesOnly:
802+ radVal = 1 .;
803+ break ;
804+ case MeshSelectionMode::FacesOnly:
805+ radVal = 0 .;
806+ break ;
807+ }
808+ pickProgram->setUniform (" u_vertPickRadius" , radVal);
809+ }
810+
795811 pickProgram->draw ();
796812
797813 render::engine->setBackfaceCull (); // return to default setting
@@ -813,10 +829,19 @@ void SurfaceMesh::prepare() {
813829
814830void SurfaceMesh::preparePick () {
815831
832+ switch (selectionMode.get ()) {
833+ case MeshSelectionMode::Auto:
834+ usingSimplePick = !(edgesHaveBeenUsed || halfedgesHaveBeenUsed || cornersHaveBeenUsed);
835+ break ;
836+ case MeshSelectionMode::VerticesOnly:
837+ usingSimplePick = true ;
838+ break ;
839+ case MeshSelectionMode::FacesOnly:
840+ usingSimplePick = true ;
841+ break ;
842+ }
816843
817- bool simplePick = !(edgesHaveBeenUsed || halfedgesHaveBeenUsed || cornersHaveBeenUsed);
818-
819- if (simplePick) {
844+ if (usingSimplePick) {
820845 pickProgram =
821846 render::engine->requestShader (" MESH" , addSurfaceMeshRules ({" MESH_PROPAGATE_PICK_SIMPLE" }, true , false ),
822847 render::ShaderReplacementDefaults::Pick);
@@ -870,7 +895,6 @@ void SurfaceMesh::setMeshPickAttributes(render::ShaderProgram& p) {
870895 // CPU-side processing. Maybe the solution is to directly render ints?
871896
872897 // make sure we have the relevant indexing data
873- bool simplePick = !(edgesHaveBeenUsed || halfedgesHaveBeenUsed || cornersHaveBeenUsed);
874898 triangleVertexInds.ensureHostBufferPopulated ();
875899 triangleFaceInds.ensureHostBufferPopulated ();
876900 if (edgesHaveBeenUsed) triangleAllEdgeInds.ensureHostBufferPopulated ();
@@ -905,7 +929,7 @@ void SurfaceMesh::setMeshPickAttributes(render::ShaderProgram& p) {
905929 // Reserve space
906930 vertexColors.reserve (3 * nFacesTriangulation ());
907931 faceColor.reserve (3 * nFacesTriangulation ());
908- if (!simplePick ) {
932+ if (!usingSimplePick ) {
909933 halfedgeColors.reserve (3 * nFacesTriangulation ());
910934 cornerColors.reserve (3 * nFacesTriangulation ());
911935 }
@@ -936,7 +960,7 @@ void SurfaceMesh::setMeshPickAttributes(render::ShaderProgram& p) {
936960 }
937961
938962 // Second half does halfedges/edges/corners, not used for simple mode
939- if (simplePick ) {
963+ if (usingSimplePick ) {
940964 iFTri++;
941965 continue ;
942966 }
@@ -948,42 +972,45 @@ void SurfaceMesh::setMeshPickAttributes(render::ShaderProgram& p) {
948972
949973 // == Build edge index data, if needed
950974
975+ if (!usingSimplePick) {
976+ if (edgesHaveBeenUsed || halfedgesHaveBeenUsed) {
951977
952- if (edgesHaveBeenUsed || halfedgesHaveBeenUsed) {
953-
954- const std::vector<uint32_t >& eDataVec =
955- (edgesHaveBeenUsed && !halfedgesHaveBeenUsed) ? triangleAllEdgeInds.data : triangleAllHalfedgeInds.data ;
956- size_t offset =
957- (edgesHaveBeenUsed && !halfedgesHaveBeenUsed) ? edgeGlobalPickIndStart : halfedgeGlobalPickIndStart;
978+ const std::vector<uint32_t >& eDataVec =
979+ (edgesHaveBeenUsed && !halfedgesHaveBeenUsed) ? triangleAllEdgeInds.data : triangleAllHalfedgeInds.data ;
980+ size_t offset =
981+ (edgesHaveBeenUsed && !halfedgesHaveBeenUsed) ? edgeGlobalPickIndStart : halfedgeGlobalPickIndStart;
958982
959- // clang-format off
983+ // clang-format off
960984 std::array<glm::vec3, 3 > eColor = {
961985 fColor ,
962986 pick::indToVec (eDataVec[9 *iFTri + 1 ] + offset),
963987 fColor
964988 };
965- // clang-format on
966- if (j == 1 ) eColor[0 ] = pick::indToVec (eDataVec[9 * iFTri + 0 ] + offset);
967- if (j + 2 == D) eColor[2 ] = pick::indToVec (eDataVec[9 * iFTri + 2 ] + offset);
989+ // clang-format on
990+ if (j == 1 ) eColor[0 ] = pick::indToVec (eDataVec[9 * iFTri + 0 ] + offset);
991+ if (j + 2 == D) eColor[2 ] = pick::indToVec (eDataVec[9 * iFTri + 2 ] + offset);
968992
969- for (int j = 0 ; j < 3 ; j++) halfedgeColors.push_back (eColor);
970- } else {
971- for (int j = 0 ; j < 3 ; j++) halfedgeColors.push_back ({fColor , fColor , fColor });
993+ for (int j = 0 ; j < 3 ; j++) halfedgeColors.push_back (eColor);
994+ } else {
995+ for (int j = 0 ; j < 3 ; j++) halfedgeColors.push_back ({fColor , fColor , fColor });
996+ }
972997 }
973998
974999 // == Build corner index data, if needed
9751000
976- if (cornersHaveBeenUsed) {
977- // clang-format off
1001+ if (!usingSimplePick) {
1002+ if (cornersHaveBeenUsed) {
1003+ // clang-format off
9781004 std::array<glm::vec3, 3 > cColor = {
9791005 pick::indToVec (triangleCornerInds.data [3 *iFTri + 0 ] + cornerGlobalPickIndStart),
9801006 pick::indToVec (triangleCornerInds.data [3 *iFTri + 1 ] + cornerGlobalPickIndStart),
9811007 pick::indToVec (triangleCornerInds.data [3 *iFTri + 2 ] + cornerGlobalPickIndStart),
9821008 };
983- // clang-format on
984- for (int j = 0 ; j < 3 ; j++) cornerColors.push_back (cColor);
985- } else {
986- for (int j = 0 ; j < 3 ; j++) cornerColors.push_back ({vColor[0 ], vColor[1 ], vColor[2 ]});
1009+ // clang-format on
1010+ for (int j = 0 ; j < 3 ; j++) cornerColors.push_back (cColor);
1011+ } else {
1012+ for (int j = 0 ; j < 3 ; j++) cornerColors.push_back ({vColor[0 ], vColor[1 ], vColor[2 ]});
1013+ }
9871014 }
9881015
9891016 iFTri++;
@@ -1002,7 +1029,7 @@ void SurfaceMesh::setMeshPickAttributes(render::ShaderProgram& p) {
10021029 faceColorsBuff->setData (faceColor);
10031030 pickProgram->setAttribute (" a_faceColor" , faceColorsBuff);
10041031
1005- if (!simplePick ) {
1032+ if (!usingSimplePick ) {
10061033
10071034 std::shared_ptr<render::AttributeBuffer> halfedgeColorsBuff =
10081035 render::engine->generateAttributeBuffer (RenderDataType::Vector3Float, 3 );
@@ -1384,6 +1411,29 @@ void SurfaceMesh::buildCustomOptionsUI() {
13841411 }
13851412 }
13861413 }
1414+ ImGui::EndMenu ();
1415+ }
1416+
1417+ // Selection mode
1418+ if (ImGui::BeginMenu (" Selection Mode" )) {
1419+ if (ImGui::MenuItem (" auto" , NULL , selectionMode.get () == MeshSelectionMode::Auto))
1420+ setSelectionMode (MeshSelectionMode::Auto);
1421+ if (ImGui::MenuItem (" vertices only" , NULL , selectionMode.get () == MeshSelectionMode::VerticesOnly))
1422+ setSelectionMode (MeshSelectionMode::VerticesOnly);
1423+ if (ImGui::MenuItem (" faces only" , NULL , selectionMode.get () == MeshSelectionMode::FacesOnly))
1424+ setSelectionMode (MeshSelectionMode::FacesOnly);
1425+
1426+ ImGui::Separator ();
1427+
1428+ if (ImGui::MenuItem (" Mark edges as used (selectable)" , NULL , edgesHaveBeenUsed)) {
1429+ markEdgesAsUsed ();
1430+ }
1431+ if (ImGui::MenuItem (" Mark halfedges as used (selectable)" , NULL , halfedgesHaveBeenUsed)) {
1432+ markHalfedgesAsUsed ();
1433+ }
1434+ if (ImGui::MenuItem (" Mark corners as used (selectable)" , NULL , cornersHaveBeenUsed)) {
1435+ markCornersAsUsed ();
1436+ }
13871437
13881438 ImGui::EndMenu ();
13891439 }
@@ -1694,6 +1744,14 @@ SurfaceMesh* SurfaceMesh::setShadeStyle(MeshShadeStyle newStyle) {
16941744}
16951745MeshShadeStyle SurfaceMesh::getShadeStyle () { return shadeStyle.get (); }
16961746
1747+ SurfaceMesh* SurfaceMesh::setSelectionMode (MeshSelectionMode newMode) {
1748+ selectionMode = newMode;
1749+ refresh ();
1750+ requestRedraw ();
1751+ return this ;
1752+ }
1753+ MeshSelectionMode SurfaceMesh::getSelectionMode () { return selectionMode.get (); }
1754+
16971755// === Quantity adders
16981756
16991757
0 commit comments