Beispiel #1
0
void test_getEntArrAdj_up()
{
  iMesh_Instance mesh = create_mesh();
  int err;
  
  // get hexes adjacent to a row of faces in the z=0 plane
  iBase_EntityHandle *adj = 0;
  int *off = 0;
  int adj_alloc = 0, off_alloc = 0;
  int adj_size = -1, off_size = -1;
  iMesh_getEntArrAdj( mesh, FACES[4][0], INTERVALS, iBase_REGION,
                      &adj, &adj_alloc, &adj_size,
                      &off, &off_alloc, &off_size,
                      &err );
  CHECK_EQUAL( iBase_SUCCESS, err );
  CHECK( 0 != adj );
  CHECK( 0 != off );
  CHECK_EQUAL( INTERVALS, adj_size ); // one hex adjacent to each skin face
  CHECK_EQUAL( INTERVALS+1, off_size ); // one more than number of input handles
  CHECK( adj_alloc >= adj_size );
  CHECK( off_alloc >= off_size );
  
  for (int i = 0; i < INTERVALS; ++i) {
    CHECK_EQUAL( 1, off[i+1] - off[i] );
    CHECK_EQUAL( HEXES[0][i][0], adj[off[i]] );
  }
  
  free(adj);
  free(off);
}
Beispiel #2
0
int init( )
{
    // etape 1 : decrire le triangle, les coordonnees des 3 sommets.
    
    // creer un mesh pour stocker les coordonnees des sommets du triangle
    triangle= create_mesh(GL_TRIANGLES);
    
    // choisir une couleur pour les sommets, rouge + vert = jaune
    vertex_color(triangle, make_color(1, 1, 0));
    
    // donner les positions des 3 sommets, entre -1 1 sur x, y, z
    push_vertex(triangle, -0.5, -0.5, 0);
    push_vertex(triangle,  0.5,  0.5, 0);
    push_vertex(triangle, -0.5,  0.5, 0);
    
    return 0;   // ras, pas d'erreur
    
// on peut aussi donner des couleurs differentes aux sommets du triangle :
/*
    vertex_color(triangle, make_color(1, 0, 0));
    push_vertex(triangle, -0.5, -0.5, 0);
    
    vertex_color(triangle, make_color(0, 1, 0));
    push_vertex(triangle,  0.5,  0.5, 0);
    
    vertex_color(triangle, make_color(0, 0, 1));
    push_vertex(triangle, -0.5,  0.5, 0);
    
    return 0;   // ras, pas d'erreur
 */
}
Beispiel #3
0
int init()
{
  ASSERT(initSDL());
  ASSERT(initGL() == 1);
  ASSERT(create_mesh(mesh, N, M, SCREEN_WIDTH, SCREEN_HEIGHT));
  ASSERT(init_simulation());
  resize_window(SCREEN_WIDTH, SCREEN_HEIGHT);
#ifdef OPENMP
  omp_set_num_treads(MAX_THREADS);
#endif
  ASSERT(init_simulation());

  int size = (N+2)*(M+2);
  velocity_vectors = new Vector[size];
  velocity_indices = new GLuint [size*2];
  for(int i = 0; i < size*2; i++){
    velocity_indices[i] = i;
  }
  for(int i = 0; i < size; i++){
    velocity_vectors[i].p0.x = mesh.vertices[i].x;
    velocity_vectors[i].p0.y = mesh.vertices[i].y;
    velocity_vectors[i].p1.x = mesh.vertices[i].x;
    velocity_vectors[i].p1.y = mesh.vertices[i].y;
  }

  return (TRUE);
}
Beispiel #4
0
int send_create_mesh(int i)
{
    send_event(EVENT_CREATE_MESH);
    send_index(i);

    return create_mesh(i);
}
Beispiel #5
0
int main(int argc, char* argv[]) {
	Mesh* mesh = create_mesh();
	mesh_write("quad.mesh", mesh);
	mesh_destroy(mesh);

	Application app("my x11/win32 window", 600, 600, true);
	return app.run();
}
Beispiel #6
0
void test_getEntArrAdj_invalid_size()
{
  iMesh_Instance mesh = create_mesh();
  int err = -1;
  
  const int SPECIAL1 = 0xDeadBeef;
  const int SPECIAL2 = 0xCafe5;
  const int SPECIAL3 = 0xbabb1e;
  
    // test a downward query
  volatile int marker1 = SPECIAL1;
  iBase_EntityHandle adj1[8*INTERVALS-1]; // one too small
  volatile int marker2 = SPECIAL2;
  int off1[INTERVALS+1];
  int adj1_alloc = sizeof(adj1)/sizeof(adj1[0]);
  int off1_alloc = sizeof(off1)/sizeof(off1[0]);
  int adj_size, off_size;
  iBase_EntityHandle* adj_ptr = adj1;
  int* off_ptr = off1;
  iMesh_getEntArrAdj( mesh, HEXES[0][0], INTERVALS, iBase_VERTEX,
                      &adj_ptr, &adj1_alloc, &adj_size, 
                      &off_ptr, &off1_alloc, &off_size,
                      &err );
  CHECK_EQUAL( &adj1[0], adj_ptr );
  CHECK_EQUAL( &off1[0], off_ptr );
    // first ensure no stack corruption from writing off end of array
  CHECK_EQUAL( SPECIAL1, marker1 );
  CHECK_EQUAL( SPECIAL2, marker2 );
    // now verify that it correctly failed
  CHECK_EQUAL( iBase_BAD_ARRAY_SIZE, err );
  
    // now test an upwards query
  volatile int marker3 = SPECIAL3;
  int off2[INTERVALS];
  volatile int marker4 = SPECIAL1;
  int off2_alloc = sizeof(off2)/sizeof(off2[0]);
  err = iBase_SUCCESS;
  adj_ptr = adj1;
  off_ptr = off2;
  iMesh_getEntArrAdj( mesh, VERTS[0][0], INTERVALS+1, iBase_REGION,
                      &adj_ptr, &adj1_alloc, &adj_size, 
                      &off_ptr, &off2_alloc, &off_size,
                      &err );
    // first ensure no stack corruption from writing off end of array
  CHECK_EQUAL( &adj1[0], adj_ptr );
  CHECK_EQUAL( &off2[0], off_ptr );
  CHECK_EQUAL( SPECIAL3, marker3 );
  CHECK_EQUAL( SPECIAL1, marker4 );
    // now verify that it correctly failed
  CHECK_EQUAL( iBase_BAD_ARRAY_SIZE, err );
}
Beispiel #7
0
static void create_subd_mesh(Scene *scene,
                             Mesh *mesh,
                             BL::Object& b_ob,
                             BL::Mesh& b_mesh,
                             const vector<Shader*>& used_shaders,
                             float dicing_rate,
                             int max_subdivisions)
{
	BL::SubsurfModifier subsurf_mod(b_ob.modifiers[b_ob.modifiers.length()-1]);
	bool subdivide_uvs = subsurf_mod.use_subsurf_uv();

	create_mesh(scene, mesh, b_mesh, used_shaders, true, subdivide_uvs);

	/* export creases */
	size_t num_creases = 0;
	BL::Mesh::edges_iterator e;

	for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) {
		if(e->crease() != 0.0f) {
			num_creases++;
		}
	}

	mesh->subd_creases.resize(num_creases);

	Mesh::SubdEdgeCrease* crease = mesh->subd_creases.data();
	for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) {
		if(e->crease() != 0.0f) {
			crease->v[0] = e->vertices()[0];
			crease->v[1] = e->vertices()[1];
			crease->crease = e->crease();

			crease++;
		}
	}

	/* set subd params */
	if(!mesh->subd_params) {
		mesh->subd_params = new SubdParams(mesh);
	}
	SubdParams& sdparams = *mesh->subd_params;

	PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles");

	sdparams.dicing_rate = max(0.1f, RNA_float_get(&cobj, "dicing_rate") * dicing_rate);
	sdparams.max_level = max_subdivisions;

	scene->camera->update();
	sdparams.camera = scene->camera;
	sdparams.objecttoworld = get_transform(b_ob.matrix_world());
}
Beispiel #8
0
geometry_ptr create_geometry(const attributes& attr, const std::string& name, const parameter_list& params)
{
        if (name == PLANE) {
                return geometry_ptr(new plane(attr.object_to_world, attr.material));
        } else if (name == RECTANGLE) {
                return geometry_ptr(new rectangle(attr.object_to_world, attr.material));
        } else if (name == SPHERE) {
                return geometry_ptr(new sphere(attr.object_to_world, attr.material));
        } else if (name == MESH) {
                return create_mesh(attr, params);
        } else {
                throw std::invalid_argument("invalid geometry: " + name);
        }
}
Beispiel #9
0
int init( )
{
    // etape 1 : decrire le triangle, les coordonnees des 3 sommets.

    // creer un mesh pour stocker les coordonnees des sommets du triangle
    triangle= create_mesh(GL_TRIANGLES);

    vertex_color(triangle, make_color(1, 0, 0));
    push_vertex(triangle, -0.5, -0.5, 0);

    vertex_color(triangle, make_color(0, 1, 0));
    push_vertex(triangle,  0.5,  0.5, 0);

    vertex_color(triangle, make_color(0, 0, 1));
    push_vertex(triangle, -0.5,  0.5, 0);

    return 0;   // ras, pas d'erreur
}
Beispiel #10
0
int init( )
{
    // etape 1 : decrire le triangle, les coordonnees des 3 sommets.
    
    // creer un mesh pour stocker les coordonnees des sommets du triangle
    triangle= create_mesh(GL_TRIANGLES);
    
    vertex_color(triangle, make_color(1, 0, 0));
    push_vertex(triangle, -0.5, -0.5, 0);
    
    vertex_color(triangle, make_color(0, 1, 0));
    push_vertex(triangle,  0.5,  0.5, 0);
    
    vertex_color(triangle, make_color(0, 0, 1));
    push_vertex(triangle, -0.5,  0.5, 0);
    
    // etape 2 : creer une camera par defaut, elle est placee en 0, 0, 5 et regarde les objets situes en 0, 0, 0
    camera= make_orbiter();
    
    return 0;   // ras, pas d'erreur
}
Beispiel #11
0
void test_getEntArrAdj_none()
{
  iMesh_Instance mesh = create_mesh();
  int err = -1;

  iBase_EntityHandle* adj = 0;
  int* off = 0;
  int adj_alloc = 0, off_alloc = 0;
  int adj_size = -1, off_size = -1;
  iMesh_getEntArrAdj( mesh, NULL, 0, iBase_REGION, 
                      &adj, &adj_alloc, &adj_size,
                      &off, &off_alloc, &off_size,
                      &err );
  CHECK_EQUAL( iBase_SUCCESS, err );
  CHECK_EQUAL( 0, adj_alloc );
  CHECK_EQUAL( 0, adj_size );
  CHECK_EQUAL( 1, off_size );
  CHECK( off_alloc >= 1 );
  CHECK_EQUAL( 0, off[0] );  
  
  free(off);
}
Beispiel #12
0
int main( int argc, char* argv[] )
{
  REGISTER_TEST( test_getEntArrAdj_conn );
  REGISTER_TEST( test_getEntArrAdj_vertex );
  REGISTER_TEST( test_getEntArrAdj_up );
  REGISTER_TEST( test_getEntArrAdj_down );
  REGISTER_TEST( test_getEntArrAdj_invalid_size );
  REGISTER_TEST( test_getEntArrAdj_none );
  REGISTER_TEST( test_existinterface );
#ifdef  MOAB_HAVE_HDF5
  REGISTER_TEST( test_tags_retrieval );
#endif
  int result = RUN_TESTS( argc, argv );

  // Delete the static iMesh instance defined in create_mesh()
  iMesh_Instance mesh = create_mesh();
  int err;
  iMesh_dtor(mesh, &err);
  CHECK_EQUAL(iBase_SUCCESS, err);

  return result;
}
Beispiel #13
0
void test_getEntArrAdj_vertex()
{
  iMesh_Instance mesh = create_mesh();
  int err;
  
  // get hexes adjacent to row of vertices at x=0,y=0;
  iBase_EntityHandle *adj = 0;
  int *off = 0;
  int adj_alloc = 0, off_alloc = 0;
  int adj_size = -1, off_size = -1;
  iMesh_getEntArrAdj( mesh, VERTS[0][0], INTERVALS+1, iBase_REGION,
                      &adj, &adj_alloc, &adj_size,
                      &off, &off_alloc, &off_size,
                      &err );
  CHECK_EQUAL( iBase_SUCCESS, err );
  CHECK( 0 != adj );
  CHECK( 0 != off );
  CHECK_EQUAL( 2*INTERVALS, adj_size ); // INTERVALS+1 verts, end ones with one hex, others with two
  CHECK_EQUAL( INTERVALS+2, off_size ); // one more than number of input handles
  CHECK( adj_alloc >= adj_size );
  CHECK( off_alloc >= off_size );
  
    // first and last vertices should have one adjacent hex
  CHECK_EQUAL( 1, off[1] - off[0] );
  CHECK_EQUAL( HEXES[0][0][0], adj[off[0]] );
  CHECK_EQUAL( 1, off[INTERVALS+1] - off[INTERVALS] );
  CHECK_EQUAL( HEXES[0][0][INTERVALS-1], adj[off[INTERVALS]] );
    // middle ones should have two adjacent hexes
  for (int i = 1; i < INTERVALS; ++i) {
    CHECK_EQUAL( 2, off[i+1] - off[i] );
    CHECK_EQUAL( HEXES[0][0][i-1], adj[off[i]  ] );
    CHECK_EQUAL( HEXES[0][0][i  ], adj[off[i]+1] );
  }
  
  free(adj);
  free(off);
}
static void create_subd_mesh(Scene *scene,
                             Mesh *mesh,
                             BL::Object& b_ob,
                             BL::Mesh& b_mesh,
                             PointerRNA *cmesh,
                             const vector<Shader*>& used_shaders,
                             float dicing_rate,
                             int max_subdivisions)
{
	Mesh basemesh;
	create_mesh(scene, &basemesh, b_mesh, used_shaders);

	SubdParams sdparams(mesh, 0, true, false);
	sdparams.dicing_rate = max(0.1f, RNA_float_get(cmesh, "dicing_rate") * dicing_rate);
	sdparams.max_level = max_subdivisions;

	scene->camera->update();
	sdparams.camera = scene->camera;
	sdparams.objecttoworld = get_transform(b_ob.matrix_world());

	/* tesselate */
	DiagSplit dsplit(sdparams);
	basemesh.tessellate(&dsplit);
}
Beispiel #15
0
static Mesh* process_mesh(struct aiMesh* mesh, struct aiScene* scene) {
    Vertex **vertices = malloc(sizeof(Vertex *) * mesh->mNumVertices);
    for (int i = 0; i < mesh->mNumVertices; i++) {
        vertices[i] = malloc(sizeof(Vertex));
    }

    // Process vertices
    if (mesh->mVertices && mesh->mNumVertices > 0) {
        for (int i = 0; i < mesh->mNumVertices; i++) {
            struct aiVector3D position = mesh->mVertices[i];
            vertices[i]->position = create_vec(position.x, position.y, position.z, 1.0);
        }
    } else {
        gl_log(INFO, "A mesh was processed with no vertices.");
    }

    // Process normals
    if (mesh->mNormals) {
        for (int i = 0; i < mesh->mNumVertices; i++) {
            struct aiVector3D normal = mesh->mNormals[i];
            vertices[i]->normal = create_vec(normal.x, normal.y, normal.z, 1.0);
        }
    } else {
        gl_log(INFO, "A mesh was processed with no normals.");
    }

    // Process texture coords
    if (mesh->mTextureCoords[0]) {
        for (int i = 0; i < mesh->mNumVertices; i++) {
            struct aiVector3D texture = mesh->mTextureCoords[0][i];
            vertices[i]->texture_coords = create_vec(texture.x, texture.y, texture.z, 1.0);
        }
    } else {
        for (int i = 0; i < mesh->mNumVertices; i++) {
            vertices[i]->texture_coords = 0;
        }
        gl_log(INFO, "A mesh was processed with no texture coordinates.");
    }

    // Process material
    Texture* mesh_texture = malloc(sizeof(Texture));
    Material* mesh_material = malloc(sizeof(Material));
    if (mesh->mMaterialIndex >= 0) {
        struct aiString path;
        struct aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex];
        aiGetMaterialTexture(material, aiTextureType_DIFFUSE, 0, &path, 0, 0, 0, 0, 0, 0);
        mesh_texture->id = create_texture(path.data);

        struct aiColor4D color;
        aiGetMaterialColor(material, AI_MATKEY_COLOR_DIFFUSE, &color);
        mesh_material->diffuse_color = create_vec(color.r, color.g, color.b, color.a);

        aiGetMaterialColor(material, AI_MATKEY_COLOR_AMBIENT, &color);
        mesh_material->ambient_color = create_vec(color.r, color.g, color.b, color.a);

        aiGetMaterialColor(material, AI_MATKEY_COLOR_SPECULAR, &color);
        mesh_material->specular_color = create_vec(color.r, color.g, color.b, color.a);
    } else {
        gl_log(INFO, "A mesh was processed with no material.");
    }

    return create_mesh(vertices, mesh->mNumVertices, mesh_texture, mesh_material);
}
Beispiel #16
0
int main(void)
{
   GLuint pid;
   ALLEGRO_DISPLAY *d;
   ALLEGRO_EVENT_QUEUE *queue;
   ALLEGRO_EVENT event;
   int frames = 0;
   double start;

   if (!al_init()) {
      abort_example("Could not init Allegro.\n");
      return 1;
   }

   al_set_new_display_flags(ALLEGRO_OPENGL);
   al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST);
   al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST);
   d = al_create_display(WINDOW_W, WINDOW_H);
   if (!d) {
      abort_example("Unable to open a OpenGL display.\n");
      return -1;
   }

   if (al_get_display_option(ALLEGRO_SAMPLE_BUFFERS)) {
      printf("With multisampling, level %i\n", al_get_display_option(ALLEGRO_SAMPLES));
   }
   else {
      printf("Without multisampling.\n");
   }

   al_install_keyboard();

   queue = al_create_event_queue();
   al_register_event_source(queue, al_get_keyboard_event_source());
   al_register_event_source(queue, al_get_display_event_source(d));


   if (al_get_opengl_extension_list()->ALLEGRO_GL_ARB_multisample) {
      glEnable(GL_MULTISAMPLE_ARB);
   }

   if (!al_get_opengl_extension_list()->ALLEGRO_GL_ARB_vertex_program) {
      abort_example("This example requires a video card that supports "
                     " the ARB_vertex_program extension.\n");
      return -1;
   }

   glEnable(GL_DEPTH_TEST);
   glShadeModel(GL_SMOOTH);
   glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
   glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
   glDisable(GL_CULL_FACE);

   /* Setup projection and modelview matrices */
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluPerspective(45.0, WINDOW_W/(float)WINDOW_H, 0.1, 100.0);

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();

   /* Position the camera to look at our mesh from a distance */
   gluLookAt(0.0f, 20.0f, -45.0f, 0.0f, 0.0f, 0.0f, 0, 1, 0);

   create_mesh();

   /* Define the vertex program */
   glEnable(GL_VERTEX_PROGRAM_ARB);
   glGenProgramsARB(1, &pid);
   glBindProgramARB(GL_VERTEX_PROGRAM_ARB, pid);
   glGetError();

   if (al_get_opengl_extension_list()->ALLEGRO_GL_NV_vertex_program2_option) {
      glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
                        strlen(program_nv), program_nv);
   }
   else {
      glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
                        strlen(program), program);
   }

   /* Check for errors */
   if (glGetError()) {
      const char *pgm = al_get_opengl_extension_list()->ALLEGRO_GL_NV_vertex_program2_option
                        ? program_nv : program;
      GLint error_pos;
      const GLubyte *error_str = glGetString(GL_PROGRAM_ERROR_STRING_ARB);
      glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &error_pos);

      abort_example("Error compiling the vertex program:\n%s\n\nat "
            "character: %i\n%s\n", error_str, (int)error_pos,
            pgm + error_pos);
      return -1;
   }


   start = al_current_time();
   while (1) {
      if (!al_event_queue_is_empty(queue)) {
         while (al_get_next_event(queue, &event)) {
            switch (event.type) {
               case ALLEGRO_EVENT_DISPLAY_CLOSE:
                  goto done;

               case ALLEGRO_EVENT_KEY_DOWN:
                  if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE)
                     goto done;
                  break;
            }
         }
      }

      draw_mesh();
      al_flip_display();
      frames++;
   }

