January 10, 2019

BlenderのソースコードをXcodeで読む Part7

前回の記事では面の選択でした。今回もその続きです。

その1

void draw_object_backbufsel(
        Depsgraph *depsgraph, Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob,
        short select_mode)
{
    :
    :
    :

    glClearDepth(1.0); GPU_clear(GPU_DEPTH_BIT);
    GPU_depth_test(true);

上の部分は隠面消去をしていると思っていて、以下の流れだと読んでいます。

glClearDepth(1.0) を呼び、デプスバッファを初期化した時に使われるデプスの値を設定する。

GPU_clear(GPU_DEPTH_BIT)glClear(GL_DEPTH_BUFFER_BIT) を呼び、デプスバッファを初期化する。

GPU_depth_test(true)glEnable(GL_DEPTH_TEST) を呼び、デプスバッファを使って隠面消去をする。

その2

Object には type というプロパティがあって、そこで OB_MESH なら、Object mode をみて処理を分岐させています。

void draw_object_backbufsel(
        Depsgraph *depsgraph, Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob,
        short select_mode)
{
    :
    :
    :
    switch (ob->type) {
        case OB_MESH:
            if (ob->mode & OB_MODE_EDIT) {
                Mesh *me = ob->data;
                BMEditMesh *em = me->edit_btmesh;

                BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE);

                bbs_mesh_solid_EM(em, scene, v3d, ob, (select_mode & SCE_SELECT_FACE) != 0);
                if (select_mode & SCE_SELECT_FACE)
                    bm_solidoffs = 1 + em->bm->totface;
                else {
                    bm_solidoffs = 1;
                }

                ED_view3d_polygon_offset(rv3d, 1.0);

                /* we draw edges if edge select mode */
                if (select_mode & SCE_SELECT_EDGE) {
                    bbs_mesh_wire(em, bm_solidoffs);
                    bm_wireoffs = bm_solidoffs + em->bm->totedge;
                }
                else {
                    /* `bm_vertoffs` is calculated from `bm_wireoffs`. (otherwise see T53512) */
                    bm_wireoffs = bm_solidoffs;
                }

                /* we draw verts if vert select mode. */
                if (select_mode & SCE_SELECT_VERTEX) {
                    bbs_mesh_verts(em, bm_wireoffs);
                    bm_vertoffs = bm_wireoffs + em->bm->totvert;
                }
                else {
                    bm_vertoffs = bm_wireoffs;
                }

                ED_view3d_polygon_offset(rv3d, 0.0);
            }
            else {
                Mesh *me = ob->data;
                if ((me->editflag & ME_EDIT_PAINT_VERT_SEL) &&
                    /* currently vertex select supports weight paint and vertex paint*/
                    ((ob->mode & OB_MODE_WEIGHT_PAINT) || (ob->mode & OB_MODE_VERTEX_PAINT)))
                {
                    bbs_mesh_solid_verts(depsgraph, scene, ob);
                }
                else {
                    bbs_mesh_solid_faces(scene, ob);
                }
            }
            break;
        case OB_CURVE:
        case OB_SURF:
            break;
    }

mode のコメントを見ると Local object mode とあります。 OB_MODE_EDITDNA_object_enums.h に定義があります。

/* Object.mode */
typedef enum eObjectMode {
	OB_MODE_OBJECT        = 0,
	OB_MODE_EDIT          = 1 << 0,
	OB_MODE_SCULPT        = 1 << 1,
	OB_MODE_VERTEX_PAINT  = 1 << 2,
	OB_MODE_WEIGHT_PAINT  = 1 << 3,
	OB_MODE_TEXTURE_PAINT = 1 << 4,
	OB_MODE_PARTICLE_EDIT = 1 << 5,
	OB_MODE_POSE          = 1 << 6,
	OB_MODE_GPENCIL_EDIT  = 1 << 7,
	OB_MODE_GPENCIL_PAINT = 1 << 8,
	OB_MODE_GPENCIL_SCULPT = 1 << 9,
	OB_MODE_GPENCIL_WEIGHT = 1 << 10,
} eObjectMode;

さて、今回はここまで。