//------------------------------------------------------------------------------ /// Parametrically load a conical mesh Mesh* MeshLoader::cone( const double& radius, const double& height, const unsigned int& arcsegments, Material* material, const EMeshLoaderMaterialOp& material_op ) { Mesh* mesh = new Mesh(); // ----- Generate Vertices ------ // peak is 0 vertex mesh->appendVertex( new Vertex( 0.0, 0.0, height ) ); // bottom disk double dtheta = 2.0 * PI / (double) arcsegments; double theta = 0.0; for( unsigned int i = 0; i < arcsegments; i++ ) { double x = cos(theta) * radius; double y = sin(theta) * radius; theta += dtheta; mesh->appendVertex( new Vertex( x, y, 0.0 ) ); } // ------------------------------ // ----- Generate Polygons ------ Polygon* poly; // cap poly = new Polygon(); assign_material( mesh, poly, material, material_op ); for( unsigned int i = 1; i <= arcsegments; i++ ) { poly->addVertex( i ); } mesh->appendPolygon( poly ); // sides for( unsigned int i = 1; i <= arcsegments; i++ ) { poly = new Polygon(); assign_material( mesh, poly, material, material_op ); if( i < arcsegments ) { poly->addVertex( 0 ); // peak poly->addVertex( i+1 ); poly->addVertex( i ); } else { poly->addVertex( 0 ); // peak poly->addVertex( 1 ); poly->addVertex( i ); } mesh->appendPolygon( poly ); } // ------------------------------ mesh->calculate_polygon_normals(); mesh->calculate_vertex_normals(); return mesh; }
//------------------------------------------------------------------------------ /// Parametrically load a circle mesh, e.g. a flat circle Mesh* MeshLoader::circle( const double& radius, const unsigned int& arcsegments, Material* material, const EMeshLoaderMaterialOp& material_op ) { Mesh* mesh = new Mesh(); // ----- Generate Vertices ------ double dtheta = 2.0 * PI / (double) arcsegments; double theta = 0.0; double x, y; for( unsigned int i = 0; i < arcsegments; i++ ) { x = cos(theta) * radius; y = sin(theta) * radius; theta += dtheta; mesh->appendVertex( new Vertex( x, y, 0.0 ) ); } // ------------------------------ // ----- Generate Polygons ------ Polygon* poly = new Polygon(); assign_material( mesh, poly, material, material_op ); for( unsigned int i = 0; i < arcsegments; i++ ) { poly->addVertex( i ); } mesh->appendPolygon( poly ); // ------------------------------ mesh->calculate_polygon_normals(); mesh->calculate_vertex_normals(); return mesh; }
int NewBooleanMesh(Scene *scene, Base *base, Base *base_select, int int_op_type) { Mesh *me_new; int a, maxmat, totmat= 0; Object *ob_new, *ob, *ob_select; Material **mat; DerivedMesh *result; DerivedMesh *dm_select; DerivedMesh *dm; ob= base->object; ob_select= base_select->object; dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); dm_select = mesh_create_derived_view(scene, ob_select, 0); // no modifiers in editmode ?? maxmat= ob->totcol + ob_select->totcol; mat= (Material**)MEM_mallocN(sizeof(Material*)*maxmat, "NewBooleanMeshMat"); /* put some checks in for nice user feedback */ if (dm == NULL || dm_select == NULL) return 0; if (!dm->getNumFaces(dm) || !dm_select->getNumFaces(dm_select)) { MEM_freeN(mat); return -1; } result= NewBooleanDerivedMesh_intern(dm, ob, dm_select, ob_select, int_op_type, mat, &totmat); if (result == NULL) { MEM_freeN(mat); return 0; } /* create a new blender mesh object - using 'base' as a template */ ob_new= AddNewBlenderMesh(scene, base_select); me_new= ob_new->data; DM_to_mesh(result, me_new); result->release(result); dm->release(dm); dm_select->release(dm_select); /* add materials to object */ for (a = 0; a < totmat; a++) assign_material(ob_new, mat[a], a+1); MEM_freeN(mat); /* update dag */ DAG_id_tag_update(&ob_new->id, OB_RECALC_DATA); return 1; }
/* /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// */ static void get_material_cb(bContext *C, void *poin, void *poin2) { Scene *scene = CTX_data_scene(C); Main *bmain = CTX_data_main(C); bool not_set = true; Object *cur_object; Object *ob; Material *ma; cur_object = scene->basact ? scene->basact->object : 0; if(cur_object->actcol > 0) { ob = (Object*)cur_object; if(cur_object->totcol >= cur_object->actcol && ob->mat[cur_object->actcol - 1]) { bNodeTree *ntree = ob->mat[cur_object->actcol - 1]->nodetree; if(!ob->mat[cur_object->actcol - 1]->use_nodes) ob->mat[cur_object->actcol - 1]->use_nodes = true; if (ntree) { get_material(bmain, C, scene, ntree, (char*)poin, (int)poin2); not_set = false; } } if(not_set) { ID *id_me = cur_object->data; if (GS(id_me->name) == ID_ME) { Mesh *me = (Mesh*)id_me; if(me->totcol >= cur_object->actcol && me->mat[cur_object->actcol - 1]) { bNodeTree *ntree = me->mat[cur_object->actcol - 1]->nodetree; if(!me->mat[cur_object->actcol - 1]->use_nodes) me->mat[cur_object->actcol - 1]->use_nodes = true; if (ntree) { get_material(bmain, C, scene, ntree, (char*)poin, (int)poin2); not_set = false; } } } } } if(not_set) { ob = (Object*)cur_object; ma = BKE_material_add(bmain, DATA_("LDB Material")); ma->use_nodes = true; ma->nodetree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname); assign_material(ob, ma, ob->totcol + 1, BKE_MAT_ASSIGN_USERPREF); WM_event_add_notifier(C, NC_MATERIAL | NA_ADDED, ma); get_material(bmain, C, scene, ma->nodetree, (char*)poin, (int)poin2); } } /* get_material_cb() */
//------------------------------------------------------------------------------ /// Parametrically load a Quad mesh, e.g. a flat square Mesh* MeshLoader::quad( const double& width, const double& height, Material* material, const EMeshLoaderMaterialOp& material_op ) { Mesh* mesh = new Mesh(); // ----- Generate Vertices ------ double halfx = width / 2.0; double halfy = height / 2.0; mesh->appendVertex( new Vertex( -halfx, -halfy, 0.0 ) ); mesh->appendVertex( new Vertex( halfx, -halfy, 0.0 ) ); mesh->appendVertex( new Vertex( halfx, halfy, 0.0 ) ); mesh->appendVertex( new Vertex( -halfx, halfy, 0.0 ) ); mesh->appendTextureVertex( new Vector3( 1.0, 0.0, 0.0 ) ); // vert 0 mesh->appendTextureVertex( new Vector3( 0.0, 0.0, 0.0 ) ); // vert 1 mesh->appendTextureVertex( new Vector3( 0.0, 1.0, 0.0 ) ); // vert 2 mesh->appendTextureVertex( new Vector3( 1.0, 1.0, 0.0 ) ); // vert 3 // ------------------------------ // ----- Generate Polygons ------ Polygon* poly = new Polygon(); assign_material( mesh, poly, material, material_op ); poly->addVertex( 0 ); poly->addVertex( 1 ); poly->addVertex( 2 ); poly->addVertex( 3 ); poly->addTextureVertex( 0 ); poly->addTextureVertex( 1 ); poly->addTextureVertex( 2 ); poly->addTextureVertex( 3 ); mesh->appendPolygon( poly ); // ------------------------------ mesh->calculate_polygon_normals(); mesh->calculate_vertex_normals(); return mesh; }
/** * We do not know in advance which objects will share geometries. * And we do not know either if the objects which share geometries * come along with different materials. So we first create the objects * and assign the materials to Object, then in a later cleanup we decide * which materials shall be moved to the created geometries. Also see * optimize_material_assignements() above. */ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial, std::map<COLLADAFW::UniqueId, Material *>& uid_material_map, Object *ob, const COLLADAFW::UniqueId *geom_uid, char *layername, MTFace *texture_face, std::map<Material *, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index) { MTex *color_texture = NULL; Mesh *me = (Mesh *)ob->data; const COLLADAFW::UniqueId& ma_uid = cmaterial.getReferencedMaterial(); // do we know this material? if (uid_material_map.find(ma_uid) == uid_material_map.end()) { fprintf(stderr, "Cannot find material by UID.\n"); return NULL; } // first time we get geom_uid, ma_uid pair. Save for later check. materials_mapped_to_geom.insert(std::pair<COLLADAFW::UniqueId, COLLADAFW::UniqueId>(*geom_uid, ma_uid)); Material *ma = uid_material_map[ma_uid]; // Attention! This temporaly assigns material to object on purpose! // See note above. ob->actcol=0; assign_material(ob, ma, mat_index + 1, BKE_MAT_ASSIGN_OBJECT); COLLADAFW::TextureCoordinateBindingArray& tex_array = cmaterial.getTextureCoordinateBindingArray(); TexIndexTextureArrayMap texindex_texarray_map = material_texture_mapping_map[ma]; unsigned int i; // loop through <bind_vertex_inputs> for (i = 0; i < tex_array.getCount(); i++) { color_texture = assign_textures_to_uvlayer(tex_array[i], me, texindex_texarray_map, color_texture); } // set texture face if (color_texture && strlen((color_texture)->uvname) && !STREQ(layername, color_texture->uvname)) { texture_face = (MTFace *)CustomData_get_layer_named(&me->fdata, CD_MTFACE, color_texture->uvname); strcpy(layername, color_texture->uvname); } MaterialIdPrimitiveArrayMap& mat_prim_map = geom_uid_mat_mapping_map[*geom_uid]; COLLADAFW::MaterialId mat_id = cmaterial.getMaterialId(); // assign material indices to mesh faces if (mat_prim_map.find(mat_id) != mat_prim_map.end()) { std::vector<Primitive>& prims = mat_prim_map[mat_id]; std::vector<Primitive>::iterator it; for (it = prims.begin(); it != prims.end(); it++) { Primitive& prim = *it; MPoly *mpoly = prim.mpoly; for (i = 0; i < prim.totpoly; i++, mpoly++) { mpoly->mat_nr = mat_index; // bind texture images to faces if (texture_face && color_texture) { texture_face->tpage = (Image *)color_texture->tex->ima; texture_face++; } } } } return texture_face; }
//------------------------------------------------------------------------------ /// Parametrically load a sphere mesh /// where arcsegments are the number of arclengths around the sphere, e.g. longitude /// and slices are the number of cross sections from pole to pole, e.g. latitude Mesh* MeshLoader::sphere( const double& radius, const unsigned int& arcsegments, const unsigned int& slices, Material* material, const EMeshLoaderMaterialOp& material_op ) { assert( radius > 0.0 && arcsegments > 1 && slices > 0 ); Mesh* mesh = new Mesh(); // ----- Generate Vertices ------ double dtheta = 2.0 * PI / (double) arcsegments; double theta = 0.0; double dphi = (double) PI / (double) (slices + 1); double phi = 0.0; double x, y, z; // Top pole vertex mesh->appendVertex( new Vertex( 0.0, radius, 0.0 ) ); // Arc segment and slice vertices for( unsigned int i = 0; i < slices; i++ ) { theta = 0.0; phi += dphi; for( unsigned int i = 0; i < arcsegments; i++ ) { x = sin(phi) * cos(theta); y = cos(phi); z = sin(phi) * sin(theta); theta += dtheta; mesh->appendVertex( new Vertex( x * radius, y * radius, z * radius ) ); } } // Bottom pole vertex mesh->appendVertex( new Vertex( 0.0, -radius, 0.0 ) ); // ------------------------------ // ----- Generate Polygons ------ for( unsigned int slice = 0; slice < slices + 1; slice++ ) { for( unsigned int i = 0; i < arcsegments; i++ ) { Polygon* p = new Polygon(); assign_material( mesh, p, material, material_op ); if( slice == 0 ) { // Top Cap - Triads p->addVertex( 0 ); if( i < arcsegments - 1 ) p->addVertex( i + 2 ); else p->addVertex( 1 ); p->addVertex( i + 1 ); } else if( slice > 0 && slice < slices ) { // Quads p->addVertex( arcsegments * (slice - 1) + i + 1 ); if( i < arcsegments - 1 ) { p->addVertex( arcsegments * (slice - 1) + i + 2 ); p->addVertex( arcsegments * (slice) + i + 2 ); } else { p->addVertex( arcsegments * (slice - 1) + 1 ); p->addVertex( arcsegments * (slice) + 1 ); } p->addVertex( arcsegments * (slice) + i + 1 ); } else if( slice == slices ) { // Bottom Cap - Triads p->addVertex( arcsegments * (slice - 1) + i + 1 ); if( i < arcsegments - 1 ) { p->addVertex( arcsegments * (slice - 1) + i + 2 ); } else { p->addVertex( arcsegments * (slice - 1) + 1 ); } p->addVertex( mesh->vertexCount() - 1 ); } p->flip(); // the sphere is wrong handed for OpenGL. Flip here solves for all polys mesh->appendPolygon( p ); } } // ------------------------------ mesh->calculate_polygon_normals(); mesh->calculate_vertex_normals(); return mesh; }
//------------------------------------------------------------------------------ /// Parametrically load a box mesh Mesh* MeshLoader::box( const double& width, const double& height, const double& depth, Material* material, const EMeshLoaderMaterialOp& material_op ) { Mesh* mesh = new Mesh(); // ----- Generate Vertices ------ double halfx, halfy, halfz; halfx = width / 2.0; halfy = height / 2.0; halfz = depth / 2.0; mesh->appendVertex( new Vertex( -halfx, -halfy, -halfz ) ); mesh->appendVertex( new Vertex( halfx, -halfy, -halfz ) ); mesh->appendVertex( new Vertex( halfx, halfy, -halfz ) ); mesh->appendVertex( new Vertex( -halfx, halfy, -halfz ) ); mesh->appendVertex( new Vertex( -halfx, -halfy, halfz ) ); mesh->appendVertex( new Vertex( halfx, -halfy, halfz ) ); mesh->appendVertex( new Vertex( halfx, halfy, halfz ) ); mesh->appendVertex( new Vertex( -halfx, halfy, halfz ) ); // ------------------------------ // ----- Generate Polygons ------ for ( unsigned int i = 0; i < 6; i++ ) { Polygon* poly = new Polygon(); assign_material( mesh, poly, material, material_op ); if( i == 0 ) { poly->addVertex( 0 ); poly->addVertex( 1 ); poly->addVertex( 2 ); poly->addVertex( 3 ); } else if( i == 1 ) { poly->addVertex( 0 ); poly->addVertex( 4 ); poly->addVertex( 5 ); poly->addVertex( 1 ); } else if( i == 2 ) { poly->addVertex( 0 ); poly->addVertex( 3 ); poly->addVertex( 7 ); poly->addVertex( 4 ); } else if( i == 3 ) { poly->addVertex( 6 ); poly->addVertex( 5 ); poly->addVertex( 4 ); poly->addVertex( 7 ); } else if( i == 4 ) { poly->addVertex( 6 ); poly->addVertex( 7 ); poly->addVertex( 3 ); poly->addVertex( 2 ); } else if( i == 5 ) { poly->addVertex( 6 ); poly->addVertex( 2 ); poly->addVertex( 1 ); poly->addVertex( 5 ); } mesh->appendPolygon( poly ); } // ------------------------------ //calculate the surface normals mesh->calculate_polygon_normals(); mesh->calculate_vertex_normals(); return mesh; }
//------------------------------------------------------------------------------ /// Parametrically load a cylinder mesh Mesh* MeshLoader::cylinder( const double& radius, const double& height, const unsigned int& arcsegments, Material* material, const EMeshLoaderMaterialOp& material_op ) { Mesh* mesh = new Mesh(); // ----- Generate Vertices ------ double halfz = height / 2.0; double dtheta = 2.0 * PI / (double) arcsegments; double theta = 0.0; double x, y; for( unsigned int i = 0; i < arcsegments; i++ ) { x = cos(theta) * radius; y = sin(theta) * radius; theta += dtheta; mesh->appendVertex( new Vertex( x, y, halfz ) ); mesh->appendVertex( new Vertex( x, y, -halfz ) ); } // ------------------------------ // ----- Generate Polygons ------ Polygon* poly; // cap poly = new Polygon(); assign_material( mesh, poly, material, material_op ); for( unsigned int i = 0; i < arcsegments; i++ ) { poly->addVertex( i * 2 ); } poly->flip(); mesh->appendPolygon( poly ); for( unsigned int i = 0; i < arcsegments; i++ ) { poly = new Polygon(); assign_material( mesh, poly, material, material_op ); if(i == 0) { poly->addVertex( 2 ); poly->addVertex( 3 ); poly->addVertex( 1 ); poly->addVertex( 0 ); } else if( i == arcsegments - 1) { poly->addVertex( i*2 ); poly->addVertex( 0 ); poly->addVertex( 1 ); poly->addVertex( i*2+1 ); } else { poly->addVertex( (i+1)*2 ); poly->addVertex( (i+1)*2+1 ); poly->addVertex( i*2+1 ); poly->addVertex( i*2 ); } mesh->appendPolygon( poly ); } // cap poly = new Polygon(); assign_material( mesh, poly, material, material_op ); for( unsigned int i = 0; i < arcsegments; i++ ) { poly->addVertex( i * 2 + 1 ); } //poly->flip(); mesh->appendPolygon( poly ); // ------------------------------ mesh->calculate_polygon_normals(); mesh->calculate_vertex_normals(); return mesh; }