Mesh *bc_get_mesh_copy(Scene *scene, Object *ob, BC_export_mesh_type export_mesh_type, bool apply_modifiers, bool triangulate) { Mesh *tmpmesh; CustomDataMask mask = CD_MASK_MESH; Mesh *mesh = (Mesh *)ob->data; DerivedMesh *dm = NULL; if (apply_modifiers) { switch (export_mesh_type) { case BC_MESH_TYPE_VIEW: { dm = mesh_create_derived_view(scene, ob, mask); break; } case BC_MESH_TYPE_RENDER: { dm = mesh_create_derived_render(scene, ob, mask); break; } } } else { dm = mesh_create_derived((Mesh *)ob->data, NULL); } tmpmesh = BKE_mesh_add(G.main, "ColladaMesh"); // name is not important here DM_to_mesh(dm, tmpmesh, ob, CD_MASK_MESH, true); tmpmesh->flag = mesh->flag; if (triangulate) { bc_triangulate_mesh(tmpmesh); } BKE_mesh_tessface_ensure(tmpmesh); return tmpmesh; }
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 int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, ModifierData *md) { ModifierTypeInfo *mti= modifierType_getInfo(md->type); md->scene= scene; if (mti->isDisabled && mti->isDisabled(md, 0)) { BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply"); return 0; } if (ob->type==OB_MESH) { DerivedMesh *dm; Mesh *me = ob->data; MultiresModifierData *mmd= find_multires_modifier_before(scene, md); if(me->key && mti->type != eModifierTypeType_NonGeometrical) { BKE_report(reports, RPT_ERROR, "Modifier cannot be applied to Mesh with Shape Keys"); return 0; } /* Multires: ensure that recent sculpting is applied */ if(md->type == eModifierType_Multires) multires_force_update(ob); if (mmd && mmd->totlvl && mti->type==eModifierTypeType_OnlyDeform) { if(!multiresModifier_reshapeFromDeformMod (scene, mmd, ob, md)) { BKE_report(reports, RPT_ERROR, "Multires modifier returned error, skipping apply"); return 0; } } else { dm = mesh_create_derived_for_modifier(scene, ob, md); if (!dm) { BKE_report(reports, RPT_ERROR, "Modifier returned error, skipping apply"); return 0; } DM_to_mesh(dm, me); dm->release(dm); if(md->type == eModifierType_Multires) { CustomData_external_remove(&me->fdata, &me->id, CD_MDISPS, me->totface); CustomData_free_layer_active(&me->fdata, CD_MDISPS, me->totface); } } } else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { Curve *cu; int numVerts; float (*vertexCos)[3]; if (ELEM(mti->type, eModifierTypeType_Constructive, eModifierTypeType_Nonconstructive)) { BKE_report(reports, RPT_ERROR, "Cannot apply constructive modifiers on curve"); return 0; } cu = ob->data; BKE_report(reports, RPT_INFO, "Applied modifier only changed CV points, not tesselated/bevel vertices"); vertexCos = curve_getVertexCos(cu, &cu->nurb, &numVerts); mti->deformVerts(md, ob, NULL, vertexCos, numVerts, 0, 0); curve_applyVertexCos(cu, &cu->nurb, vertexCos); MEM_freeN(vertexCos); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } else { BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type"); return 0; } /* lattice modifier can be applied to particle system too */ if(ob->particlesystem.first) { ParticleSystem *psys = ob->particlesystem.first; for(; psys; psys=psys->next) { if(psys->part->type != PART_HAIR) continue; psys_apply_hair_lattice(scene, ob, psys); } } return 1; }
/* settings: 0 - preview, 1 - render */ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_modifiers, int settings) { Mesh *tmpmesh; Curve *tmpcu = NULL; Object *tmpobj = NULL; int render = settings == eModifierMode_Render, i; int cage = !apply_modifiers; /* perform the mesh extraction based on type */ switch (ob->type) { case OB_FONT: case OB_CURVE: case OB_SURF: /* copies object and modifiers (but not the data) */ tmpobj= copy_object(ob); tmpcu = (Curve *)tmpobj->data; tmpcu->id.us--; /* if getting the original caged mesh, delete object modifiers */ if( cage ) object_free_modifiers(tmpobj); /* copies the data */ tmpobj->data = copy_curve( (Curve *) ob->data ); #if 0 /* copy_curve() sets disp.first null, so currently not need */ { Curve *cu; cu = (Curve *)tmpobj->data; if( cu->disp.first ) MEM_freeN( cu->disp.first ); cu->disp.first = NULL; } #endif /* get updated display list, and convert to a mesh */ makeDispListCurveTypes( sce, tmpobj, 0 ); nurbs_to_mesh( tmpobj ); /* nurbs_to_mesh changes the type to a mesh, check it worked */ if (tmpobj->type != OB_MESH) { free_libblock_us( &(G.main->object), tmpobj ); BKE_report(reports, RPT_ERROR, "cant convert curve to mesh. Does the curve have any segments?"); return NULL; } tmpmesh = tmpobj->data; free_libblock_us( &G.main->object, tmpobj ); break; case OB_MBALL: { /* metaballs don't have modifiers, so just convert to mesh */ Object *basis_ob = find_basis_mball(sce, ob); /* todo, re-generatre for render-res */ /* metaball_polygonize(scene, ob) */ if(ob != basis_ob) return NULL; /* only do basis metaball */ tmpmesh = add_mesh("Mesh"); if(render) { ListBase disp = {NULL, NULL}; makeDispListMBall_forRender(sce, ob, &disp); mball_to_mesh(&disp, tmpmesh); freedisplist(&disp); } else mball_to_mesh(&ob->disp, tmpmesh); break; } case OB_MESH: /* copies object and modifiers (but not the data) */ if (cage) { /* copies the data */ tmpmesh = copy_mesh( ob->data ); /* if not getting the original caged mesh, get final derived mesh */ } else { /* Make a dummy mesh, saves copying */ DerivedMesh *dm; /* CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; */ CustomDataMask mask = CD_MASK_MESH; /* this seems more suitable, exporter, for example, needs CD_MASK_MDEFORMVERT */ /* Write the display mesh into the dummy mesh */ if (render) dm = mesh_create_derived_render( sce, ob, mask ); else dm = mesh_create_derived_view( sce, ob, mask ); tmpmesh = add_mesh( "Mesh" ); DM_to_mesh( dm, tmpmesh ); dm->release( dm ); } break; default: BKE_report(reports, RPT_ERROR, "Object does not have geometry data"); return NULL; } /* Copy materials to new mesh */ switch (ob->type) { case OB_SURF: case OB_FONT: case OB_CURVE: tmpmesh->totcol = tmpcu->totcol; /* free old material list (if it exists) and adjust user counts */ if( tmpcu->mat ) { for( i = tmpcu->totcol; i-- > 0; ) { /* are we an object material or data based? */ tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : tmpcu->mat[i]; if (tmpmesh->mat[i]) { tmpmesh->mat[i]->id.us++; } } } break; #if 0 /* Crashes when assigning the new material, not sure why */ case OB_MBALL: tmpmb = (MetaBall *)ob->data; tmpmesh->totcol = tmpmb->totcol; /* free old material list (if it exists) and adjust user counts */ if( tmpmb->mat ) { for( i = tmpmb->totcol; i-- > 0; ) { tmpmesh->mat[i] = tmpmb->mat[i]; /* CRASH HERE ??? */ if (tmpmesh->mat[i]) { tmpmb->mat[i]->id.us++; } } } break; #endif case OB_MESH: if (!cage) { Mesh *origmesh= ob->data; tmpmesh->flag= origmesh->flag; tmpmesh->mat = MEM_dupallocN(origmesh->mat); tmpmesh->totcol = origmesh->totcol; tmpmesh->smoothresh= origmesh->smoothresh; if( origmesh->mat ) { for( i = origmesh->totcol; i-- > 0; ) { /* are we an object material or data based? */ tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : origmesh->mat[i]; if (tmpmesh->mat[i]) { tmpmesh->mat[i]->id.us++; } } } } break; } /* end copy materials */ /* we don't assign it to anything */ tmpmesh->id.us--; /* make sure materials get updated in objects */ test_object_materials( ( ID * ) tmpmesh ); return tmpmesh; }