GF_EXPORT GF_Err gf_sg_vrml_mf_reset(void *mf, u32 FieldType) { GenMFField *mffield = (GenMFField *)mf; if (!mffield->array) return GF_OK; //field we can't copy if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM; if (!gf_sg_vrml_get_sf_size(FieldType)) return GF_BAD_PARAM; switch (FieldType) { case GF_SG_VRML_MFSTRING: gf_sg_mfstring_del( * ((MFString *) mf)); break; case GF_SG_VRML_MFURL: gf_sg_mfurl_del( * ((MFURL *) mf)); break; case GF_SG_VRML_MFSCRIPT: gf_sg_mfscript_del( * ((MFScript *) mf)); break; default: if (mffield->array) gf_free(mffield->array); break; } mffield->array = NULL; mffield->count = 0; return GF_OK; }
//remove the specified item (0-based index) GF_Err gf_sg_vrml_mf_remove(void *mf, u32 FieldType, u32 RemoveFrom) { char *buffer; u32 FieldSize, i, k; GenMFField *mffield = (GenMFField *)mf; FieldSize = gf_sg_vrml_get_sf_size(FieldType); //field we can't copy if (!FieldSize) return GF_BAD_PARAM; if (!mffield->count || RemoveFrom >= mffield->count) return GF_BAD_PARAM; if (mffield->count == 1) { gf_free(mffield->array); mffield->array = NULL; mffield->count = 0; return GF_OK; } k=0; buffer = (char*)gf_malloc(sizeof(char)*(mffield->count-1)*FieldSize); for (i=0; i<mffield->count; i++) { if (RemoveFrom == i) { k = 1; } else { memcpy(buffer + (i-k)*FieldSize, mffield->array + i*FieldSize, FieldSize); } } gf_free(mffield->array); mffield->array = buffer; mffield->count -= 1; return GF_OK; }
// // Insert (+alloc) an MFField with a specified position for insertion and sets the ptr to the // newly created slot // !! Doesnt work for MFNodes // InsertAt is the 0-based index for the new slot GF_Err gf_sg_vrml_mf_insert(void *mf, u32 FieldType, void **new_ptr, u32 InsertAt) { char *buffer; u32 FieldSize, i, k; GenMFField *mffield = (GenMFField *)mf; if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM; if (FieldType == GF_SG_VRML_MFNODE) return GF_BAD_PARAM; FieldSize = gf_sg_vrml_get_sf_size(FieldType); //field we can't copy if (!FieldSize) return GF_BAD_PARAM; //first item ever if (!mffield->count || !mffield->array) { if (mffield->array) gf_free(mffield->array); mffield->array = (char*)gf_malloc(sizeof(char)*FieldSize); memset(mffield->array, 0, sizeof(char)*FieldSize); mffield->count = 1; if (new_ptr) *new_ptr = mffield->array; return GF_OK; } //append at the end if (InsertAt >= mffield->count) { mffield->array = (char*)gf_realloc(mffield->array, sizeof(char)*(1+mffield->count)*FieldSize); memset(mffield->array + mffield->count * FieldSize, 0, FieldSize); if (new_ptr) *new_ptr = mffield->array + mffield->count * FieldSize; mffield->count += 1; return GF_OK; } //alloc 1+itemCount buffer = (char*)gf_malloc(sizeof(char)*(1+mffield->count)*FieldSize); //insert in the array k=0; for (i=0; i < mffield->count; i++) { if (InsertAt == i) { if (new_ptr) { *new_ptr = buffer + i*FieldSize; memset(*new_ptr, 0, sizeof(char)*FieldSize); } k = 1; } memcpy(buffer + (k+i) * FieldSize , mffield->array + i*FieldSize, FieldSize); } gf_free(mffield->array); mffield->array = buffer; mffield->count += 1; return GF_OK; }
GF_Err gf_sg_vrml_mf_get_item(void *mf, u32 FieldType, void **new_ptr, u32 ItemPos) { u32 FieldSize; GenMFField *mffield = (GenMFField *)mf; *new_ptr = NULL; if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM; if (FieldType == GF_SG_VRML_MFNODE) return GF_BAD_PARAM; FieldSize = gf_sg_vrml_get_sf_size(FieldType); //field we can't copy if (!FieldSize) return GF_BAD_PARAM; if (ItemPos >= mffield->count) return GF_BAD_PARAM; *new_ptr = mffield->array + ItemPos * FieldSize; return GF_OK; }
GF_EXPORT GF_Err gf_sg_vrml_mf_alloc(void *mf, u32 FieldType, u32 NbItems) { u32 FieldSize; GenMFField *mffield = (GenMFField *)mf; if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM; if (FieldType == GF_SG_VRML_MFNODE) return GF_BAD_PARAM; FieldSize = gf_sg_vrml_get_sf_size(FieldType); //field we can't copy if (!FieldSize) return GF_BAD_PARAM; if (NbItems>MAX_MFFIELD_ALLOC) return GF_IO_ERR; if (mffield->count==NbItems) return GF_OK; gf_sg_vrml_mf_reset(mf, FieldType); if (NbItems) { mffield->array = (char*)gf_malloc(sizeof(char)*FieldSize*NbItems); memset(mffield->array, 0, sizeof(char)*FieldSize*NbItems); } mffield->count = NbItems; return GF_OK; }
GF_EXPORT void gf_sg_vrml_field_clone(void *dest, void *orig, u32 field_type, GF_SceneGraph *inScene) { u32 size, i, sf_type; void *dst_field, *orig_field; if (!dest || !orig) return; switch (field_type) { case GF_SG_VRML_SFBOOL: memcpy(dest, orig, sizeof(SFBool)); break; case GF_SG_VRML_SFCOLOR: memcpy(dest, orig, sizeof(SFColor)); break; case GF_SG_VRML_SFFLOAT: memcpy(dest, orig, sizeof(SFFloat)); break; case GF_SG_VRML_SFINT32: memcpy(dest, orig, sizeof(SFInt32)); break; case GF_SG_VRML_SFROTATION: memcpy(dest, orig, sizeof(SFRotation)); break; case GF_SG_VRML_SFTIME: memcpy(dest, orig, sizeof(SFTime)); break; case GF_SG_VRML_SFVEC2F: memcpy(dest, orig, sizeof(SFVec2f)); break; case GF_SG_VRML_SFVEC3F: memcpy(dest, orig, sizeof(SFVec3f)); break; case GF_SG_VRML_SFATTRREF: memcpy(dest, orig, sizeof(SFAttrRef)); break; case GF_SG_VRML_SFSTRING: if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer); if ( ((SFString*)orig)->buffer ) ((SFString*)dest)->buffer = gf_strdup(((SFString*)orig)->buffer); else ((SFString*)dest)->buffer = NULL; break; case GF_SG_VRML_SFURL: if ( ((SFURL *)dest)->url ) gf_free( ((SFURL *)dest)->url ); ((SFURL *)dest)->OD_ID = ((SFURL *)orig)->OD_ID; if (((SFURL *)orig)->url) ((SFURL *)dest)->url = gf_strdup(((SFURL *)orig)->url); else ((SFURL *)dest)->url = NULL; break; case GF_SG_VRML_SFIMAGE: if (((SFImage *)dest)->pixels) gf_free(((SFImage *)dest)->pixels); ((SFImage *)dest)->width = ((SFImage *)orig)->width; ((SFImage *)dest)->height = ((SFImage *)orig)->height; ((SFImage *)dest)->numComponents = ((SFImage *)orig)->numComponents; size = ((SFImage *)dest)->width * ((SFImage *)dest)->height * ((SFImage *)dest)->numComponents; ((SFImage *)dest)->pixels = (u8*)gf_malloc(sizeof(char)*size); memcpy(((SFImage *)dest)->pixels, ((SFImage *)orig)->pixels, sizeof(char)*size); break; case GF_SG_VRML_SFCOMMANDBUFFER: { SFCommandBuffer *cb_dst = (SFCommandBuffer *)dest; SFCommandBuffer *cb_src = (SFCommandBuffer *)orig; cb_dst->bufferSize = cb_src->bufferSize; if (cb_dst->bufferSize && !gf_list_count(cb_src->commandList) ) { cb_dst->buffer = (u8*)gf_realloc(cb_dst->buffer, sizeof(char)*cb_dst->bufferSize); memcpy(cb_dst->buffer, cb_src->buffer, sizeof(char)*cb_src->bufferSize); } else { u32 j, c2; if (cb_dst->buffer) gf_free(cb_dst->buffer); cb_dst->buffer = NULL; /*clone command list*/ c2 = gf_list_count(cb_src->commandList); for (j=0; j<c2;j++) { GF_Command *sub_com = (GF_Command *)gf_list_get(cb_src->commandList, j); GF_Command *new_com = gf_sg_vrml_command_clone(sub_com, inScene, 0); gf_list_add(cb_dst->commandList, new_com); } } } break; /*simply copy text string*/ case GF_SG_VRML_SFSCRIPT: if (((SFScript*)dest)->script_text) gf_free(((SFScript*)dest)->script_text); ((SFScript*)dest)->script_text = NULL; if ( ((SFScript*)orig)->script_text) ((SFScript *)dest)->script_text = (char *)gf_strdup( (char*) ((SFScript*)orig)->script_text ); break; //simple MFFields, do a memcpy case GF_SG_VRML_MFBOOL: case GF_SG_VRML_MFFLOAT: case GF_SG_VRML_MFTIME: case GF_SG_VRML_MFINT32: case GF_SG_VRML_MFVEC3F: case GF_SG_VRML_MFVEC2F: case GF_SG_VRML_MFCOLOR: case GF_SG_VRML_MFROTATION: case GF_SG_VRML_MFATTRREF: size = gf_sg_vrml_get_sf_size(field_type) * ((GenMFField *)orig)->count; if (((GenMFField *)orig)->count != ((GenMFField *)dest)->count) { ((GenMFField *)dest)->array = gf_realloc(((GenMFField *)dest)->array, size); ((GenMFField *)dest)->count = ((GenMFField *)orig)->count; } memcpy(((GenMFField *)dest)->array, ((GenMFField *)orig)->array, size); break; //complex MFFields case GF_SG_VRML_MFSTRING: case GF_SG_VRML_MFIMAGE: case GF_SG_VRML_MFURL: case GF_SG_VRML_MFSCRIPT: size = ((GenMFField *)orig)->count; gf_sg_vrml_mf_reset(dest, field_type); gf_sg_vrml_mf_alloc(dest, field_type, size); sf_type = gf_sg_vrml_get_sf_type(field_type); //duplicate all items for (i=0; i<size; i++) { gf_sg_vrml_mf_get_item(dest, field_type, &dst_field, i); gf_sg_vrml_mf_get_item(orig, field_type, &orig_field, i); gf_sg_vrml_field_copy(dst_field, orig_field, sf_type); } break; } }