void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me) { if (!CustomData_has_layer(&me->fdata, CD_MCOL)) return; MFace *f; int totcolor = 0, i, j; for (i = 0, f = me->mface; i < me->totface; i++, f++) totcolor += f->v4 ? 4 : 3; COLLADASW::FloatSourceF source(mSW); source.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::COLOR)); source.setArrayId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::COLOR) + ARRAY_ID_SUFFIX); source.setAccessorCount(totcolor); source.setAccessorStride(3); COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); param.push_back("R"); param.push_back("G"); param.push_back("B"); source.prepareToAppendValues(); int index = CustomData_get_active_layer_index(&me->fdata, CD_MCOL); MCol *mcol = (MCol*)me->fdata.layers[index].data; MCol *c = mcol; for (i = 0, f = me->mface; i < me->totface; i++, c += 4, f++) for (j = 0; j < (f->v4 ? 4 : 3); j++) source.appendValues(c[j].b / 255.0f, c[j].g / 255.0f, c[j].r / 255.0f); source.finish(); }
void InstanceWriter::add_material_bindings(COLLADASW::BindMaterial& bind_material, Object *ob, bool active_uv_only) { for (int a = 0; a < ob->totcol; a++) { Material *ma = give_current_material(ob, a + 1); COLLADASW::InstanceMaterialList& iml = bind_material.getInstanceMaterialList(); if (ma) { std::string matid(get_material_id(ma)); matid = translate_id(matid); std::ostringstream ostr; ostr << matid; COLLADASW::InstanceMaterial im(ostr.str(), COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, matid)); // create <bind_vertex_input> for each uv map Mesh *me = (Mesh *)ob->data; int totlayer = CustomData_number_of_layers(&me->fdata, CD_MTFACE); int map_index = 0; int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE) -1; for (int b = 0; b < totlayer; b++) { if (!active_uv_only || b == active_uv_index) { char *name = bc_CustomData_get_layer_name(&me->fdata, CD_MTFACE, b); im.push_back(COLLADASW::BindVertexInput(name, "TEXCOORD", map_index++)); } } iml.push_back(im); } } }
char *bc_CustomData_get_active_layer_name(const CustomData *data, int type) { /* get the layer index of the active layer of type */ int layer_index = CustomData_get_active_layer_index(data, type); if (layer_index < 0) return NULL; return data->layers[layer_index].name; }
int ED_mesh_color_remove(bContext *C, Object *ob, Mesh *me) { CustomDataLayer *cdl; int index; index= CustomData_get_active_layer_index(&me->fdata, CD_MCOL); cdl= (index == -1)? NULL: &me->fdata.layers[index]; if(!cdl) return 0; delete_customdata_layer(C, ob, cdl); DAG_id_flush_update(&me->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); return 1; }
void validate_layer_name(const CustomData *data, int type, char *name, char *outname) { int index = -1; /* if a layer name was given, try to find that layer */ if(name[0]) index = CustomData_get_named_layer_index(data, type, name); if(index < 0) { /* either no layer was specified, or the layer we want has been * deleted, so assign the active layer to name */ index = CustomData_get_active_layer_index(data, type); strcpy(outname, data->layers[index].name); } else strcpy(outname, name); }
static PyObject *bpy_bmlayercollection_active_get(BPy_BMLayerItem *self, void *UNUSED(flag)) { CustomData *data; int index; BPY_BM_CHECK_OBJ(self); data = bpy_bm_customdata_get(self->bm, self->htype); index = CustomData_get_active_layer_index(data, self->type); /* absolute */ if (index != -1) { index -= CustomData_get_layer_index(data, self->type); /* make relative */ return BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index); } else { Py_RETURN_NONE; } }
int ED_mesh_color_remove(bContext *C, Object *ob, Mesh *me) { CustomData *data= (me->edit_mesh)? &me->edit_mesh->fdata: &me->fdata; CustomDataLayer *cdl; int index; index= CustomData_get_active_layer_index(data, CD_MCOL); cdl= (index == -1)? NULL: &data->layers[index]; if(!cdl) return 0; delete_customdata_layer(C, ob, cdl); DAG_id_tag_update(&me->id, 0); WM_event_add_notifier(C, NC_GEOM|ND_DATA, me); return 1; }
//creates <source> for texcoords void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me) { int totpoly = me->totpoly; int totuv = me->totloop; MPoly *mpolys = me->mpoly; int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); // write <source> for each layer // each <source> will get id like meshName + "map-channel-1" int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV); for (int a = 0; a < num_layers; a++) { if (!this->export_settings->active_uv_only || a == active_uv_index) { MLoopUV *mloops = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, a); COLLADASW::FloatSourceF source(mSW); std::string layer_id = makeTexcoordSourceId(geom_id, a, this->export_settings->active_uv_only); source.setId(layer_id); source.setArrayId(layer_id + ARRAY_ID_SUFFIX); source.setAccessorCount(totuv); source.setAccessorStride(2); COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); param.push_back("S"); param.push_back("T"); source.prepareToAppendValues(); for (int index = 0; index < totpoly; index++) { MPoly *mpoly = mpolys+index; MLoopUV *mloop = mloops+mpoly->loopstart; for (int j = 0; j < mpoly->totloop; j++) { source.appendValues(mloop[j].uv[0], mloop[j].uv[1]); } } source.finish(); } } }
static PyObject *bpy_bmlayercollection_verify(BPy_BMLayerCollection *self) { int index; CustomData *data; BPY_BM_CHECK_OBJ(self); data = bpy_bm_customdata_get(self->bm, self->htype); index = CustomData_get_layer_index(data, self->type); if (index == -1) { BM_data_layer_add(self->bm, data, self->type); index = 0; } else { index = CustomData_get_active_layer_index(data, self->type) - index; /* make relative */ } BLI_assert(index >= 0); return BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index); }
void ImagesExporter::export_UV_Images() { std::set<Image *> uv_textures; LinkNode *node; bool use_texture_copies = this->export_settings->use_texture_copies; bool active_uv_only = this->export_settings->active_uv_only; for (node = this->export_settings->export_set; node; node = node->next) { Object *ob = (Object *)node->link; if (ob->type == OB_MESH && ob->totcol) { Mesh *me = (Mesh *) ob->data; BKE_mesh_tessface_ensure(me); int active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY); for (int i = 0; i < me->pdata.totlayer; i++) { if (me->pdata.layers[i].type == CD_MTEXPOLY) { if (!active_uv_only || active_uv_layer == i) { MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data; for (int j = 0; j < me->totpoly; j++, txface++) { Image *ima = txface->tpage; if (ima == NULL) continue; bool not_in_list = uv_textures.find(ima) == uv_textures.end(); if (not_in_list) { uv_textures.insert(ima); export_UV_Image(ima, use_texture_copies); } } } } } } } }
void EffectsExporter::operator()(Material *ma, Object *ob) { // create a list of indices to textures of type TEX_IMAGE std::vector<int> tex_indices; if (this->export_settings->include_material_textures) createTextureIndices(ma, tex_indices); openEffect(translate_id(id_name(ma)) + "-effect"); COLLADASW::EffectProfile ep(mSW); ep.setProfileType(COLLADASW::EffectProfile::COMMON); ep.openProfile(); // set shader type - one of three blinn, phong or lambert if (ma->spec > 0.0f) { if (ma->spec_shader == MA_SPEC_BLINN) { writeBlinn(ep, ma); } else { // \todo figure out handling of all spec+diff shader combos blender has, for now write phong // for now set phong in case spec shader is not blinn writePhong(ep, ma); } } else { if (ma->diff_shader == MA_DIFF_LAMBERT) { writeLambert(ep, ma); } else { // \todo figure out handling of all spec+diff shader combos blender has, for now write phong writePhong(ep, ma); } } // index of refraction if (ma->mode & MA_RAYTRANSP) { ep.setIndexOfRefraction(ma->ang, false, "index_of_refraction"); } else { ep.setIndexOfRefraction(1.0f, false, "index_of_refraction"); } COLLADASW::ColorOrTexture cot; // transparency if (ma->mode & MA_TRANSP) { // Tod: because we are in A_ONE mode transparency is calculated like this: ep.setTransparency(ma->alpha, false, "transparency"); // cot = getcol(1.0f, 1.0f, 1.0f, 1.0f); // ep.setTransparent(cot); } // emission cot = getcol(ma->emit, ma->emit, ma->emit, 1.0f); ep.setEmission(cot, false, "emission"); // diffuse multiplied by diffuse intensity cot = getcol(ma->r * ma->ref, ma->g * ma->ref, ma->b * ma->ref, 1.0f); ep.setDiffuse(cot, false, "diffuse"); // ambient /* ma->ambX is calculated only on render, so lets do it here manually and not rely on ma->ambX. */ if (this->scene->world) cot = getcol(this->scene->world->ambr * ma->amb, this->scene->world->ambg * ma->amb, this->scene->world->ambb * ma->amb, 1.0f); else cot = getcol(ma->amb, ma->amb, ma->amb, 1.0f); ep.setAmbient(cot, false, "ambient"); // reflective, reflectivity if (ma->mode & MA_RAYMIRROR) { cot = getcol(ma->mirr, ma->mirg, ma->mirb, 1.0f); ep.setReflective(cot); ep.setReflectivity(ma->ray_mirror); } // else { // cot = getcol(ma->specr, ma->specg, ma->specb, 1.0f); // ep.setReflective(cot); // ep.setReflectivity(ma->spec); // } // specular if (ep.getShaderType() != COLLADASW::EffectProfile::LAMBERT) { cot = getcol(ma->specr * ma->spec, ma->specg * ma->spec, ma->specb * ma->spec, 1.0f); ep.setSpecular(cot, false, "specular"); } // XXX make this more readable if possible // create <sampler> and <surface> for each image COLLADASW::Sampler samplers[MAX_MTEX]; //COLLADASW::Surface surfaces[MAX_MTEX]; //void *samp_surf[MAX_MTEX][2]; void *samp_surf[MAX_MTEX][1]; // image to index to samp_surf map // samp_surf[index] stores 2 pointers, sampler and surface std::map<std::string, int> im_samp_map; unsigned int a, b; for (a = 0, b = 0; a < tex_indices.size(); a++) { MTex *t = ma->mtex[tex_indices[a]]; Image *ima = t->tex->ima; // Image not set for texture if (!ima) continue; std::string key(id_name(ima)); key = translate_id(key); // create only one <sampler>/<surface> pair for each unique image if (im_samp_map.find(key) == im_samp_map.end()) { // //<newparam> <surface> <init_from> // COLLADASW::Surface surface(COLLADASW::Surface::SURFACE_TYPE_2D, // key + COLLADASW::Surface::SURFACE_SID_SUFFIX); // COLLADASW::SurfaceInitOption sio(COLLADASW::SurfaceInitOption::INIT_FROM); // sio.setImageReference(key); // surface.setInitOption(sio); // COLLADASW::NewParamSurface surface(mSW); // surface->setParamType(COLLADASW::CSW_SURFACE_TYPE_2D); //<newparam> <sampler> <source> COLLADASW::Sampler sampler(COLLADASW::Sampler::SAMPLER_TYPE_2D, key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX, key + COLLADASW::Sampler::SURFACE_SID_SUFFIX); sampler.setImageId(key); // copy values to arrays since they will live longer samplers[a] = sampler; //surfaces[a] = surface; // store pointers so they can be used later when we create <texture>s samp_surf[b][0] = &samplers[a]; //samp_surf[b][1] = &surfaces[a]; im_samp_map[key] = b; b++; } } std::set<Image *> uv_textures; if (ob->type == OB_MESH && ob->totcol && this->export_settings->include_uv_textures) { bool active_uv_only = this->export_settings->active_uv_only; Mesh *me = (Mesh *) ob->data; int active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY); BKE_mesh_tessface_ensure(me); for (int i = 0; i < me->pdata.totlayer; i++) { if (!active_uv_only || active_uv_layer == i) { if (me->pdata.layers[i].type == CD_MTEXPOLY) { MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data; MFace *mface = me->mface; for (int j = 0; j < me->totpoly; j++, mface++, txface++) { Material *mat = give_current_material(ob, mface->mat_nr + 1); if (mat != ma) continue; Image *ima = txface->tpage; if (ima == NULL) continue; bool not_in_list = uv_textures.find(ima)==uv_textures.end(); if (not_in_list) { std::string name = id_name(ima); std::string key(name); key = translate_id(key); // create only one <sampler>/<surface> pair for each unique image if (im_samp_map.find(key) == im_samp_map.end()) { //<newparam> <sampler> <source> COLLADASW::Sampler sampler(COLLADASW::Sampler::SAMPLER_TYPE_2D, key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX, key + COLLADASW::Sampler::SURFACE_SID_SUFFIX); sampler.setImageId(key); samplers[a] = sampler; samp_surf[b][0] = &samplers[a]; im_samp_map[key] = b; b++; a++; uv_textures.insert(ima); } } } } } } } // used as fallback when MTex->uvname is "" (this is pretty common) // it is indeed the correct value to use in that case std::string active_uv(getActiveUVLayerName(ob)); // write textures // XXX very slow for (a = 0; a < tex_indices.size(); a++) { MTex *t = ma->mtex[tex_indices[a]]; Image *ima = t->tex->ima; std::string key(id_name(ima)); key = translate_id(key); int i = im_samp_map[key]; std::string uvname = strlen(t->uvname) ? t->uvname : active_uv; COLLADASW::Sampler *sampler = (COLLADASW::Sampler *)samp_surf[i][0]; writeTextures(ep, key, sampler, t, ima, uvname); } std::set<Image *>::iterator uv_t_iter; for (uv_t_iter = uv_textures.begin(); uv_t_iter != uv_textures.end(); uv_t_iter++ ) { Image *ima = *uv_t_iter; std::string key(id_name(ima)); key = translate_id(key); int i = im_samp_map[key]; COLLADASW::Sampler *sampler = (COLLADASW::Sampler *)samp_surf[i][0]; ep.setDiffuse(createTexture(ima, active_uv, sampler), false, "diffuse"); } // performs the actual writing ep.addProfileElements(); bool twoSided = false; if (ob->type == OB_MESH && ob->data) { Mesh *me = (Mesh *)ob->data; if (me->flag & ME_TWOSIDED) twoSided = true; } if (twoSided) ep.addExtraTechniqueParameter("GOOGLEEARTH", "double_sided", 1); ep.addExtraTechniques(mSW); ep.closeProfile(); if (twoSided) mSW->appendTextBlock("<extra><technique profile=\"MAX3D\"><double_sided>1</double_sided></technique></extra>"); closeEffect(); }
HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma, const float vec[3], const float vec1[3], const float *orco, const float *uvco, float hasize, float vectsize, int seed, const float pa_co[3]) { const bool skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0; HaloRen *har; MTex *mtex; float tin, tr, tg, tb, ta; float xn, yn, zn, texvec[3], hoco[4], hoco1[4], in[3], tex[3], out[3]; int i, hasrgb; if (hasize==0.0f) return NULL; projectverto(vec, re->winmat, hoco); if (hoco[3]==0.0f) return NULL; if (vec1) { projectverto(vec1, re->winmat, hoco1); if (hoco1[3]==0.0f) return NULL; } har= RE_findOrAddHalo(obr, obr->tothalo++); copy_v3_v3(har->co, vec); har->hasize= hasize; /* actual projectvert is done in function project_renderdata() because of parts/border/pano */ /* we do it here for sorting of halos */ zn= hoco[3]; har->xs= 0.5f*re->winx*(hoco[0]/zn); har->ys= 0.5f*re->winy*(hoco[1]/zn); har->zs= 0x7FFFFF*(hoco[2]/zn); har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn); /* halovect */ if (vec1) { har->type |= HA_VECT; xn= har->xs - 0.5f*re->winx*(hoco1[0]/hoco1[3]); yn= har->ys - 0.5f*re->winy*(hoco1[1]/hoco1[3]); if (xn==0.0f || (xn==0.0f && yn==0.0f)) zn= 0.0; else zn = atan2f(yn, xn); har->sin = sinf(zn); har->cos = cosf(zn); zn= len_v3v3(vec1, vec)*0.5f; har->hasize= vectsize*zn + (1.0f-vectsize)*hasize; sub_v3_v3v3(har->no, vec, vec1); normalize_v3(har->no); } if (ma->mode & MA_HALO_XALPHA) har->type |= HA_XALPHA; har->alfa= ma->alpha; har->r= ma->r; har->g= ma->g; har->b= ma->b; har->add= (255.0f*ma->add); har->mat= ma; har->hard= ma->har; har->seed= seed % 256; if (ma->mode & MA_STAR) har->starpoints= ma->starc; if (ma->mode & MA_HALO_LINES) har->linec= ma->linec; if (ma->mode & MA_HALO_RINGS) har->ringc= ma->ringc; if (ma->mode & MA_HALO_FLARE) har->flarec= ma->flarec; if ((ma->mode & MA_HALOTEX) && ma->mtex[0]) har->tex= 1; for (i=0; i<MAX_MTEX; i++) if (ma->mtex[i] && (ma->septex & (1<<i))==0) { mtex= ma->mtex[i]; copy_v3_v3(texvec, vec); if (mtex->texco & TEXCO_NORM) { ; } else if (mtex->texco & TEXCO_OBJECT) { if (mtex->object) mul_m4_v3(mtex->object->imat_ren, texvec); } else if (mtex->texco & TEXCO_GLOB) { copy_v3_v3(texvec, vec); } else if (mtex->texco & TEXCO_UV && uvco) { int uv_index=CustomData_get_named_layer_index(&dm->faceData, CD_MTFACE, mtex->uvname); if (uv_index<0) uv_index=CustomData_get_active_layer_index(&dm->faceData, CD_MTFACE); uv_index-=CustomData_get_layer_index(&dm->faceData, CD_MTFACE); texvec[0]=2.0f*uvco[2*uv_index]-1.0f; texvec[1]=2.0f*uvco[2*uv_index+1]-1.0f; texvec[2]=0.0f; } else if (mtex->texco & TEXCO_PARTICLE) { /* particle coordinates in range [0, 1] */ texvec[0] = 2.f * pa_co[0] - 1.f; texvec[1] = 2.f * pa_co[1] - 1.f; texvec[2] = pa_co[2]; } else if (orco) { copy_v3_v3(texvec, orco); } hasrgb = externtex(mtex, texvec, &tin, &tr, &tg, &tb, &ta, 0, re->pool, skip_load_image); //yn= tin*mtex->colfac; //zn= tin*mtex->alphafac; if (mtex->mapto & MAP_COL) { tex[0]=tr; tex[1]=tg; tex[2]=tb; out[0]=har->r; out[1]=har->g; out[2]=har->b; texture_rgb_blend(in, tex, out, tin, mtex->colfac, mtex->blendtype); // zn= 1.0-yn; //har->r= (yn*tr+ zn*ma->r); //har->g= (yn*tg+ zn*ma->g); //har->b= (yn*tb+ zn*ma->b); har->r= in[0]; har->g= in[1]; har->b= in[2]; } /* alpha returned, so let's use it instead of intensity */ if (hasrgb) tin = ta; if (mtex->mapto & MAP_ALPHA) har->alfa = texture_value_blend(mtex->def_var, har->alfa, tin, mtex->alphafac, mtex->blendtype); if (mtex->mapto & MAP_HAR) har->hard = 1.0f+126.0f*texture_value_blend(mtex->def_var, ((float)har->hard)/127.0f, tin, mtex->hardfac, mtex->blendtype); if (mtex->mapto & MAP_RAYMIRR) har->hasize = 100.0f*texture_value_blend(mtex->def_var, har->hasize/100.0f, tin, mtex->raymirrfac, mtex->blendtype); if (mtex->mapto & MAP_TRANSLU) { float add = texture_value_blend(mtex->def_var, (float)har->add/255.0f, tin, mtex->translfac, mtex->blendtype); CLAMP(add, 0.f, 1.f); har->add = 255.0f*add; } /* now what on earth is this good for?? */ //if (mtex->texco & 16) { // har->alfa= tin; //} } har->pool = re->pool; har->skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0; return har; }
int bc_get_active_UVLayer(Object *ob) { Mesh *me = (Mesh *)ob->data; return CustomData_get_active_layer_index(&me->fdata, CD_MTFACE); }
static void delete_customdata_layer(bContext *C, Object *ob, CustomDataLayer *layer) { Mesh *me = ob->data; CustomData *data= (me->edit_mesh)? &me->edit_mesh->fdata: &me->fdata; void *actlayerdata, *rndlayerdata, *clonelayerdata, *stencillayerdata, *layerdata=layer->data; int type= layer->type; int index= CustomData_get_layer_index(data, type); int i, actindex, rndindex, cloneindex, stencilindex; /* ok, deleting a non-active layer needs to preserve the active layer indices. to do this, we store a pointer to the .data member of both layer and the active layer, (to detect if we're deleting the active layer or not), then use the active layer data pointer to find where the active layer has ended up. this is necassary because the deletion functions only support deleting the active layer. */ actlayerdata = data->layers[CustomData_get_active_layer_index(data, type)].data; rndlayerdata = data->layers[CustomData_get_render_layer_index(data, type)].data; clonelayerdata = data->layers[CustomData_get_clone_layer_index(data, type)].data; stencillayerdata = data->layers[CustomData_get_stencil_layer_index(data, type)].data; CustomData_set_layer_active(data, type, layer - &data->layers[index]); if(me->edit_mesh) { EM_free_data_layer(me->edit_mesh, data, type); } else { CustomData_free_layer_active(data, type, me->totface); mesh_update_customdata_pointers(me); } if(!CustomData_has_layer(data, type) && (type == CD_MCOL && (ob->mode & OB_MODE_VERTEX_PAINT))) ED_object_toggle_modes(C, OB_MODE_VERTEX_PAINT); /* reconstruct active layer */ if (actlayerdata != layerdata) { /* find index */ actindex = CustomData_get_layer_index(data, type); for (i=actindex; i<data->totlayer; i++) { if (data->layers[i].data == actlayerdata) { actindex = i - actindex; break; } } /* set index */ CustomData_set_layer_active(data, type, actindex); } if (rndlayerdata != layerdata) { /* find index */ rndindex = CustomData_get_layer_index(data, type); for (i=rndindex; i<data->totlayer; i++) { if (data->layers[i].data == rndlayerdata) { rndindex = i - rndindex; break; } } /* set index */ CustomData_set_layer_render(data, type, rndindex); } if (clonelayerdata != layerdata) { /* find index */ cloneindex = CustomData_get_layer_index(data, type); for (i=cloneindex; i<data->totlayer; i++) { if (data->layers[i].data == clonelayerdata) { cloneindex = i - cloneindex; break; } } /* set index */ CustomData_set_layer_clone(data, type, cloneindex); } if (stencillayerdata != layerdata) { /* find index */ stencilindex = CustomData_get_layer_index(data, type); for (i=stencilindex; i<data->totlayer; i++) { if (data->layers[i].data == stencillayerdata) { stencilindex = i - stencilindex; break; } } /* set index */ CustomData_set_layer_stencil(data, type, stencilindex); } }
void InstanceWriter::add_material_bindings(COLLADASW::BindMaterial& bind_material, Object *ob, bool active_uv_only, BC_export_texture_type export_texture_type) { bool all_uv_layers = !active_uv_only; COLLADASW::InstanceMaterialList& iml = bind_material.getInstanceMaterialList(); if (export_texture_type == BC_TEXTURE_TYPE_UV) { std::set<Image *> uv_images = bc_getUVImages(ob, all_uv_layers); std::set<Image *>::iterator uv_images_iter; for (uv_images_iter = uv_images.begin(); uv_images_iter != uv_images.end(); uv_images_iter++) { Image *ima = *uv_images_iter; std::string matid(id_name(ima)); matid = get_material_id_from_id(matid); std::ostringstream ostr; ostr << matid; COLLADASW::InstanceMaterial im(ostr.str(), COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, matid)); // create <bind_vertex_input> for each uv map Mesh *me = (Mesh *)ob->data; int totlayer = CustomData_number_of_layers(&me->fdata, CD_MTFACE); int map_index = 0; int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE) - 1; for (int b = 0; b < totlayer; b++) { if (!active_uv_only || b == active_uv_index) { char *name = bc_CustomData_get_layer_name(&me->fdata, CD_MTFACE, b); im.push_back(COLLADASW::BindVertexInput(name, "TEXCOORD", map_index++)); } } iml.push_back(im); } } else { for (int a = 0; a < ob->totcol; a++) { Material *ma = give_current_material(ob, a + 1); if (ma) { std::string matid(get_material_id(ma)); matid = translate_id(matid); std::ostringstream ostr; ostr << matid; COLLADASW::InstanceMaterial im(ostr.str(), COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, matid)); // create <bind_vertex_input> for each uv map Mesh *me = (Mesh *)ob->data; int totlayer = CustomData_number_of_layers(&me->fdata, CD_MTFACE); int map_index = 0; int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE) - 1; for (int b = 0; b < totlayer; b++) { if (!active_uv_only || b == active_uv_index) { char *name = bc_CustomData_get_layer_name(&me->fdata, CD_MTFACE, b); im.push_back(COLLADASW::BindVertexInput(name, "TEXCOORD", map_index++)); } } iml.push_back(im); } } } }
/* if all is good tag image and return true */ static bool bake_object_check(Object *ob, ReportList *reports) { Image *image; void *lock; int i; if (ob->type != OB_MESH) { BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not a mesh", ob->id.name + 2); return false; } else { Mesh *me = (Mesh *)ob->data; if (CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV) == -1) { BKE_reportf(reports, RPT_ERROR, "No active UV layer found in the object \"%s\"", ob->id.name + 2); return false; } } for (i = 0; i < ob->totcol; i++) { bNodeTree *ntree = NULL; bNode *node = NULL; ED_object_get_active_image(ob, i + 1, &image, NULL, &node, &ntree); if (image) { ImBuf *ibuf; if (node) { if (BKE_node_is_connected_to_output(ntree, node)) { /* we don't return false since this may be a false positive * this can't be RPT_ERROR though, otherwise it prevents * multiple highpoly objects to be baked at once */ BKE_reportf(reports, RPT_INFO, "Circular dependency for image \"%s\" from object \"%s\"", image->id.name + 2, ob->id.name + 2); } } ibuf = BKE_image_acquire_ibuf(image, NULL, &lock); if (ibuf) { BKE_image_release_ibuf(image, ibuf, lock); } else { BKE_reportf(reports, RPT_ERROR, "Uninitialized image \"%s\" from object \"%s\"", image->id.name + 2, ob->id.name + 2); BKE_image_release_ibuf(image, ibuf, lock); return false; } } else { if (ob->mat[i]) { BKE_reportf(reports, RPT_ERROR, "No active image found in material \"%s\" (%d) for object \"%s\"", ob->mat[i]->id.name + 2, i, ob->id.name + 2); } else if (((Mesh *) ob->data)->mat[i]) { BKE_reportf(reports, RPT_ERROR, "No active image found in material \"%s\" (%d) for object \"%s\"", ((Mesh *) ob->data)->mat[i]->id.name + 2, i, ob->id.name + 2); } else { BKE_reportf(reports, RPT_ERROR, "No active image found in material (%d) for object \"%s\"", i, ob->id.name + 2); } return false; } image->id.tag |= LIB_TAG_DOIT; } return true; }
// powerful because it handles both cases when there is material and when there's not void GeometryExporter::createPolylist(short material_index, bool has_uvs, bool has_color, Object *ob, Mesh *me, std::string& geom_id, std::vector<BCPolygonNormalsIndices>& norind) { MPoly *mpolys = me->mpoly; MLoop *mloops = me->mloop; int totpolys = me->totpoly; // <vcount> int i; int faces_in_polylist = 0; std::vector<unsigned long> vcount_list; // count faces with this material for (i = 0; i < totpolys; i++) { MPoly *p = &mpolys[i]; if (p->mat_nr == material_index) { faces_in_polylist++; vcount_list.push_back(p->totloop); } } // no faces using this material if (faces_in_polylist == 0) { fprintf(stderr, "%s: material with index %d is not used.\n", id_name(ob).c_str(), material_index); return; } Material *ma = ob->totcol ? give_current_material(ob, material_index + 1) : NULL; COLLADASW::Polylist polylist(mSW); // sets count attribute in <polylist> polylist.setCount(faces_in_polylist); // sets material name if (ma) { std::string material_id = get_material_id(ma); std::ostringstream ostr; ostr << translate_id(material_id); polylist.setMaterial(ostr.str()); } COLLADASW::InputList &til = polylist.getInputList(); // creates <input> in <polylist> for vertices COLLADASW::Input input1(COLLADASW::InputSemantic::VERTEX, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX), 0); // creates <input> in <polylist> for normals COLLADASW::Input input2(COLLADASW::InputSemantic::NORMAL, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL), 1); til.push_back(input1); til.push_back(input2); // if mesh has uv coords writes <input> for TEXCOORD int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE)-1; for (i = 0; i < num_layers; i++) { if (!this->export_settings->active_uv_only || i == active_uv_index) { // char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i); COLLADASW::Input input3(COLLADASW::InputSemantic::TEXCOORD, makeUrl(makeTexcoordSourceId(geom_id, i, this->export_settings->active_uv_only)), 2, // this is only until we have optimized UV sets (this->export_settings->active_uv_only) ? 0 : i // only_active_uv exported -> we have only one set ); til.push_back(input3); } } int totlayer_mcol = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL); if (totlayer_mcol > 0) { int map_index = 0; for (int a = 0; a < totlayer_mcol; a++) { char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_MLOOPCOL, a); COLLADASW::Input input4(COLLADASW::InputSemantic::COLOR, makeUrl(makeVertexColorSourceId(geom_id, layer_name)), (has_uvs) ? 3 : 2, // all color layers have same index order map_index // set number equals color map index ); til.push_back(input4); map_index++; } } // sets <vcount> polylist.setVCountList(vcount_list); // performs the actual writing polylist.prepareToAppendValues(); // <p> int texindex = 0; for (i = 0; i < totpolys; i++) { MPoly *p = &mpolys[i]; int loop_count = p->totloop; if (p->mat_nr == material_index) { MLoop *l = &mloops[p->loopstart]; BCPolygonNormalsIndices normal_indices = norind[i]; for (int j = 0; j < loop_count; j++) { polylist.appendValues(l[j].v); polylist.appendValues(normal_indices[j]); if (has_uvs) polylist.appendValues(texindex + j); if (has_color) polylist.appendValues(texindex + j); } } texindex += loop_count; } polylist.finish(); }