Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Eagar <joeedh@gmail.com>2011-05-02 04:58:33 +0400
committerJoseph Eagar <joeedh@gmail.com>2011-05-02 04:58:33 +0400
commite64fba68a03e3289710bf35e2176f3a854612e83 (patch)
treeaebdaa76d84647d87b09eb175feb7eea1ee26c19
parent733a97f88e264a92f5d2a7b0d566d74f168e96e9 (diff)
=bmesh=
Added a temporary (but fairly complete) wavefront obj exporter. There's no importer as yet, however.
-rw-r--r--release/scripts/startup/bl_ui/space_info.py2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c10
-rw-r--r--source/blender/blenlib/BLI_fileops.h2
-rw-r--r--source/blender/editors/mesh/bmesh_tools.c314
-rw-r--r--source/blender/editors/mesh/mesh_ops.c3
5 files changed, 326 insertions, 5 deletions
diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py
index 49f8e890856..1e3879ec3b7 100644
--- a/release/scripts/startup/bl_ui/space_info.py
+++ b/release/scripts/startup/bl_ui/space_info.py
@@ -164,6 +164,8 @@ class INFO_MT_file_export(bpy.types.Menu):
bl_label = "Export"
def draw(self, context):
+ self.layout.operator("export_mesh.wavefront", text="Wavefront (.obj)")
+
if hasattr(bpy.types, "WM_OT_collada_export"):
self.layout.operator("wm.collada_export", text="COLLADA (.dae)")
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 285f089a871..421e8a89137 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -782,10 +782,12 @@ static void *get_orco_coords_dm(Object *ob, BMEditMesh *em, int layer, int *free
by a more flexible customdata system, but not simple */
if(!em) {
ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
- KeyBlock *kb= key_get_keyblock(ob_get_key(ob), clmd->sim_parms->shapekey_rest);
-
- if(kb->data)
- return kb->data;
+ if (clmd) {
+ KeyBlock *kb= key_get_keyblock(ob_get_key(ob), clmd->sim_parms->shapekey_rest);
+
+ if(kb->data)
+ return kb->data;
+ }
}
return NULL;
diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h
index 59c01348c07..f32e6bacdc3 100644
--- a/source/blender/blenlib/BLI_fileops.h
+++ b/source/blender/blenlib/BLI_fileops.h
@@ -47,7 +47,7 @@ int BLI_link(const char *file, const char *to);
int BLI_is_writable(const char *filename);
/**
- * @attention Do not confuse with BLI_exist
+ * @attention Do not confuse with BLI_exist [joeedh--yet, it calls BLI_exist?]
*/
int BLI_exists(const char *file);
int BLI_copy_fileops(const char *file, const char *to);
diff --git a/source/blender/editors/mesh/bmesh_tools.c b/source/blender/editors/mesh/bmesh_tools.c
index 8c41542d9b2..ec8b5ffa47a 100644
--- a/source/blender/editors/mesh/bmesh_tools.c
+++ b/source/blender/editors/mesh/bmesh_tools.c
@@ -64,6 +64,8 @@
#include "BKE_material.h"
#include "BKE_context.h"
#include "BKE_customdata.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_cdderivedmesh.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_library.h"
@@ -4799,3 +4801,315 @@ void MESH_OT_bevel(wmOperatorType *ot)
//RNA_def_float(ot->srna, "param4", 0.5f, -FLT_MAX, FLT_MAX, "Parameter 4", "", -1000.0f, 1000.0f);
//RNA_def_float(ot->srna, "param5", 0.5f, -FLT_MAX, FLT_MAX, "Parameter 5", "", -1000.0f, 1000.0f);
}
+
+static int mesh_export_obj_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = CTX_data_active_object(C);
+ DerivedMesh *dm;
+ Scene *scene = CTX_data_scene(C);
+ Mesh *me;
+ Main *bmain = CTX_data_main(C);
+ MVert *mvert, *mv;
+ MLoop *mloop, *ml;
+ MPoly *mpoly, *mp;
+ MTexPoly *mtexpoly;
+ MLoopUV *luv, *mloopuv;
+ MLoopCol *lcol, *mloopcol;
+ FILE *file, *matfile;
+ int *face_mat_group;
+ struct {Material *mat; MTexPoly poly; int end;} **matlists;
+ char str[FILE_MAX], str2[FILE_MAX];
+ int i, j, c, free;
+
+ if (ob->type != OB_MESH) {
+ BKE_report(op->reports, RPT_OPERATOR, "Only meshes can be exported");
+ return OPERATOR_CANCELLED;
+ }
+
+ RNA_string_get(op->ptr, "filepath", str);
+
+ sprintf(str2, "%s_materials.mtl", str);
+ file = fopen(str, "wb");
+ matfile = fopen(str2, "wb");
+
+ if (!file) {
+ BKE_report(op->reports, RPT_OPERATOR, "Could not open file");
+
+ if (matfile)
+ fclose(matfile);
+ return OPERATOR_CANCELLED;
+ }
+
+ if (!matfile) {
+ BKE_report(op->reports, RPT_OPERATOR, "Could not open material file");
+
+ if (file)
+ fclose(file);
+ return OPERATOR_CANCELLED;
+ }
+
+ me = ob->data;
+ if (me->edit_btmesh) {
+ EDBM_LoadEditBMesh(scene, ob);
+ }
+
+ if (!RNA_boolean_get(op->ptr, "apply_modifiers")) {
+ dm = CDDM_from_mesh(me, ob);
+ free = 1;
+ } else {
+ dm = mesh_get_derived_final(scene, ob, CD_MASK_DERIVEDMESH);
+ if (!CDDM_Check(dm)) {
+ dm = CDDM_copy(dm, 0);
+ free = 1;
+ } else {
+ free = 0;
+ }
+ }
+
+ face_mat_group = MEM_callocN(sizeof(int)*dm->numPolyData, "face_mat_group");
+
+ if (MAX2(ob->totcol, me->totcol))
+ matlists = MEM_callocN(sizeof(*matlists)*MAX2(me->totcol, ob->totcol), "matlists");
+ else matlists = NULL;
+
+ for (i=0; i<MAX2(ob->totcol, me->totcol); i++) {
+ matlists[i] = MEM_callocN(sizeof(**matlists), "matlists[i]");
+ matlists[i][0].end = 1;
+ }
+
+
+ mvert = CDDM_get_verts(dm);
+ mloop = CDDM_get_loops(dm);
+ mpoly = CDDM_get_polys(dm);
+ mtexpoly = CustomData_get_layer(&dm->polyData, CD_MTEXPOLY);
+ mloopuv = CustomData_get_layer(&dm->loopData, CD_MLOOPUV);
+ mloopcol = CustomData_get_layer(&dm->loopData, CD_MLOOPCOL);
+
+ /*build material list*/
+ mp = mpoly;
+ for (i=0; i<dm->numPolyData; i++, (mtexpoly ? mtexpoly++ : NULL), mp++) {
+ int found = 0;
+
+ j = 0;
+ while (!matlists[mp->mat_nr][j].end) {
+ Material *mat = ob->matbits[mp->mat_nr] ? ob->mat[mp->mat_nr] : me->mat[mp->mat_nr];
+
+ if (matlists[mp->mat_nr][j].mat == mat) {
+ if (mtexpoly) {
+ if (matlists[mp->mat_nr][j].poly.tpage == mtexpoly->tpage) {
+ found = 1;
+ break;
+ }
+ } else {
+ found = 1;
+ break;
+ }
+ }
+ j++;
+ }
+
+ if (!found) {
+ matlists[mp->mat_nr] = MEM_reallocN(matlists[mp->mat_nr], sizeof(**matlists)*(j+2));
+
+ /*add sentinal*/
+ matlists[mp->mat_nr][j+1].end = 1;
+ matlists[mp->mat_nr][j].end = 0;
+
+ if (ob->matbits && ob->matbits[mp->mat_nr]) {
+ matlists[mp->mat_nr][j].mat = ob->mat[mp->mat_nr];
+ } else {
+ matlists[mp->mat_nr][j].mat = me->mat[mp->mat_nr];
+ }
+
+ if (mtexpoly)
+ matlists[mp->mat_nr][j].poly = *mtexpoly;
+ }
+
+ face_mat_group[i] = j;
+ }
+
+ /*write material references*/
+ fprintf(file, "mtllib %s_materials.mtl\n", str);
+ fprintf(file, "o %s\n", (ob->id.name+2));
+
+ for (mv=mvert, i=0; i<dm->numVertData; i++, mv++) {
+ fprintf(file, "v %.8f\t%.8f\t%.8f\n", mv->co[0], mv->co[1], mv->co[2]);
+ fprintf(file, "vn %.5f\t%.5f\t%.5f\n", (float)mv->no[0]/65535.0f, (float)mv->no[1]/65535.0f, (float)mv->no[2]/65535.0f);
+ }
+
+ /*write texture coordinates*/
+ if (mloopuv) {
+ fprintf(file, "\n");
+ for (mp=mpoly, i=0; i<dm->numPolyData; i++, mp++) {
+ luv = mloopuv + mp->loopstart;
+ for (j=0; j<mp->totloop; j++, luv++) {
+ fprintf(file, "vt %.8f\t%.8f\n", luv->uv[0], luv->uv[1]);
+ }
+ }
+ }
+
+ fprintf(file, "\n");
+ c = 0;
+ for (mp=mpoly, i=0; i<dm->numPolyData; i++, mp++) {
+ char matname[256];
+
+ if (mp->flag & ME_SMOOTH) {
+ fprintf(file, "s 1\n");
+ } else {
+ fprintf(file, "s off\n");
+ }
+
+ if (matlists[mp->mat_nr][face_mat_group[i]].mat && matlists[mp->mat_nr][face_mat_group[i]].poly.tpage) {
+ sprintf(matname, "%s__%s", matlists[mp->mat_nr][face_mat_group[i]].mat->id.name+2,
+ matlists[mp->mat_nr][face_mat_group[i]].poly.tpage->id.name+2);
+ } else if (matlists[mp->mat_nr][face_mat_group[i]].mat) {
+ sprintf(matname, "%s", matlists[mp->mat_nr][face_mat_group[i]].mat->id.name+2);
+ } else if (matlists[mp->mat_nr][face_mat_group[i]].poly.tpage != NULL) {
+ sprintf(matname, "texture_%s", matlists[mp->mat_nr][face_mat_group[i]].poly.tpage->id.name+2);
+ } else {
+ sprintf(matname, "__null_material_%d_%d", mp->mat_nr, face_mat_group[mp->mat_nr]);
+ }
+
+ fprintf(file, "usemtl %s\n", matname);
+ fprintf(file, "f ");
+
+ ml = mloop + mp->loopstart;
+ luv = mloopuv ? mloopuv + mp->loopstart : NULL;
+ for (j=0; j<mp->totloop; j++, ml++, (luv ? luv++ : NULL), c++) {
+ if (luv) {
+ fprintf(file, "%d/%d ", ml->v+1, c+1);
+ } else {
+ fprintf(file, "%d ", ml->v+1);
+ }
+ }
+ fprintf(file, "\n");
+ }
+
+ fclose(file);
+
+ /*write material library*/
+ fprintf(matfile, "#Blender MTL File\n\n");
+ for (i=0; i<MAX2(ob->totcol, me->totcol); i++) {
+ Material *mat;
+ char basedir[FILE_MAX], filename[FILE_MAX], str3[FILE_MAX];
+
+ j = 0;
+ while (!matlists[i][j].end) {
+ mat = matlists[i][j].mat;
+
+ if (mat && matlists[i][j].poly.tpage) {
+ fprintf(matfile, "newmtl %s__%s\n", mat->id.name+2,
+ matlists[i][j].poly.tpage->id.name+2);
+ } else if (mat) {
+ fprintf(matfile, "newmtl %s\n", mat->id.name+2);
+ } else if (matlists[i][j].poly.tpage != NULL) {
+ fprintf(matfile, "newmtl texture_%s\n", matlists[i][j].poly.tpage->id.name+2);
+ } else {
+ fprintf(matfile, "newmtl __null_material_%d_%d\n", i, j);
+ }
+
+ if (mat) {
+ fprintf(matfile, "Kd %.6f %.6f %.6f\n", mat->r, mat->g, mat->b);
+ fprintf(matfile, "Ks %.6f %.6f %.6f\n", mat->specr, mat->specg, mat->specb);
+ fprintf(matfile, "Ns %.6f\n", mat->spec*1000.0f);
+ } else {
+ fprintf(matfile, "Kd %.6f %.6f %.6f\n", 0.45f, 0.45f, 0.45f);
+ fprintf(matfile, "Ks %.6f %.6f %.6f\n", 1.0f, 0.4f, 0.1f);
+ fprintf(matfile, "Ns %.6f\n", 300.0f);
+ }
+
+ fprintf(matfile, "illum 2\n");
+
+ if (matlists[i][j].poly.tpage) {
+ BLI_strncpy(str2, matlists[i][j].poly.tpage->name, FILE_MAX);
+ BLI_strncpy(basedir, bmain->name, FILE_MAX);
+
+ BLI_splitdirstring(basedir, filename);
+ BLI_cleanup_file(basedir, str2); /* fix any /foo/../foo/ */
+
+ if (BLI_exists(str2)) {
+ char rel[3] = {0};
+
+ BLI_strncpy(str3, str2, FILE_MAX);
+ if (RNA_boolean_get(op->ptr, "relpaths")) {
+ BLI_path_rel(str3, str);
+
+ if (str3[2] != '.' && str3[2] != '/' && str3[2] != '\\') {
+ rel[0] = '.';
+ rel[1] = '/';
+ }
+ }
+
+ fprintf(matfile, "map_Ka %s%s\n", rel, (str3+2*RNA_boolean_get(op->ptr, "relpaths")));
+ fprintf(matfile, "map_Kd %s%s\n", rel, (str3+2*RNA_boolean_get(op->ptr, "relpaths")));
+ }
+ }
+
+ fprintf(matfile, "\n");
+ j++;
+ }
+ }
+
+ fclose(matfile);
+
+ for (i=0; i<MAX2(ob->totcol, me->totcol); i++) {
+ MEM_freeN(matlists[i]);
+ }
+
+ if (matlists)
+ MEM_freeN(matlists);
+
+ if (face_mat_group)
+ MEM_freeN(face_mat_group);
+
+ if (free) {
+ dm->needsFree = 1;
+ dm->release(dm);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+static void export_obj_filesel(bContext *C, wmOperator *op, const char *path)
+{
+ RNA_string_set(op->ptr, "filepath", path);
+ WM_event_add_fileselect(C, op);
+}
+
+
+static int export_obj_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+{
+ char filename[FILE_MAX];
+
+ BLI_strncpy(filename, "//untitled.obj", FILE_MAX);
+
+ if(RNA_property_is_set(op->ptr, "filepath"))
+ return mesh_export_obj_exec(C, op);
+
+ export_obj_filesel(C, op, filename);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+
+void EXPORT_MESH_OT_wavefront(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Export Wavefront OBJ";
+ ot->description= "Export Wavefront (obj)";
+ ot->idname= "EXPORT_MESH_OT_wavefront";
+
+ /* api callbacks */
+ ot->exec= mesh_export_obj_exec;
+ ot->invoke= export_obj_invoke;
+ ot->poll= ED_operator_object_active;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE, FILE_SPECIAL, FILE_SAVE, WM_FILESEL_FILEPATH);
+
+ RNA_def_boolean(ot->srna, "apply_modifiers", 0, "Apply Modifiers", "Apply Modifiers");
+ RNA_def_boolean(ot->srna, "relpaths", 0, "Relative Paths", "Use relative paths for textures");
+}
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index bb6169eab72..9e70249d9e4 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -59,6 +59,7 @@
/**************************** registration **********************************/
+void EXPORT_MESH_OT_wavefront(wmOperatorType *ot);
void ED_operatortypes_mesh(void)
{
WM_operatortype_append(MESH_OT_select_all);
@@ -157,6 +158,8 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_bevel);
WM_operatortype_append(MESH_OT_select_next_loop);
+
+ WM_operatortype_append(EXPORT_MESH_OT_wavefront);
}
#if 0 /* UNUSED, remove? */