done:
   printf("%.1f FPS\n", frames / (al_current_time() - start));
   glDeleteProgramsARB(1, &pid);
   al_destroy_event_queue(queue);

   return 0;
}
Beispiel #17
0
int main()
{
	/* Really this is for testing purposes, in no way will this be the final usage */

	GFXContext context;
	context.major = 0;
	context.minor = 0;

	if(!gfx_init(context, GFX_ERROR_MODE_DEBUG))
	{
		GFXError error;
		if(gfx_errors_peek(&error)) print_error(error);

		return 0;
	}


	/* Setup 2 windows */
	GFXColorDepth depth;
	depth.redBits   = 8;
	depth.greenBits = 8;
	depth.blueBits  = 8;

	GFXWindow* window1 = gfx_window_create(NULL, 0, &depth, "Window Unos", 100, 100, 800, 600, GFX_WINDOW_RESIZABLE);
	GFXWindow* window2 = gfx_window_create(NULL, 0, &depth, "Window Deux", 200, 200, 800, 600, GFX_WINDOW_RESIZABLE);


	/* Pipeline */
	GFXPipeline* pipeline = gfx_pipeline_create();

	char targets[] = { 0 };
	GFXViewport viewport = { 0, 0, 800, 600 };
	pipeline->viewport = viewport;
	gfx_pipeline_target(pipeline, 1, targets);

	GFXPipe* bucket = gfx_pipeline_push_bucket(pipeline, 0);
	gfx_pipe_get_state(bucket)->render.state = GFX_STATE_DEFAULT | GFX_CLEAR_COLOR;


	/* Texture */
	GFXTextureFormat format;
	format.components    = 3;
	format.type.unpacked = GFX_UNSIGNED_BYTE;
	format.interpret     = GFX_INTERPRET_NORMALIZED;

	GFXTexture* tex = gfx_texture_create(GFX_TEXTURE_2D, format, 0, 800, 600, 1);

	GFXTextureImage image;
	image.texture = tex;
	image.mipmap  = 0;
	image.layer   = 0;

	gfx_pipeline_attach(pipeline, image, GFX_COLOR_ATTACHMENT, 0);


	/* Post processing */
	const char* vertSrc =
		"in ivec4 data;"
		"out vec2 coord;"
		"void main() {"
		"gl_Position = vec4(data.xy, 0, 1);"
		"coord = data.zw;"
		"}";

	const char* fragSrcA =
		"in vec2 coord;"
		"out vec3 color;"
		"uniform sampler2D tex;"
		"void main() {"
		"color = vec3(1.0f) - texture(tex, coord).rgb;"
		"}";
	const char* fragSrcB =
		"in vec2 coord;"
		"out vec3 color;"
		"uniform sampler2D tex;"
		"void main() {"
		"color = texture(tex, coord).rgb;"
		"}";

	GFXShader* vert = gfx_shader_create(GFX_VERTEX_SHADER);
	GFXShader* frag = gfx_shader_create(GFX_FRAGMENT_SHADER);
	gfx_shader_set_source(vert, 1, &vertSrc, NULL);
	gfx_shader_set_source(frag, 1, &fragSrcA, NULL);

	GFXShader* shaders[] = { vert, frag };

	GFXPipe* pipeA = gfx_pipeline_push_process(pipeline, window1, 0);
	GFXProgram* programA = gfx_pipe_process_add(pipeA->process, GFX_ALL_SHADERS, 1);
	gfx_program_set_attribute(programA, 0, "data");
	gfx_program_link(programA, 2, shaders, 0);

	gfx_shader_set_source(frag, 1, &fragSrcB, NULL);

	GFXPipe* pipeB = gfx_pipeline_push_process(pipeline, window2, 0);
	GFXProgram* programB = gfx_pipe_process_add(pipeB->process, GFX_ALL_SHADERS, 1);
	gfx_program_set_attribute(programB, 0, "data");
	gfx_program_link(programB, 2, shaders, 0);

	gfx_shader_free(vert);
	gfx_shader_free(frag);


	/* Property map */
	GFXSampler sampler =
	{
		.minFilter = GFX_FILTER_LINEAR,
		.mipFilter = GFX_FILTER_NEAREST,
		.magFilter = GFX_FILTER_LINEAR,

		.maxAnisotropy = 1.0f,

		.lodMin = 0,
		.lodMax = 0,

		.wrapS = GFX_WRAP_REPEAT,
		.wrapT = GFX_WRAP_REPEAT,
		.wrapR = GFX_WRAP_REPEAT
	};

	GFXPropertyMap* mapA = gfx_pipe_process_get_map(pipeA->process, 1);
	GFXPropertyMap* mapB = gfx_pipe_process_get_map(pipeB->process, 1);
	gfx_property_map_forward_named(mapA, 0, 0, 0, GFX_FRAGMENT_SHADER, "tex");
	gfx_property_map_set_sampler(mapA, 0, 0, sampler);
	gfx_property_map_set_texture(mapA, 0, 0, tex);
	gfx_property_map_forward_named(mapB, 0, 0, 0, GFX_FRAGMENT_SHADER, "tex");
	gfx_property_map_set_sampler_share(mapB, 0, 0, mapA, 0, 0);
	gfx_property_map_set_texture(mapB, 0, 0, tex);


	/* Mesh and material */
	GFXMaterial* material = create_material();
	GFXMesh* mesh = create_mesh();


	/* Batch */
	GFXBatch* batch = gfx_batch_create(
		bucket->bucket, material, mesh, 0, 0, 1, 1);
	gfx_batch_set_level(
		batch, 0, 0, 0, 1);
	gfx_batch_set(
		batch, 0, 1, 1);


	/* Setup a loop */
	while(gfx_poll_events() && gfx_get_num_windows())
	{
		/* Execute pipeline & swap buffers */
		gfx_pipeline_execute(pipeline, 0);

		/* Print time */
		//double time = gfx_get_time();
		//gfx_set_time(0.0);

		//printf("%f\n", 1.0 / time);

		/* Print all the errors! */
		GFXError error;
		while(gfx_errors_peek(&error))
		{
			print_error(error);
			gfx_errors_pop();
		}
	}


	/* Free all the things */
	gfx_batch_free(batch);
	gfx_mesh_free(mesh);
	gfx_material_free(material);
	gfx_program_map_free(programMap);
	gfx_texture_free(tex);
	gfx_pipeline_free(pipeline);

	gfx_window_free(window1);
	gfx_window_free(window2);

	gfx_terminate();

	return 0;
}
Beispiel #18
0
void test_getEntArrAdj_down()
{
  iMesh_Instance mesh = create_mesh();
  int err;
  
  // get quads adjacent to a edge-row of hexes
  iBase_EntityHandle *adj = 0;
  int *off = 0;
  int adj_alloc = 0, off_alloc = 0;
  int adj_size = -1, off_size = -1;
  iMesh_getEntArrAdj( mesh, HEXES[0][0], INTERVALS, iBase_FACE,
                      &adj, &adj_alloc, &adj_size,
                      &off, &off_alloc, &off_size,
                      &err );
  CHECK_EQUAL( iBase_SUCCESS, err );
  CHECK( 0 != adj );
  CHECK( 0 != off );
  CHECK_EQUAL( 2*INTERVALS+2, adj_size ); // corner hexes adj to 3 faces, others adj to 2
  CHECK_EQUAL( INTERVALS+1, off_size ); // one more than number of input handles
  CHECK( adj_alloc >= adj_size );
  CHECK( off_alloc >= off_size );
  
    // first (corner) hex should have three adjacent faces
  CHECK_EQUAL( 3, off[1] - off[0] );
  iBase_EntityHandle exp[3] = { FACES[0][0][0],
                                FACES[3][0][0],
                                FACES[4][0][0] };
  iBase_EntityHandle act[3];
  std::copy( adj + off[0], adj+off[1], act );
  std::sort( exp, exp+3 );
  std::sort( act, act+3 );
  CHECK_ARRAYS_EQUAL( exp, 3, act, 3 );
  
    // last (corner) hex should have three adjacent faces
  CHECK_EQUAL( 3, off[INTERVALS] - off[INTERVALS-1] );
  iBase_EntityHandle exp2[3] = { FACES[0][0][INTERVALS-1],
                                 FACES[3][0][INTERVALS-1],
                                 FACES[5][0][0] };
  std::copy( adj + off[INTERVALS-1], adj+off[INTERVALS], act );
  std::sort( exp2, exp2+3 );
  std::sort( act, act+3 );
  CHECK_ARRAYS_EQUAL( exp2, 3, act, 3 );
  
    // all middle hexes should have two adjacent faces
  for (int i = 1; i < INTERVALS-1; ++i) {
    iBase_EntityHandle e1, e2, a1, a2;
    e1 = FACES[0][0][i];
    e2 = FACES[3][0][i];
    if (e1 > e2) std::swap(e1,e2);
    
    CHECK_EQUAL( 2, off[i+1] - off[i] );
    a1 = adj[off[i]  ];
    a2 = adj[off[i]+1];
    if (a1 > a2) std::swap(a1,a2);
    
    CHECK_EQUAL( e1, a1 );
    CHECK_EQUAL( e2, a2 );
  }
  
  free(adj);
  free(off);
}
Beispiel #19
0
Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tris)
{
	/* test if we can instance or if the object is modified */
	BL::ID b_ob_data = b_ob.data();
	BL::ID key = (BKE_object_is_modified(b_ob))? b_ob: b_ob_data;
	BL::Material material_override = render_layer.material_override;

	/* find shader indices */
	vector<uint> used_shaders;

	BL::Object::material_slots_iterator slot;
	for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) {
		if(material_override)
			find_shader(material_override, used_shaders, scene->default_surface);
		else
			find_shader(slot->material(), used_shaders, scene->default_surface);
	}

	if(used_shaders.size() == 0) {
		if(material_override)
			find_shader(material_override, used_shaders, scene->default_surface);
		else
			used_shaders.push_back(scene->default_surface);
	}
	
	/* test if we need to sync */
	Mesh *mesh;

	if(!mesh_map.sync(&mesh, key)) {
		
		/* if transform was applied to mesh, need full update */
		if(object_updated && mesh->transform_applied);
		/* test if shaders changed, these can be object level so mesh
		 * does not get tagged for recalc */
		else if(mesh->used_shaders != used_shaders);
		else {
			/* even if not tagged for recalc, we may need to sync anyway
			 * because the shader needs different mesh attributes */
			bool attribute_recalc = false;

			foreach(uint shader, mesh->used_shaders)
				if(scene->shaders[shader]->need_update_attributes)
					attribute_recalc = true;

			if(!attribute_recalc)
				return mesh;
		}
	}

	/* ensure we only sync instanced meshes once */
	if(mesh_synced.find(mesh) != mesh_synced.end())
		return mesh;
	
	mesh_synced.insert(mesh);

	/* create derived mesh */
	PointerRNA cmesh = RNA_pointer_get(&b_ob_data.ptr, "cycles");

	vector<Mesh::Triangle> oldtriangle = mesh->triangles;
	
	/* compares curve_keys rather than strands in order to handle quick hair
	 * adjustsments in dynamic BVH - other methods could probably do this better*/
	vector<float4> oldcurve_keys = mesh->curve_keys;

	mesh->clear();
	mesh->used_shaders = used_shaders;
	mesh->name = ustring(b_ob_data.name().c_str());

	if(render_layer.use_surfaces || render_layer.use_hair) {
		if(preview)
			b_ob.update_from_editmode();

		bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED);
		BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, need_undeformed);

		if(b_mesh) {
			if(render_layer.use_surfaces && !hide_tris) {
				if(cmesh.data && experimental && RNA_boolean_get(&cmesh, "use_subdivision"))
					create_subd_mesh(scene, mesh, b_mesh, &cmesh, used_shaders);
				else
					create_mesh(scene, mesh, b_mesh, used_shaders);

				create_mesh_volume_attributes(scene, b_ob, mesh);
			}

			if(render_layer.use_hair)
				sync_curves(mesh, b_mesh, b_ob, false);

			/* free derived mesh */
			b_data.meshes.remove(b_mesh);
		}
	}

	/* displacement method */
	if(cmesh.data) {
		const int method = RNA_enum_get(&cmesh, "displacement_method");

		if(method == 0 || !experimental)
			mesh->displacement_method = Mesh::DISPLACE_BUMP;
		else if(method == 1)
			mesh->displacement_method = Mesh::DISPLACE_TRUE;
		else
			mesh->displacement_method = Mesh::DISPLACE_BOTH;
	}

	/* tag update */
	bool rebuild = false;

	if(oldtriangle.size() != mesh->triangles.size())
		rebuild = true;
	else if(oldtriangle.size()) {
		if(memcmp(&oldtriangle[0], &mesh->triangles[0], sizeof(Mesh::Triangle)*oldtriangle.size()) != 0)
			rebuild = true;
	}

	if(oldcurve_keys.size() != mesh->curve_keys.size())
		rebuild = true;
	else if(oldcurve_keys.size()) {
		if(memcmp(&oldcurve_keys[0], &mesh->curve_keys[0], sizeof(float4)*oldcurve_keys.size()) != 0)
			rebuild = true;
	}
	
	mesh->tag_update(scene, rebuild);

	return mesh;
}
Beispiel #20
0
void test_getEntArrAdj_conn()
{
  iMesh_Instance mesh = create_mesh();
  int err;
  
    // test hex vertices
  for (int i = 0; i < INTERVALS; ++i) {
    for (int j = 0; j < INTERVALS; ++j) {
      iBase_EntityHandle adj[8*INTERVALS];
      int off[INTERVALS+1];
      int adj_alloc = sizeof(adj)/sizeof(adj[0]);
      int off_alloc = sizeof(off)/sizeof(off[0]);
      int adj_size = -1, off_size = -1;
      iBase_EntityHandle* adj_ptr = adj;
      int* off_ptr = off;
      iMesh_getEntArrAdj( mesh, HEXES[i][j], INTERVALS, iBase_VERTEX,
                          &adj_ptr, &adj_alloc, &adj_size, 
                          &off_ptr, &off_alloc, &off_size,
                          &err );
      CHECK_EQUAL( &adj[0], adj_ptr );
      CHECK_EQUAL( &off[0], off_ptr );
      CHECK_EQUAL( iBase_SUCCESS, err );
      CHECK_EQUAL( 8*INTERVALS, adj_size );
      CHECK_EQUAL( 8*INTERVALS, adj_alloc );
      CHECK_EQUAL( INTERVALS+1, off_size );
      CHECK_EQUAL( INTERVALS+1, off_alloc );
      for (int k = 0; k < INTERVALS; ++k) {
        CHECK_EQUAL( 8*k, off[k] );
        iBase_EntityHandle conn[8];
        HEX_VERTS( i, j, k, conn );
        CHECK_ARRAYS_EQUAL( conn, 8, adj + off[k], off[k+1]-off[k] );
      }
    }
  }
  
    // test quad vertices for one side of mesh
  const int f = 0;
  for (int i = 0; i < INTERVALS; ++i) {
    iBase_EntityHandle adj[4*INTERVALS];
    int off[INTERVALS+1];
    int adj_alloc = sizeof(adj)/sizeof(adj[0]);
    int off_alloc = sizeof(off)/sizeof(off[0]);
    int adj_size = -1, off_size = -1;
      iBase_EntityHandle* adj_ptr = adj;
      int* off_ptr = off;
    iMesh_getEntArrAdj( mesh, FACES[f][i], INTERVALS, iBase_VERTEX,
                        &adj_ptr, &adj_alloc, &adj_size, 
                        &off_ptr, &off_alloc, &off_size,
                        &err );
    CHECK_EQUAL( &adj[0], adj_ptr );
    CHECK_EQUAL( &off[0], off_ptr );
    CHECK_EQUAL( iBase_SUCCESS, err );
    CHECK_EQUAL( 4*INTERVALS, adj_size );
    CHECK_EQUAL( 4*INTERVALS, adj_alloc );
    CHECK_EQUAL( INTERVALS+1, off_size );
    CHECK_EQUAL( INTERVALS+1, off_alloc );
    for (int k = 0; k < INTERVALS; ++k) {
      CHECK_EQUAL( 4*k, off[k] );
      iBase_EntityHandle conn[4];
      QUAD_VERTS( f, i, k, conn );
      CHECK_ARRAYS_EQUAL( conn, 4, adj + off[k], off[k+1]-off[k] );
    }
  }
}
Beispiel #21
0
void draw()
{
    int mesh = 0, multi = 0, meshcolor = 0;
    switch (state) {
    case STATE_GRAY_SOURCE:
        parg_shader_bind(P_GRAY);
        parg_texture_bind(graytex, 0);
        parg_uniform1f(U_ZSCALE, 1);
        break;
    case STATE_COLOR_IH:
        mesh = 1;
        parg_shader_bind(P_GRAYMESH);
        parg_uniform1f(U_ZSCALE, 0.3);
        break;
    case STATE_COLOR_DHSCSI:
        mesh = multi = 1;
        parg_shader_bind(P_GRAYMESH);
        parg_uniform1f(U_ZSCALE, 0.3);
        break;
    case STATE_MULTI_RGBA:
    case STATE_MULTI_RGB:
    case STATE_MULTI_DIAGRAM:
        meshcolor = mesh = multi = 1;
        parg_shader_bind(P_GRAYMESH);
        parg_uniform1f(U_ZSCALE, 0.25);
        break;
    case STATE_COLOR_DEFAULT:
    case STATE_GRAY_DEFAULT:
    case STATE_GRAY_SIMPLIFY:
    case STATE_GRAY_INVERT:
    case STATE_GRAY_HEIGHTS:
        mesh = 1;
        parg_shader_bind(P_GRAYMESH);
        parg_uniform1f(U_ZSCALE, 1);
        break;
    case STATE_GRAY_MULTI:
        mesh = multi = 1;
        parg_shader_bind(P_GRAYMESH);
        parg_texture_bind(colortex, 0);
        parg_uniform1f(U_ZSCALE, 0.3);
        break;
    case STATE_GRAY_DUAL:
        mesh = multi = 1;
        parg_shader_bind(P_GRAYMESH);
        parg_texture_bind(colortex, 0);
        parg_uniform1f(U_ZSCALE, 1);
        break;
    case STATE_GRAY_DHS:
    case STATE_GRAY_DHSC:
        mesh = multi = 1;
        parg_shader_bind(P_GRAYMESH);
        parg_texture_bind(colortex, 0);
        parg_uniform1f(U_ZSCALE, 0.5);
        break;
    case STATE_COLOR_SOURCE:
        parg_texture_bind(colortex, 0);
        parg_shader_bind(P_COLOR);
        parg_uniform1f(U_ZSCALE, 1);
        break;
    default:
        break;
    }

    if (mesh) {
        for (int i = 0; i < sizeof(trimesh) / sizeof(trimesh[0]); i++) {
            parg_mesh_free(trimesh[i]);
        }
        memset(trimesh, 0, sizeof(trimesh));
        create_mesh();
    }

    Matrix4 model;
    if (mesh) {
        model = M4MakeScale(V3MakeFromElems(20, 20, 10));
        model = M4Mul(M4MakeTranslation(V3MakeFromElems(-10, -10, 0)), model);
    } else {
        model = M4MakeIdentity();
    }

    Matrix4 modelview = M4Mul(view, model);
    Matrix4 mvp = M4Mul(projection, modelview);
    parg_uniform_matrix4f(U_MVP, &mvp);
    parg_draw_clear();
    if (mesh) {
        Vector4 colors[3];
        colors[0] = (Vector4){0, 0.6, 0.9, 1};
        colors[1] = (Vector4){0, 0.9, 0.6, 1};
        colors[2] = (Vector4){0.9, 0.6, 0, 1};
        Vector4 black = {0, 0, 0, 1.0};

        for (int imesh = 0; imesh < nmeshes; imesh++) {
            parg_varray_enable(parg_mesh_coord(trimesh[imesh]), A_POSITION, 3,
                PARG_FLOAT, 0, 0);
            parg_varray_bind(parg_mesh_index(trimesh[imesh]));
            if (meshcolor) {
                unsigned int b = meshcolors[imesh] & 0xff;
                unsigned int g = (meshcolors[imesh] >> 8) & 0xff;
                unsigned int r = (meshcolors[imesh] >> 16) & 0xff;
                unsigned int a = (meshcolors[imesh] >> 24) & 0xff;
                Vector4 color;
                color.x = r / 255.0f;
                color.y = g / 255.0f;
                color.z = b / 255.0f;
                color.w = a / 255.0f;
                parg_uniform4f(U_COLOR, &color);
            } else {
                parg_uniform4f(U_COLOR, &colors[imesh]);
            }
            parg_draw_triangles_u16(0, parg_mesh_ntriangles(trimesh[imesh]));
            parg_uniform4f(U_COLOR, &black);
            parg_draw_wireframe_triangles_u16(
                0, parg_mesh_ntriangles(trimesh[imesh]));
        }

    } else {
Beispiel #22
0
void recv_create_mesh(void)
{
    int i = recv_index();

    create_mesh(i);
}
Beispiel #23
0
/**
 * メッシュ情報を読み込む
 *
 * @param mesh メッシュ情報
 */
void FbxFileLoader::load_mesh( FbxMesh* mesh )
{
	if ( ! mesh )
	{
		return;
	}

	if ( ! get_model()->get_mesh() )
	{
		get_model()->set_mesh( create_mesh() );
	}

	VertexIndexMap vertex_index_map;
	VertexList vertex_list;

	Mesh::PositionList position_list;
	Mesh::VertexWeightList vertex_weight_list;

	// load_mesh_vertex()
	for ( int n = 0; n < mesh->GetControlPointsCount(); n++ )
	{
		FbxVector4 v = mesh->GetControlPointAt( n );

		position_list.push_back(
			Mesh::Position(
				static_cast< float >( v[ 0 ] ),
				static_cast< float >( v[ 1 ] ),
				static_cast< float >( v[ 2 ] ) ) );
	}

	// load_mesh_vertex_weight()
	{
		int skin_count = mesh->GetDeformerCount( FbxDeformer::eSkin );

		if ( skin_count > 0 )
		{
			assert( skin_count == 1 );

			vertex_weight_list.resize( position_list.size() );

			FbxSkin* skin = FbxCast< FbxSkin >( mesh->GetDeformer( 0, FbxDeformer::eSkin ) );

			load_mesh_vertex_weight( skin, vertex_weight_list );
		}
	}

	FbxLayerElementSmoothing* smoothing = 0;

	// load_mesh_smoothing_info()
	{
		FbxLayer* layer = mesh->GetLayer( 0 );
		smoothing = layer->GetSmoothing();
	}

	if ( ! smoothing )
	{
		COMMON_THROW_EXCEPTION_MESSAGE( "this FBX format is not supported. ( no smoothing info )" );
	}

	// load_mesh_plygon()
	FbxLayerElementArrayTemplate< int >* material_indices;
	mesh->GetMaterialIndices( & material_indices );

	for ( int n = 0; n < mesh->GetPolygonCount(); n++ )
	{
		Mesh::VertexGroup* vertex_group = get_model()->get_mesh()->get_vertex_group_at( material_indices->GetAt( n ) );

		bool is_smooth = smoothing->GetDirectArray().GetAt( n ) != 0;
		FbxVector4 polygon_normal( 0.f, 0.f, 0.f );

		if ( ! is_smooth )
		{
			// ポリゴンの法線を計算する
			Mesh::Position p1( position_list.at( mesh->GetPolygonVertex( n, 0 ) ) );
			Mesh::Position p2( position_list.at( mesh->GetPolygonVertex( n, 1 ) ) );
			Mesh::Position p3( position_list.at( mesh->GetPolygonVertex( n, 2 ) ) );

			FbxVector4 a = FbxVector4( p1.x(), p1.y(), p1.z() );
			FbxVector4 b = FbxVector4( p2.x(), p2.y(), p2.z() );
			FbxVector4 c = FbxVector4( p3.x(), p3.y(), p3.z() );

			FbxVector4 ab( b - a );
			FbxVector4 bc( c - b );

			polygon_normal = ab.CrossProduct( bc );
			polygon_normal.Normalize();
		}

		for ( int m = 0; m < mesh->GetPolygonSize( n ); m++ )
		{
			int position_index = mesh->GetPolygonVertex( n, m );

			Mesh::Vertex v;
			v.Position = Mesh::Position( position_list.at( position_index ) );

			FbxVector2 uv_vector;
			bool unmapped;
			
			if ( mesh->GetPolygonVertexUV( n, m, "UVMap", uv_vector, unmapped) )
			{
				v.TexCoord = Mesh::TexCoord(
					static_cast< float >( uv_vector[ 0 ] ),
					1.f - static_cast< float >( uv_vector[ 1 ] ) );
			}

			if ( is_smooth )
			{
				FbxVector4 normal_vector;

				// 頂点の法線
				if ( mesh->GetPolygonVertexNormal( n, m, normal_vector ) )
				{
					v.Normal = Mesh::Normal(
						static_cast< float >( normal_vector[ 0 ] ),
						static_cast< float >( normal_vector[ 1 ] ),
						static_cast< float >( normal_vector[ 2 ] ) );
				}
			}
			else
			{
				// ポリゴンの法線
				v.Normal = Mesh::Normal(
					static_cast< float >( polygon_normal[ 0 ] ),
					static_cast< float >( polygon_normal[ 1 ] ),
					static_cast< float >( polygon_normal[ 2 ] ) );
			}
			
			// 頂点の一覧に追加
			{
				VertexIndexMap::iterator i = vertex_index_map.find( v );

				if ( i != vertex_index_map.end() )
				{
					vertex_group->add_index( i->second );
				}
				else
				{
					Mesh::Index vertex_index = static_cast< Mesh::Index >( get_model()->get_mesh()->get_vertex_count() );

					get_model()->get_mesh()->add_vertex( v );

					if ( ! vertex_weight_list.empty() )
					{
						get_model()->get_mesh()->add_vertex_weight( vertex_weight_list.at( position_index ) );
					}

					vertex_group->add_index( vertex_index );

					vertex_index_map[ v ] = vertex_index;
				}
			}
		}
	}
}
Beispiel #24
0
Mesh *BlenderSync::sync_mesh(BL::Depsgraph &b_depsgraph,
                             BL::Object &b_ob,
                             BL::Object &b_ob_instance,
                             bool object_updated,
                             bool show_self,
                             bool show_particles)
{
  /* test if we can instance or if the object is modified */
  BL::ID b_ob_data = b_ob.data();
  BL::ID key = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data;
  BL::Material material_override = view_layer.material_override;

  /* find shader indices */
  vector<Shader *> used_shaders;

  BL::Object::material_slots_iterator slot;
  for (b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) {
    if (material_override) {
      find_shader(material_override, used_shaders, scene->default_surface);
    }
    else {
      BL::ID b_material(slot->material());
      find_shader(b_material, used_shaders, scene->default_surface);
    }
  }

  if (used_shaders.size() == 0) {
    if (material_override)
      find_shader(material_override, used_shaders, scene->default_surface);
    else
      used_shaders.push_back(scene->default_surface);
  }

  /* test if we need to sync */
  int requested_geometry_flags = Mesh::GEOMETRY_NONE;
  if (view_layer.use_surfaces) {
    requested_geometry_flags |= Mesh::GEOMETRY_TRIANGLES;
  }
  if (view_layer.use_hair) {
    requested_geometry_flags |= Mesh::GEOMETRY_CURVES;
  }
  Mesh *mesh;

  if (!mesh_map.sync(&mesh, key)) {
    /* if transform was applied to mesh, need full update */
    if (object_updated && mesh->transform_applied)
      ;
    /* test if shaders changed, these can be object level so mesh
     * does not get tagged for recalc */
    else if (mesh->used_shaders != used_shaders)
      ;
    else if (requested_geometry_flags != mesh->geometry_flags)
      ;
    else {
      /* even if not tagged for recalc, we may need to sync anyway
       * because the shader needs different mesh attributes */
      bool attribute_recalc = false;

      foreach (Shader *shader, mesh->used_shaders)
        if (shader->need_update_mesh)
          attribute_recalc = true;

      if (!attribute_recalc)
        return mesh;
    }
  }

  /* ensure we only sync instanced meshes once */
  if (mesh_synced.find(mesh) != mesh_synced.end())
    return mesh;

  progress.set_sync_status("Synchronizing object", b_ob.name());

  mesh_synced.insert(mesh);

  /* create derived mesh */
  array<int> oldtriangles;
  array<Mesh::SubdFace> oldsubd_faces;
  array<int> oldsubd_face_corners;
  oldtriangles.steal_data(mesh->triangles);
  oldsubd_faces.steal_data(mesh->subd_faces);
  oldsubd_face_corners.steal_data(mesh->subd_face_corners);

  /* compares curve_keys rather than strands in order to handle quick hair
   * adjustments in dynamic BVH - other methods could probably do this better*/
  array<float3> oldcurve_keys;
  array<float> oldcurve_radius;
  oldcurve_keys.steal_data(mesh->curve_keys);
  oldcurve_radius.steal_data(mesh->curve_radius);

  mesh->clear();
  mesh->used_shaders = used_shaders;
  mesh->name = ustring(b_ob_data.name().c_str());

  if (requested_geometry_flags != Mesh::GEOMETRY_NONE) {
    /* Adaptive subdivision setup. Not for baking since that requires
     * exact mapping to the Blender mesh. */
    if (scene->bake_manager->get_baking()) {
      mesh->subdivision_type = Mesh::SUBDIVISION_NONE;
    }
    else {
      mesh->subdivision_type = object_subdivision_type(b_ob, preview, experimental);
    }

    /* For some reason, meshes do not need this... */
    bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED);

    BL::Mesh b_mesh = object_to_mesh(
        b_data, b_ob, b_depsgraph, need_undeformed, mesh->subdivision_type);

    if (b_mesh) {
      /* Sync mesh itself. */
      if (view_layer.use_surfaces && show_self) {
        if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE)
          create_subd_mesh(scene, mesh, b_ob, b_mesh, used_shaders, dicing_rate, max_subdivisions);
        else
          create_mesh(scene, mesh, b_mesh, used_shaders, false);

        create_mesh_volume_attributes(scene, b_ob, mesh, b_scene.frame_current());
      }

      /* Sync hair curves. */
      if (view_layer.use_hair && show_particles &&
          mesh->subdivision_type == Mesh::SUBDIVISION_NONE) {
        sync_curves(mesh, b_mesh, b_ob, false);
      }

      free_object_to_mesh(b_data, b_ob, b_mesh);
    }
  }
  mesh->geometry_flags = requested_geometry_flags;

  /* fluid motion */
  sync_mesh_fluid_motion(b_ob, scene, mesh);

  /* tag update */
  bool rebuild = (oldtriangles != mesh->triangles) || (oldsubd_faces != mesh->subd_faces) ||
                 (oldsubd_face_corners != mesh->subd_face_corners) ||
                 (oldcurve_keys != mesh->curve_keys) || (oldcurve_radius != mesh->curve_radius);

  mesh->tag_update(scene, rebuild);

  return mesh;
}
Beispiel #25
0
Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated)
{
	/* test if we can instance or if the object is modified */
	BL::ID b_ob_data = b_ob.data();
	BL::ID key = (object_is_modified(b_ob))? b_ob: b_ob_data;

	/* find shader indices */
	vector<uint> used_shaders;

	BL::Object::material_slots_iterator slot;
	for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) {
		BL::Material material_override = render_layers.front().material_override;

		if(material_override)
			find_shader(material_override, used_shaders, scene->default_surface);
		else
			find_shader(slot->material(), used_shaders, scene->default_surface);
	}

	if(used_shaders.size() == 0)
		used_shaders.push_back(scene->default_surface);
	
	/* test if we need to sync */
	Mesh *mesh;

	if(!mesh_map.sync(&mesh, key)) {
		/* if transform was applied to mesh, need full update */
		if(object_updated && mesh->transform_applied);
		/* test if shaders changed, these can be object level so mesh
		   does not get tagged for recalc */
		else if(mesh->used_shaders != used_shaders);
		else {
			/* even if not tagged for recalc, we may need to sync anyway
			 * because the shader needs different mesh attributes */
			bool attribute_recalc = false;

			foreach(uint shader, mesh->used_shaders)
				if(scene->shaders[shader]->need_update_attributes)
					attribute_recalc = true;

			if(!attribute_recalc)
				return mesh;
		}
	}

	/* ensure we only sync instanced meshes once */
	if(mesh_synced.find(mesh) != mesh_synced.end())
		return mesh;
	
	mesh_synced.insert(mesh);

	/* create derived mesh */
	BL::Mesh b_mesh = object_to_mesh(b_ob, b_scene, true, !preview);
	PointerRNA cmesh = RNA_pointer_get(&b_ob_data.ptr, "cycles");

	vector<Mesh::Triangle> oldtriangle = mesh->triangles;

	mesh->clear();
	mesh->used_shaders = used_shaders;
	mesh->name = ustring(b_ob_data.name().c_str());

	if(b_mesh) {
		if(cmesh.data && experimental && RNA_boolean_get(&cmesh, "use_subdivision"))
			create_subd_mesh(mesh, b_mesh, &cmesh, used_shaders);
		else
			create_mesh(scene, mesh, b_mesh, used_shaders);

		/* free derived mesh */
		object_remove_mesh(b_data, b_mesh);
	}

	/* displacement method */
	if(cmesh.data) {
		int method = RNA_enum_get(&cmesh, "displacement_method");

		if(method == 0 || !experimental)
			mesh->displacement_method = Mesh::DISPLACE_BUMP;
		else if(method == 1)
			mesh->displacement_method = Mesh::DISPLACE_TRUE;
		else
			mesh->displacement_method = Mesh::DISPLACE_BOTH;
	}

	/* tag update */
	bool rebuild = false;

	if(oldtriangle.size() != mesh->triangles.size())
		rebuild = true;
	else if(oldtriangle.size()) {
		if(memcmp(&oldtriangle[0], &mesh->triangles[0], sizeof(Mesh::Triangle)*oldtriangle.size()) != 0)
			rebuild = true;
	}
	
	mesh->tag_update(scene, rebuild);

	return mesh;
}
Beispiel #26
0
Mesh *BlenderSync::sync_mesh(BL::Object& b_ob,
                             bool object_updated,
                             bool hide_tris)
{
	/* When viewport display is not needed during render we can force some
	 * caches to be releases from blender side in order to reduce peak memory
	 * footprint during synchronization process.
	 */
	const bool is_interface_locked = b_engine.render() &&
	                                 b_engine.render().use_lock_interface();
	const bool can_free_caches = BlenderSession::headless || is_interface_locked;

	/* test if we can instance or if the object is modified */
	BL::ID b_ob_data = b_ob.data();
	BL::ID key = (BKE_object_is_modified(b_ob))? b_ob: b_ob_data;
	BL::Material material_override = render_layer.material_override;

	/* find shader indices */
	vector<uint> used_shaders;

	BL::Object::material_slots_iterator slot;
	for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) {
		if(material_override) {
			find_shader(material_override, used_shaders, scene->default_surface);
		}
		else {
			BL::ID b_material(slot->material());
			find_shader(b_material, used_shaders, scene->default_surface);
		}
	}

	if(used_shaders.size() == 0) {
		if(material_override)
			find_shader(material_override, used_shaders, scene->default_surface);
		else
			used_shaders.push_back(scene->default_surface);
	}
	
	/* test if we need to sync */
	int requested_geometry_flags = Mesh::GEOMETRY_NONE;
	if(render_layer.use_surfaces) {
		requested_geometry_flags |= Mesh::GEOMETRY_TRIANGLES;
	}
	if(render_layer.use_hair) {
		requested_geometry_flags |= Mesh::GEOMETRY_CURVES;
	}
	Mesh *mesh;

	if(!mesh_map.sync(&mesh, key)) {
		/* if transform was applied to mesh, need full update */
		if(object_updated && mesh->transform_applied);
		/* test if shaders changed, these can be object level so mesh
		 * does not get tagged for recalc */
		else if(mesh->used_shaders != used_shaders);
		else if(requested_geometry_flags != mesh->geometry_flags);
		else {
			/* even if not tagged for recalc, we may need to sync anyway
			 * because the shader needs different mesh attributes */
			bool attribute_recalc = false;

			foreach(uint shader, mesh->used_shaders)
				if(scene->shaders[shader]->need_update_attributes)
					attribute_recalc = true;

			if(!attribute_recalc)
				return mesh;
		}
	}

	/* ensure we only sync instanced meshes once */
	if(mesh_synced.find(mesh) != mesh_synced.end())
		return mesh;
	
	mesh_synced.insert(mesh);

	/* create derived mesh */
	PointerRNA cmesh = RNA_pointer_get(&b_ob_data.ptr, "cycles");

	vector<Mesh::Triangle> oldtriangle = mesh->triangles;
	
	/* compares curve_keys rather than strands in order to handle quick hair
	 * adjustments in dynamic BVH - other methods could probably do this better*/
	vector<float4> oldcurve_keys = mesh->curve_keys;

	mesh->clear();
	mesh->used_shaders = used_shaders;
	mesh->name = ustring(b_ob_data.name().c_str());

	if(requested_geometry_flags != Mesh::GEOMETRY_NONE) {
		/* mesh objects does have special handle in the dependency graph,
		 * they're ensured to have properly updated.
		 *
		 * updating meshes here will end up having derived mesh referencing
		 * freed data from the blender side.
		 */
		if(preview && b_ob.type() != BL::Object::type_MESH)
			b_ob.update_from_editmode();

		bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED);
		BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, need_undeformed);

		if(b_mesh) {
			if(render_layer.use_surfaces && !hide_tris) {
				if(cmesh.data && experimental && RNA_boolean_get(&cmesh, "use_subdivision"))
					create_subd_mesh(scene, mesh, b_mesh, &cmesh, used_shaders);
				else
					create_mesh(scene, mesh, b_mesh, used_shaders);

				create_mesh_volume_attributes(scene, b_ob, mesh, b_scene.frame_current());
			}

			if(render_layer.use_hair)
				sync_curves(mesh, b_mesh, b_ob, false);

			if(can_free_caches) {
				b_ob.cache_release();
			}

			/* free derived mesh */
			b_data.meshes.remove(b_mesh);
		}
	}
	mesh->geometry_flags = requested_geometry_flags;

	/* displacement method */
	if(cmesh.data) {
		const int method = get_enum(cmesh, "displacement_method");

		if(method == 0 || !experimental)
			mesh->displacement_method = Mesh::DISPLACE_BUMP;
		else if(method == 1)
			mesh->displacement_method = Mesh::DISPLACE_TRUE;
		else
			mesh->displacement_method = Mesh::DISPLACE_BOTH;
	}

	/* tag update */
	bool rebuild = false;

	if(oldtriangle.size() != mesh->triangles.size())
		rebuild = true;
	else if(oldtriangle.size()) {
		if(memcmp(&oldtriangle[0], &mesh->triangles[0], sizeof(Mesh::Triangle)*oldtriangle.size()) != 0)
			rebuild = true;
	}

	if(oldcurve_keys.size() != mesh->curve_keys.size())
		rebuild = true;
	else if(oldcurve_keys.size()) {
		if(memcmp(&oldcurve_keys[0], &mesh->curve_keys[0], sizeof(float4)*oldcurve_keys.size()) != 0)
			rebuild = true;
	}
	
	mesh->tag_update(scene, rebuild);

	return mesh;
}