diff --git a/app/src/main/java/ru/ytkab0bp/slicebeam/MainActivity.java b/app/src/main/java/ru/ytkab0bp/slicebeam/MainActivity.java index 58a4d7b..62d985c 100644 --- a/app/src/main/java/ru/ytkab0bp/slicebeam/MainActivity.java +++ b/app/src/main/java/ru/ytkab0bp/slicebeam/MainActivity.java @@ -5,7 +5,6 @@ import android.content.ContentResolver; import android.content.ContentValues; import android.content.Intent; import android.content.res.Configuration; -import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; @@ -21,7 +20,6 @@ import android.util.Log; import android.util.SparseArray; import android.view.View; import android.view.WindowManager; -import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -58,6 +56,7 @@ import ru.ytkab0bp.slicebeam.events.NeedDismissSnackbarEvent; import ru.ytkab0bp.slicebeam.events.NeedSnackbarEvent; import ru.ytkab0bp.slicebeam.events.ObjectsListChangedEvent; import ru.ytkab0bp.slicebeam.fragment.BedFragment; +import ru.ytkab0bp.slicebeam.navigation.Fragment; import ru.ytkab0bp.slicebeam.navigation.MobileNavigationDelegate; import ru.ytkab0bp.slicebeam.navigation.NavigationDelegate; import ru.ytkab0bp.slicebeam.slic3r.Model; @@ -71,7 +70,8 @@ import ru.ytkab0bp.slicebeam.view.SnackbarsLayout; public class MainActivity extends AppCompatActivity { public final static int REQUEST_CODE_OPEN_FILE = 1, REQUEST_CODE_EXPORT_GCODE = 2, - REQUEST_CODE_IMPORT_PROFILES = 3, REQUEST_CODE_EXPORT_PROFILES = 4; + REQUEST_CODE_IMPORT_PROFILES = 3, REQUEST_CODE_EXPORT_PROFILES = 4, + REQUEST_CODE_EXPORT_3MF = 5, private static MainActivity activeInstance; @@ -203,12 +203,39 @@ public class MainActivity extends AppCompatActivity { setIntent(null); } + /** @noinspection ResultOfMethodCallIgnored*/ @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == Activity.RESULT_OK) { - if (requestCode == MainActivity.REQUEST_CODE_EXPORT_GCODE) { + if (requestCode == MainActivity.REQUEST_CODE_EXPORT_3MF) { + Fragment fragment = getNavigationDelegate().getCurrentFragment(); + if (fragment instanceof BedFragment) { + try { + OutputStream out = getContentResolver().openOutputStream(data.getData()); + Model model = ((BedFragment) fragment).getGlView().getRenderer().getModel(); + File tempFile = File.createTempFile("temp_project", ".3mf"); + SliceBeam.genCurrentConfig(); + File cfg = SliceBeam.getCurrentConfigFile(); + model.export3mf(cfg.getAbsolutePath(), tempFile.getAbsolutePath()); + + InputStream in = new FileInputStream(tempFile); + byte[] buffer = new byte[10240]; + int c; + while ((c = in.read(buffer)) != -1) { + out.write(buffer, 0, c); + } + in.close(); + out.close(); + tempFile.delete(); + + SliceBeam.EVENT_BUS.fireEvent(new NeedSnackbarEvent(R.string.MenuFileExport3mfSuccess)); + } catch (IOException | Slic3rRuntimeError e) { + throw new RuntimeException(e); + } + } + } else if (requestCode == MainActivity.REQUEST_CODE_EXPORT_GCODE) { try { OutputStream out = getContentResolver().openOutputStream(data.getData()); InputStream in = new FileInputStream(BedFragment.getTempGCodePath()); diff --git a/app/src/main/java/ru/ytkab0bp/slicebeam/slic3r/Model.java b/app/src/main/java/ru/ytkab0bp/slicebeam/slic3r/Model.java index 51f9055..6d1eb19 100644 --- a/app/src/main/java/ru/ytkab0bp/slicebeam/slic3r/Model.java +++ b/app/src/main/java/ru/ytkab0bp/slicebeam/slic3r/Model.java @@ -167,6 +167,10 @@ public class Model { return new GCodeProcessorResult(Native.model_slice(pointer, configPath, gcodePath, listener)); } + public void export3mf(String configPath, String _3mfPath) throws Slic3rRuntimeError { + Native.model_export_3mf(pointer, configPath, _3mfPath); + } + public void release() { if (pointer != 0) { Native.model_release(pointer); diff --git a/app/src/main/java/ru/ytkab0bp/slicebeam/slic3r/Native.java b/app/src/main/java/ru/ytkab0bp/slicebeam/slic3r/Native.java index 693cf0c..27680a6 100644 --- a/app/src/main/java/ru/ytkab0bp/slicebeam/slic3r/Native.java +++ b/app/src/main/java/ru/ytkab0bp/slicebeam/slic3r/Native.java @@ -76,6 +76,7 @@ class Native { static native int model_get_extruder(long ptr, int i); static native void model_set_extruder(long ptr, int i, int extruder); static native long model_slice(long ptr, String configPath, String path, SliceListener listener) throws Slic3rRuntimeError; + static native void model_export_3mf(long ptr, String configPath, String path) throws Slic3rRuntimeError; static native void model_release(long ptr); static native long gcoderesult_load_file(String path, String name); diff --git a/app/src/main/jni/slicebeam/beam_native.cpp b/app/src/main/jni/slicebeam/beam_native.cpp index a9699e5..d040446 100644 --- a/app/src/main/jni/slicebeam/beam_native.cpp +++ b/app/src/main/jni/slicebeam/beam_native.cpp @@ -5,13 +5,13 @@ #include "libslic3r/Config.hpp" #include "libslic3r/Model.hpp" #include "libslic3r/Print.hpp" -#include "libslic3r/PresetBundle.hpp" #include "libslic3r/ModelArrange.hpp" #include "libslic3r/SVG.hpp" #include "libslic3r/Geometry.hpp" #include "libslic3r/Arrange.hpp" #include "libslic3r/AABBMesh.hpp" #include "libslic3r/Geometry/ConvexHull.hpp" +#include "libslic3r/Format/3mf.hpp" #include "bbl/Orient.hpp" #include "Viewer.hpp" @@ -840,11 +840,10 @@ extern "C" { ModelRef* model = (ModelRef*) (intptr_t) ptr; Print print; - PresetBundle bundle; DynamicPrintConfig config; const char *chars = env->GetStringUTFChars(configPath, JNI_FALSE); config.load(std::string(chars), ForwardCompatibilitySubstitutionRule::Disable); - env->ReleaseStringUTFChars(path, chars); + env->ReleaseStringUTFChars(configPath, chars); config.normalize_fdm(); for (auto* mo : model->model.objects) { @@ -901,6 +900,24 @@ extern "C" { } } + JNIEXPORT void JNICALL Java_ru_ytkab0bp_slicebeam_slic3r_Native_model_1export_13mf(JNIEnv* env, jclass, jlong ptr, jstring configPath, jstring path) { + auto model = reinterpret_cast(ptr); + + try { + DynamicPrintConfig config; + const char *chars = env->GetStringUTFChars(configPath, JNI_FALSE); + config.load(std::string(chars), ForwardCompatibilitySubstitutionRule::Disable); + env->ReleaseStringUTFChars(configPath, chars); + config.normalize_fdm(); + + const char *pathChars = env->GetStringUTFChars(path, JNI_FALSE); + Slic3r::store_3mf(pathChars, &model->model, &config, false, nullptr, false); + env->ReleaseStringUTFChars(path, pathChars); + } catch (const std::exception& e) { + env->ThrowNew(env->FindClass("ru/ytkab0bp/slicebeam/slic3r/Slic3rRuntimeError"), e.what()); + } + } + JNIEXPORT void JNICALL Java_ru_ytkab0bp_slicebeam_slic3r_Native_model_1release(JNIEnv* env, jclass, jlong ptr) { ModelRef* model = (ModelRef*) (intptr_t) ptr; delete model; diff --git a/app/src/main/res/drawable/arrow_down_to_square_outline_28.xml b/app/src/main/res/drawable/arrow_down_to_square_outline_28.xml new file mode 100644 index 0000000..2a0bfe0 --- /dev/null +++ b/app/src/main/res/drawable/arrow_down_to_square_outline_28.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 89cbb49..d259336 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -42,6 +42,8 @@ Принтеры Не выбрано ни одного профиля. Профили успешно экспортированы. + Экспорт. 3mf + Успешно экспортировали проект. Камера Изомет.\nвид Вид\nсверху diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9947a9e..5235175 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -44,6 +44,8 @@ Printers No profiles selected. Exported profiles successfully. + Export 3mf + Successfully exported project. Camera Isom. view Top view