198 lines
5.7 KiB
C
198 lines
5.7 KiB
C
/*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* The Original Code is Copyright (C) 2008 Blender Foundation.
|
|
* All rights reserved.
|
|
*/
|
|
|
|
/** \file
|
|
* \ingroup edobj
|
|
*/
|
|
|
|
#include <string.h>
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
#include "BLI_fileops.h"
|
|
#include "BLI_listbase.h"
|
|
#include "BLI_math_base.h"
|
|
#include "BLI_path_util.h"
|
|
#include "BLI_string.h"
|
|
|
|
#include "DNA_object_types.h"
|
|
#include "DNA_volume_types.h"
|
|
|
|
#include "RNA_access.h"
|
|
#include "RNA_define.h"
|
|
|
|
#include "BKE_context.h"
|
|
#include "BKE_lib_id.h"
|
|
#include "BKE_main.h"
|
|
#include "BKE_report.h"
|
|
#include "BKE_volume.h"
|
|
|
|
#include "WM_api.h"
|
|
#include "WM_types.h"
|
|
|
|
#include "ED_image.h"
|
|
#include "ED_object.h"
|
|
#include "ED_screen.h"
|
|
|
|
#include "object_intern.h"
|
|
|
|
/* Volume Add */
|
|
|
|
static Object *object_volume_add(bContext *C, wmOperator *op, const char *name)
|
|
{
|
|
ushort local_view_bits;
|
|
float loc[3], rot[3];
|
|
|
|
if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, NULL, &local_view_bits, NULL)) {
|
|
return NULL;
|
|
}
|
|
return ED_object_add_type(C, OB_VOLUME, name, loc, rot, false, local_view_bits);
|
|
}
|
|
|
|
static int object_volume_add_exec(bContext *C, wmOperator *op)
|
|
{
|
|
return (object_volume_add(C, op, NULL) != NULL) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
|
|
}
|
|
|
|
void OBJECT_OT_volume_add(wmOperatorType *ot)
|
|
{
|
|
/* identifiers */
|
|
ot->name = "Add Volume";
|
|
ot->description = "Add a volume object to the scene";
|
|
ot->idname = "OBJECT_OT_volume_add";
|
|
|
|
/* api callbacks */
|
|
ot->exec = object_volume_add_exec;
|
|
ot->poll = ED_operator_objectmode;
|
|
|
|
/* flags */
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
|
|
|
ED_object_add_generic_props(ot, false);
|
|
}
|
|
|
|
/* Volume Import */
|
|
|
|
static int volume_import_exec(bContext *C, wmOperator *op)
|
|
{
|
|
Main *bmain = CTX_data_main(C);
|
|
const bool is_relative_path = RNA_boolean_get(op->ptr, "relative_path");
|
|
bool imported = false;
|
|
|
|
ListBase ranges = ED_image_filesel_detect_sequences(bmain, op, false);
|
|
LISTBASE_FOREACH (ImageFrameRange *, range, &ranges) {
|
|
char filename[FILE_MAX];
|
|
BLI_split_file_part(range->filepath, filename, sizeof(filename));
|
|
BLI_path_extension_replace(filename, sizeof(filename), "");
|
|
|
|
Object *object = object_volume_add(C, op, filename);
|
|
Volume *volume = (Volume *)object->data;
|
|
|
|
STRNCPY(volume->filepath, range->filepath);
|
|
if (is_relative_path) {
|
|
BLI_path_rel(volume->filepath, BKE_main_blendfile_path(bmain));
|
|
}
|
|
|
|
if (!BKE_volume_load(volume, bmain)) {
|
|
BKE_reportf(op->reports,
|
|
RPT_WARNING,
|
|
"Volume \"%s\" failed to load: %s",
|
|
filename,
|
|
BKE_volume_grids_error_msg(volume));
|
|
BKE_id_delete(bmain, &object->id);
|
|
BKE_id_delete(bmain, &volume->id);
|
|
continue;
|
|
}
|
|
if (BKE_volume_is_points_only(volume)) {
|
|
BKE_reportf(op->reports,
|
|
RPT_WARNING,
|
|
"Volume \"%s\" contains points, only voxel grids are supported",
|
|
filename);
|
|
BKE_id_delete(bmain, &object->id);
|
|
BKE_id_delete(bmain, &volume->id);
|
|
continue;
|
|
}
|
|
|
|
/* Set sequence parameters after trying to load the first frame, for file validation we want
|
|
* to use a consistent frame rather than whatever corresponds to the current scene frame. */
|
|
volume->is_sequence = (range->length > 1);
|
|
volume->frame_duration = (volume->is_sequence) ? range->length : 0;
|
|
volume->frame_start = 1;
|
|
volume->frame_offset = (volume->is_sequence) ? range->offset - 1 : 0;
|
|
|
|
if (BKE_volume_is_y_up(volume)) {
|
|
object->rot[0] += M_PI_2;
|
|
}
|
|
|
|
BKE_volume_unload(volume);
|
|
|
|
imported = true;
|
|
}
|
|
BLI_freelistN(&ranges);
|
|
|
|
return (imported) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
|
|
}
|
|
|
|
static int volume_import_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
|
{
|
|
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
|
|
return volume_import_exec(C, op);
|
|
}
|
|
|
|
RNA_string_set(op->ptr, "filepath", U.textudir);
|
|
WM_event_add_fileselect(C, op);
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
}
|
|
|
|
/* called by other space types too */
|
|
void OBJECT_OT_volume_import(wmOperatorType *ot)
|
|
{
|
|
/* identifiers */
|
|
ot->name = "Import OpenVDB Volume";
|
|
ot->description = "Import OpenVDB volume file";
|
|
ot->idname = "OBJECT_OT_volume_import";
|
|
|
|
/* api callbacks */
|
|
ot->exec = volume_import_exec;
|
|
ot->invoke = volume_import_invoke;
|
|
|
|
/* flags */
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
|
|
|
/* properties */
|
|
WM_operator_properties_filesel(ot,
|
|
FILE_TYPE_FOLDER | FILE_TYPE_VOLUME,
|
|
FILE_SPECIAL,
|
|
FILE_OPENFILE,
|
|
WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILES |
|
|
WM_FILESEL_RELPATH,
|
|
FILE_DEFAULTDISPLAY,
|
|
FILE_SORT_DEFAULT);
|
|
|
|
RNA_def_boolean(
|
|
ot->srna,
|
|
"use_sequence_detection",
|
|
true,
|
|
"Detect Sequences",
|
|
"Automatically detect animated sequences in selected volume files (based on file names)");
|
|
|
|
ED_object_add_generic_props(ot, false);
|
|
}
|