HXALayer *FindHxaLayer(HXALayerStack *stack, char *layer_name) { for(int i = 0; i < stack->layer_count; i++) { if(!strcmp(stack->layers[i].name, layer_name)) return &(stack->layers)[i]; } return NULL; } void MVert_ToBlender(CustomData *vdata, HXALayerStack *vertex_stack, int element_count) { MVert *mvert = (MVert *)CustomData_add_layer(vdata, CD_MVERT, CD_CALLOC, NULL, element_count); HXALayer *vertex_coord_layer = FindHxaLayer(vertex_stack, (char *)HXA_CONVENTION_HARD_BASE_VERTEX_LAYER_NAME); HXALayer *vertex_flag_layer = FindHxaLayer(vertex_stack, (char *)"vert flag"); HXALayer *vertex_bevelweight_layer = FindHxaLayer(vertex_stack, (char *)"vertex bevel weight"); for(int i = 0; i < element_count; i++) { mvert[i].co[0] = vertex_coord_layer->data.float_data[3*i+0]; mvert[i].co[1] = vertex_coord_layer->data.float_data[3*i+1]; mvert[i].co[2] = vertex_coord_layer->data.float_data[3*i+2]; mvert[i].flag = (char)vertex_flag_layer->data.int32_data[i]; mvert[i].bweight = (char)vertex_bevelweight_layer->data.int32_data[i]; } } void MEdge_ToBlender(CustomData *edata, HXALayerStack *edge_stack, int element_count) { MEdge *medge = (MEdge *)CustomData_add_layer(edata, CD_MEDGE, CD_CALLOC, NULL, element_count); HXALayer *vertex_indexes_layer = FindHxaLayer(edge_stack, (char *)"vertex indexes"); HXALayer *edge_creases_layer = FindHxaLayer(edge_stack, (char *)HXA_CONVENTION_SOFT_LAYER_CREASES); HXALayer *edge_bevelweights_layer = FindHxaLayer(edge_stack, (char *)"edge bevel weight"); HXALayer *edge_flags_layer = FindHxaLayer(edge_stack, (char *)"edge flag"); for(int i = 0; i < element_count; i++) { medge[i].v1 = (unsigned int)vertex_indexes_layer->data.int32_data[2*i+0]; medge[i].v2 = (unsigned int)vertex_indexes_layer->data.int32_data[2*i+1]; medge[i].crease = (char)edge_creases_layer->data.int32_data[i]; medge[i].bweight = (char)edge_bevelweights_layer->data.int32_data[i]; // medge[i].flag = (short)edge_flags_layer->data.int32_data[i]; medge[i].flag = ME_EDGEDRAW | ME_EDGERENDER; } } void MLoop_ToBlender(CustomData *ldata, HXALayerStack *corner_stack, int element_count) { MLoop *mloops = (MLoop *)CustomData_add_layer(ldata, CD_MLOOP, CD_CALLOC, NULL, element_count); HXALayer *vertex_reference_layer = FindHxaLayer(corner_stack, (char *)HXA_CONVENTION_HARD_BASE_CORNER_LAYER_NAME); HXALayer *edge_index_layer = FindHxaLayer(corner_stack, (char *)"edge index"); for(int i = 0; i < element_count; i++) { int vert_index = vertex_reference_layer->data.int32_data[i]; if(vert_index < 0) vert_index = -1 - vert_index; mloops[i].v = (unsigned int)vert_index; mloops[i].e = (unsigned int)edge_index_layer->data.int32_data[i]; } } void MPoly_ToBlender(CustomData *pdata, HXALayerStack *face_stack, int element_count) { MPoly *mpoly = (MPoly *)CustomData_add_layer(pdata, CD_MPOLY, CD_CALLOC, NULL, element_count); HXALayer *vertex_offset_layer = FindHxaLayer(face_stack, (char *)"vertex index offset"); HXALayer *polygon_size_layer = FindHxaLayer(face_stack, (char *)"polygon size"); HXALayer *material_index_layer = FindHxaLayer(face_stack, (char *)"material index"); HXALayer *polygon_flag_layer = FindHxaLayer(face_stack, (char *)"poly flag"); for(int i = 0; i < element_count; i++) { mpoly[i].loopstart = vertex_offset_layer->data.int32_data[i]; mpoly[i].totloop = polygon_size_layer->data.int32_data[i]; mpoly[i].mat_nr = (short)material_index_layer->data.int32_data[i]; mpoly[i].flag = (char)polygon_flag_layer->data.int32_data[i]; } } // The previous functions have proven themselves to work for HxA file imports static Mesh *hxa_to_mesh() { HXAFile *hxafile = hxa_load((char *)"../hxa models/Triangulation target.hxa", 1); if(!hxafile) { printf("! No friggin HxA file!\n"); return NULL; } HXAMeta *metadata_cdlayers = NULL; HXAMeta *meta_indexcount = NULL; HXAMeta *vdata = NULL; HXAMeta *edata = NULL; HXAMeta *ldata = NULL; HXAMeta *pdata = NULL; for(int i = 0; i < hxafile->node_array[0].meta_data_count; i++) { HXAMeta *meta = &hxafile->node_array[0].meta_data[i]; if(!strcmp(meta->name, "CDLayers data")) metadata_cdlayers = meta; } if(!metadata_cdlayers) { printf("! No friggin cdlayers\n"); return NULL; } for(int i = 0; i < metadata_cdlayers->array_length; i++) { HXAMeta *meta = &((HXAMeta *)(metadata_cdlayers->value.array_of_meta))[i]; if(!strcmp(meta->name, "VData")) vdata = meta; if(!strcmp(meta->name, "EData")) edata = meta; if(!strcmp(meta->name, "LData")) ldata = meta; if(!strcmp(meta->name, "PData")) pdata = meta; } if(!vdata) { printf("! No friggin vertex data\n"); return NULL; } if(!edata) { printf("! No friggin edge data\n"); return NULL; } if(!ldata) { printf("! No friggin loop data\n"); return NULL; } if(!pdata) { printf("! No friggin poly data\n"); return NULL; } for(int i = 0; i < hxafile->node_array[0].meta_data_count; i++) { HXAMeta *meta = &hxafile->node_array[0].meta_data[i]; if(!strcmp(meta->name, "Index count")) meta_indexcount = meta; } if(!meta_indexcount) { printf("! No friggin index counts\n"); return NULL; } int vcount = vdata->array_length; int ecount = edata->array_length; int lcount = ldata->array_length; int pcount = pdata->array_length; char **vdata_cdlayers = (char **)malloc(sizeof(char *) * vcount); char **edata_cdlayers = (char **)malloc(sizeof(char *) * ecount); char **ldata_cdlayers = (char **)malloc(sizeof(char *) * lcount); char **pdata_cdlayers = (char **)malloc(sizeof(char *) * pcount); for(int i = 0; i < vcount; i++) { HXAMeta *meta = &((HXAMeta *)(vdata->value.array_of_meta))[i]; vdata_cdlayers[i] = meta->value.text_value; } for(int i = 0; i < ecount; i++) { HXAMeta *meta = &((HXAMeta *)(edata->value.array_of_meta))[i]; edata_cdlayers[i] = meta->value.text_value; } for(int i = 0; i < lcount; i++) { HXAMeta *meta = &((HXAMeta *)(ldata->value.array_of_meta))[i]; ldata_cdlayers[i] = meta->value.text_value; } for(int i = 0; i < pcount; i++) { HXAMeta *meta = &((HXAMeta *)(pdata->value.array_of_meta))[i]; pdata_cdlayers[i] = meta->value.text_value; } int totvert = hxafile->node_array[0].content.geometry.vertex_count; int totedge = (int)meta_indexcount->value.int64_value[0]; int totloop = hxafile->node_array[0].content.geometry.edge_corner_count; int totpoly = hxafile->node_array[0].content.geometry.face_count; Mesh *mesh = BKE_mesh_new_nomain(totvert, totedge, 0, totloop, totpoly); /* Q: which types are we processing here? We don't need every single one A: There isn't any extras except for LData. But we only need CD_MLOOP from it. */ for(int i = 0; i < vcount; i++) { char *type = vdata_cdlayers[i]; if(!strcmp(type, "CD_MVERT")) MVert_ToBlender(&mesh->vdata, &hxafile->node_array[0].content.geometry.vertex_stack, mesh->totvert); } for(int i = 0; i < ecount; i++) { char *type = edata_cdlayers[i]; if(!strcmp(type, "CD_MEDGE")) MEdge_ToBlender(&mesh->edata, &hxafile->node_array[0].content.geometry.edge_stack, mesh->totedge); } for(int i = 0; i < lcount; i++) { char *type = ldata_cdlayers[i]; if(!strcmp(type, "CD_MLOOP")) MLoop_ToBlender(&mesh->ldata, &hxafile->node_array[0].content.geometry.corner_stack, mesh->totloop); } for(int i = 0; i < pcount; i++) { char *type = pdata_cdlayers[i]; if(!strcmp(type, "CD_MPOLY")) MPoly_ToBlender(&mesh->pdata, &hxafile->node_array[0].content.geometry.face_stack, mesh->totpoly); } // Q: do we have velp/data pointers set up here? // A: about to find out... mesh->mvert = (MVert *)CustomData_get_layer(&mesh->vdata, CD_MVERT); mesh->medge = (MEdge *)CustomData_get_layer(&mesh->edata, CD_MEDGE); mesh->mloop = (MLoop *)CustomData_get_layer(&mesh->ldata, CD_MLOOP); mesh->mpoly = (MPoly *)CustomData_get_layer(&mesh->pdata, CD_MPOLY); BKE_mesh_validate(mesh, false, false); BLI_assert(BKE_mesh_is_valid(mesh)); return mesh; }