Files
armorpaint/paint/sources/import_mesh.ts
T

269 lines
7.3 KiB
TypeScript
Raw Normal View History

2024-03-13 23:50:11 +01:00
2025-10-15 18:39:55 +02:00
let import_mesh_clear_layers: bool = true;
2024-03-13 23:50:11 +01:00
let import_mesh_meshes_to_unwrap: any[] = null;
function import_mesh_run(path: string, _clear_layers: bool = true, replace_existing: bool = true) {
if (!path_is_mesh(path)) {
if (!context_enable_import_plugin(path)) {
2025-01-19 20:35:39 +01:00
console_error(strings_unknown_asset_format());
2024-03-13 23:50:11 +01:00
return;
}
}
import_mesh_clear_layers = _clear_layers;
context_raw.layer_filter = 0;
import_mesh_meshes_to_unwrap = null;
2024-03-20 16:13:54 +01:00
let p: string = to_lower_case(path);
if (ends_with(p, ".obj")) {
import_obj_run(path, replace_existing);
}
else if (ends_with(p, ".blend")) {
import_blend_mesh_run(path, replace_existing);
}
2024-03-13 23:50:11 +01:00
else {
2025-10-15 18:39:55 +02:00
let ext: string = substring(path, string_last_index_of(path, ".") + 1, path.length);
let importer: any = map_get(path_mesh_importers, ext); // JSValue -> (s: string)=>raw_mesh_t
2024-08-24 11:17:02 +02:00
let mesh: raw_mesh_t = js_pcall_str(importer, path);
if (mesh.name == "") {
mesh.name = path_base_name(path);
}
2024-08-25 21:47:36 +02:00
replace_existing ? import_mesh_make_mesh(mesh) : import_mesh_add_mesh(mesh);
2024-03-13 23:50:11 +01:00
2024-04-02 15:45:49 +02:00
let has_next: bool = mesh.has_next;
while (has_next) {
2024-08-24 11:17:02 +02:00
let mesh: raw_mesh_t = js_pcall_str(importer, path);
if (mesh.name == "") {
mesh.name = path_base_name(path);
}
2024-04-02 15:45:49 +02:00
has_next = mesh.has_next;
import_mesh_add_mesh(mesh);
}
2024-03-13 23:50:11 +01:00
}
2025-10-15 18:39:55 +02:00
project_mesh_assets = [ path ];
2024-03-13 23:50:11 +01:00
2025-10-15 18:39:55 +02:00
/// if (arm_android || arm_ios)
2024-03-20 16:13:54 +01:00
sys_title_set(substring(path, string_last_index_of(path, path_sep) + 1, string_last_index_of(path, ".")));
2025-10-15 18:39:55 +02:00
/// end
2024-03-13 23:50:11 +01:00
}
function import_mesh_finish_import() {
if (context_raw.merged_object != null) {
mesh_data_delete(context_raw.merged_object.data);
mesh_object_remove(context_raw.merged_object);
context_raw.merged_object = null;
}
context_select_paint_object(context_main_object());
2025-01-19 20:43:05 +01:00
// No mask by default
for (let i: i32 = 0; i < project_paint_objects.length; ++i) {
let p: mesh_object_t = project_paint_objects[i];
2025-10-15 18:39:55 +02:00
p.base.visible = true;
2025-01-19 20:43:05 +01:00
}
2024-03-13 23:50:11 +01:00
if (project_paint_objects.length > 1) {
// Sort by name
2025-10-15 18:39:55 +02:00
array_sort(project_paint_objects, function(pa: any_ptr, pb: any_ptr): i32 {
2024-07-22 00:14:37 +02:00
let a: mesh_object_t = DEREFERENCE(pa);
let b: mesh_object_t = DEREFERENCE(pb);
return strcmp(a.base.name, b.base.name);
2024-03-13 23:50:11 +01:00
});
2024-03-20 16:13:54 +01:00
if (context_raw.merged_object == null) {
util_mesh_merge();
}
2025-10-15 18:39:55 +02:00
context_raw.paint_object.skip_context = "paint";
2024-03-13 23:50:11 +01:00
context_raw.merged_object.base.visible = true;
}
viewport_scale_to_bounds();
2024-03-20 16:13:54 +01:00
if (context_raw.paint_object.base.name == "") {
context_raw.paint_object.base.name = "Object";
}
2024-03-14 15:31:22 +01:00
make_material_parse_paint_material();
make_material_parse_mesh_material();
2024-03-13 23:50:11 +01:00
2025-10-15 18:39:55 +02:00
ui_view2d_hwnd.redraws = 2;
2024-03-13 23:50:11 +01:00
render_path_raytrace_ready = false;
2025-10-15 18:39:55 +02:00
context_raw.paint_body = null;
2024-03-13 23:50:11 +01:00
}
2024-05-03 21:29:39 +02:00
function _import_mesh_make_mesh(mesh: raw_mesh_t) {
2024-03-13 23:50:11 +01:00
let raw: mesh_data_t = import_mesh_raw_mesh(mesh);
2025-10-15 18:39:55 +02:00
let md: mesh_data_t = mesh_data_create(raw);
2024-03-13 23:50:11 +01:00
context_raw.paint_object = context_main_object();
context_select_paint_object(context_main_object());
2024-11-29 13:00:40 +01:00
2024-03-13 23:50:11 +01:00
for (let i: i32 = 0; i < project_paint_objects.length; ++i) {
let p: mesh_object_t = project_paint_objects[i];
2024-03-20 16:13:54 +01:00
if (p == context_raw.paint_object) {
continue;
}
2024-03-13 23:50:11 +01:00
data_delete_mesh(p.data._.handle);
mesh_object_remove(p);
}
2024-11-29 13:00:40 +01:00
2024-03-13 23:50:11 +01:00
let handle: string = context_raw.paint_object.data._.handle;
if (handle != "SceneSphere" && handle != "ScenePlane") {
2025-08-16 20:43:45 +02:00
sys_notify_on_next_frame(function(md: mesh_data_t) {
2025-01-06 21:49:01 +01:00
mesh_data_delete(md);
}, context_raw.paint_object.data);
2024-03-13 23:50:11 +01:00
}
mesh_object_set_data(context_raw.paint_object, md);
context_raw.paint_object.base.name = mesh.name;
2025-10-15 18:39:55 +02:00
project_paint_objects = [ context_raw.paint_object ];
2024-03-13 23:50:11 +01:00
2025-01-06 21:49:01 +01:00
md._.handle = string_copy(raw.name);
2024-03-20 16:13:54 +01:00
map_set(data_cached_meshes, md._.handle, md);
2024-03-13 23:50:11 +01:00
context_raw.ddirty = 4;
ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2;
ui_base_hwnds[tab_area_t.SIDEBAR1].redraws = 2;
2025-10-15 18:39:55 +02:00
util_uv_uvmap_cached = false;
util_uv_trianglemap_cached = false;
util_uv_dilatemap_cached = false;
2024-03-13 23:50:11 +01:00
if (import_mesh_clear_layers) {
while (project_layers.length > 0) {
2024-05-03 21:29:39 +02:00
let l: slot_layer_t = array_pop(project_layers);
2024-03-14 15:31:22 +01:00
slot_layer_unload(l);
2024-03-13 23:50:11 +01:00
}
2024-11-10 16:53:36 +01:00
layers_new_layer(false);
2025-08-16 20:43:45 +02:00
sys_notify_on_next_frame(layers_init);
2024-03-13 23:50:11 +01:00
history_reset();
}
2025-01-02 16:32:43 +01:00
// Wait for add_mesh calls to finish
2024-03-13 23:50:11 +01:00
if (import_mesh_meshes_to_unwrap != null) {
2025-03-11 19:49:42 +01:00
sys_notify_on_next_frame(import_mesh_finish_import);
2024-03-13 23:50:11 +01:00
}
else {
2025-08-16 20:43:45 +02:00
sys_notify_on_next_frame(import_mesh_finish_import);
2024-03-13 23:50:11 +01:00
}
}
2024-05-03 21:29:39 +02:00
function import_mesh_first_unwrap_done(mesh: raw_mesh_t) {
_import_mesh_make_mesh(mesh);
for (let i: i32 = 0; i < import_mesh_meshes_to_unwrap.length; ++i) {
let mesh: raw_mesh_t = import_mesh_meshes_to_unwrap[i];
project_unwrap_mesh_box(mesh, _import_mesh_add_mesh, true);
}
}
2024-08-25 21:47:36 +02:00
function import_mesh_make_mesh(mesh: raw_mesh_t) {
2024-03-13 23:50:11 +01:00
if (mesh == null || mesh.posa == null || mesh.nora == null || mesh.inda == null || mesh.posa.length == 0) {
2025-01-19 20:35:39 +01:00
console_error(strings_failed_to_read_mesh_data());
2024-03-13 23:50:11 +01:00
return;
}
if (mesh.texa == null) {
if (import_mesh_meshes_to_unwrap == null) {
import_mesh_meshes_to_unwrap = [];
}
2024-05-03 21:29:39 +02:00
project_unwrap_mesh_box(mesh, import_mesh_first_unwrap_done);
2024-03-13 23:50:11 +01:00
}
else {
_import_mesh_make_mesh(mesh);
}
}
2025-01-19 11:22:37 +01:00
function _import_mesh_is_unique_name(s: string): bool {
for (let i: i32 = 0; i < project_paint_objects.length; ++i) {
let p: mesh_object_t = project_paint_objects[i];
if (p.base.name == s) {
return false;
}
}
return true;
}
function _import_mesh_number_ext(i: i32): string {
if (i < 10) {
return ".00" + i;
}
if (i < 100) {
return ".0" + i;
}
return "." + i;
}
2024-05-03 21:29:39 +02:00
function _import_mesh_add_mesh(mesh: raw_mesh_t) {
2024-03-13 23:50:11 +01:00
let raw: mesh_data_t = import_mesh_raw_mesh(mesh);
2025-08-14 21:45:07 +02:00
if (context_raw.tool == tool_type_t.GIZMO) {
2025-09-16 15:03:51 +02:00
util_mesh_pack_uvs(mesh.texa);
2025-08-14 21:45:07 +02:00
}
2024-12-02 18:58:23 +01:00
2024-03-13 23:50:11 +01:00
let md: mesh_data_t = mesh_data_create(raw);
2025-09-02 19:32:15 +02:00
let object: mesh_object_t = scene_add_mesh_object(md, context_raw.paint_object.material, context_raw.paint_object.base);
2025-10-15 18:39:55 +02:00
object.base.name = mesh.name;
object.skip_context = "paint";
2024-03-13 23:50:11 +01:00
// Ensure unique names
2025-01-19 11:22:37 +01:00
let oname: string = object.base.name;
2025-10-15 18:39:55 +02:00
let ext: string = "";
let i: i32 = 0;
2025-01-19 11:22:37 +01:00
while (!_import_mesh_is_unique_name(oname + ext)) {
ext = _import_mesh_number_ext(++i);
}
object.base.name += ext;
raw.name += ext;
2024-03-13 23:50:11 +01:00
2024-03-20 16:13:54 +01:00
array_push(project_paint_objects, object);
2024-03-13 23:50:11 +01:00
2025-01-06 21:49:01 +01:00
md._.handle = string_copy(raw.name);
2024-03-20 16:13:54 +01:00
map_set(data_cached_meshes, md._.handle, md);
2024-03-13 23:50:11 +01:00
context_raw.ddirty = 4;
ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2;
2025-10-15 18:39:55 +02:00
util_uv_uvmap_cached = false;
util_uv_trianglemap_cached = false;
util_uv_dilatemap_cached = false;
2024-03-13 23:50:11 +01:00
}
2024-05-03 21:29:39 +02:00
function import_mesh_add_mesh(mesh: raw_mesh_t) {
2024-03-13 23:50:11 +01:00
if (mesh.texa == null) {
2024-03-20 16:13:54 +01:00
if (import_mesh_meshes_to_unwrap != null) {
array_push(import_mesh_meshes_to_unwrap, mesh);
}
else {
project_unwrap_mesh_box(mesh, _import_mesh_add_mesh);
}
2024-03-13 23:50:11 +01:00
}
else {
_import_mesh_add_mesh(mesh);
}
}
2024-05-03 21:29:39 +02:00
function import_mesh_raw_mesh(mesh: raw_mesh_t): mesh_data_t {
2024-07-22 00:14:37 +02:00
let raw: mesh_data_t = {
2025-10-15 18:39:55 +02:00
name : mesh.name,
vertex_arrays : [
{values : mesh.posa, attrib : "pos", data : "short4norm"}, {values : mesh.nora, attrib : "nor", data : "short2norm"},
{values : mesh.texa, attrib : "tex", data : "short2norm"}
2024-03-13 23:50:11 +01:00
],
2025-10-15 18:39:55 +02:00
index_array : mesh.inda,
scale_pos : mesh.scale_pos,
scale_tex : mesh.scale_tex
2024-03-13 23:50:11 +01:00
};
2025-01-06 15:18:02 +01:00
if (mesh.cola != null) {
2025-10-15 18:39:55 +02:00
let va: vertex_array_t = {values : mesh.cola, attrib : "col", data : "short4norm"};
2025-01-06 15:18:02 +01:00
array_push(raw.vertex_arrays, va);
}
2024-05-03 21:29:39 +02:00
return raw;
2024-03-13 23:50:11 +01:00
}