From 467dbce4a1789c9e00fc86346da522c29e0092de Mon Sep 17 00:00:00 2001 From: SiboVG Date: Mon, 21 Aug 2023 03:47:06 +0200 Subject: [PATCH] Add scaling option to OBJ export dialog --- core/resources/l10n/messages.properties | 4 +- .../wavefrontobj/export/OBJExportOptions.java | 8 ++++ .../src/net/sf/openrocket/unit/UnitGroup.java | 7 +++ .../file/wavefrontobj/OBJOptionChooser.java | 46 ++++++++++++------- 4 files changed, 48 insertions(+), 17 deletions(-) diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 10daf4f2e..3e5148004 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -1494,13 +1494,15 @@ OBJOptionChooser.checkbox.exportAppearance = Export appearance OBJOptionChooser.checkbox.exportAppearance.ttip = If true, export the component appearances to an MTL file. OBJOptionChooser.checkbox.exportAsSeparateFiles = Export as separate files OBJOptionChooser.checkbox.exportAsSeparateFiles.ttip = If true, export each component as a separate OBJ file. -OBJOptionChooser.checkbox.removeOffset = Remove offset +OBJOptionChooser.checkbox.removeOffset = Remove origin offset OBJOptionChooser.checkbox.removeOffset.ttip = If true, remove the offset of the component from the origin.
If false, the component is exported at its original location in the rocket. OBJOptionChooser.btn.showAdvanced = Show Advanced options OBJOptionChooser.checkbox.triangulate = Triangulate mesh OBJOptionChooser.checkbox.triangulate.ttip = If true, triangulate the mesh before exporting (convert all quads or high-order polygons to a triangle). OBJOptionChooser.checkbox.sRGB = Export colors in sRGB OBJOptionChooser.checkbox.sRGB.ttip = If true, export colors in sRGB instead of a linear color scheme.
Is useful for instance when exporting for use in Blender. +OBJOptionChooser.lbl.Scaling = Scaling: +OBJOptionChooser.lbl.Scaling.ttip = Scale the exported geometry by the given factor.
The default dimensions are in SI units (meters), but e.g. 3D printing slicer software often uses mm.
In that scenario, you can set the scale to '1000'. OBJOptionChooser.lbl.LevelOfDetail = Level of detail: OBJOptionChooser.lbl.LevelOfDetail.ttip = Select the desired level of detail of the geometry export. diff --git a/core/src/net/sf/openrocket/file/wavefrontobj/export/OBJExportOptions.java b/core/src/net/sf/openrocket/file/wavefrontobj/export/OBJExportOptions.java index 55f15713b..82766288b 100644 --- a/core/src/net/sf/openrocket/file/wavefrontobj/export/OBJExportOptions.java +++ b/core/src/net/sf/openrocket/file/wavefrontobj/export/OBJExportOptions.java @@ -116,10 +116,18 @@ public class OBJExportOptions { return scaling; } + public double getScalingDouble() { + return scaling; + } + public void setScaling(float scaling) { this.scaling = scaling; } + public void setScalingDouble(double scaling) { + this.scaling = (float) scaling; + } + public boolean isUseSRGB() { return useSRGB; } diff --git a/core/src/net/sf/openrocket/unit/UnitGroup.java b/core/src/net/sf/openrocket/unit/UnitGroup.java index eb5621687..6d0c5ba4d 100644 --- a/core/src/net/sf/openrocket/unit/UnitGroup.java +++ b/core/src/net/sf/openrocket/unit/UnitGroup.java @@ -80,6 +80,8 @@ public class UnitGroup { public static final UnitGroup UNITS_MOMENTUM; public static final UnitGroup UNITS_VOLTAGE; public static final UnitGroup UNITS_CURRENT; + + public static final UnitGroup UNITS_SCALING; public static final Map UNITS; // keys such as "LENGTH", "VELOCITY" @@ -290,6 +292,9 @@ public class UnitGroup { UNITS_COEFFICIENT = new UnitGroup(); UNITS_COEFFICIENT.addUnit(new FixedPrecisionUnit("" + ZWSP, 0.001)); // zero-width space + + UNITS_SCALING = new UnitGroup(); + UNITS_SCALING.addUnit(new FixedPrecisionUnit("" + ZWSP, 0.1)); // zero-width space // This is not used by OpenRocket, and not extensively tested: @@ -328,6 +333,7 @@ public class UnitGroup { map.put("RELATIVE", UNITS_RELATIVE); map.put("ROUGHNESS", UNITS_ROUGHNESS); map.put("COEFFICIENT", UNITS_COEFFICIENT); + map.put("SCALING", UNITS_SCALING); map.put("VOLTAGE", UNITS_VOLTAGE); map.put("CURRENT", UNITS_CURRENT); map.put("ENERGY", UNITS_ENERGY); @@ -450,6 +456,7 @@ public class UnitGroup { UNITS_RELATIVE.setDefaultUnit(1); UNITS_ROUGHNESS.setDefaultUnit(0); UNITS_COEFFICIENT.setDefaultUnit(0); + UNITS_SCALING.setDefaultUnit(0); UNITS_FREQUENCY.setDefaultUnit(1); } diff --git a/swing/src/net/sf/openrocket/file/wavefrontobj/OBJOptionChooser.java b/swing/src/net/sf/openrocket/file/wavefrontobj/OBJOptionChooser.java index 0b1c4c872..56817bd09 100644 --- a/swing/src/net/sf/openrocket/file/wavefrontobj/OBJOptionChooser.java +++ b/swing/src/net/sf/openrocket/file/wavefrontobj/OBJOptionChooser.java @@ -2,16 +2,20 @@ package net.sf.openrocket.file.wavefrontobj; import net.miginfocom.swing.MigLayout; import net.sf.openrocket.file.wavefrontobj.export.OBJExportOptions; +import net.sf.openrocket.gui.SpinnerEditor; +import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.rocketcomponent.ComponentAssembly; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.startup.Application; +import net.sf.openrocket.unit.UnitGroup; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSeparator; +import javax.swing.JSpinner; import javax.swing.JToggleButton; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; @@ -28,6 +32,7 @@ public class OBJOptionChooser extends JPanel { private final JCheckBox triangulate; private final JCheckBox sRGB; private final JComboBox LOD; + private final DoubleModel scalingModel; private final List selectedComponents; @@ -41,6 +46,11 @@ public class OBJOptionChooser extends JPanel { this.exportChildren = new JCheckBox(trans.get("OBJOptionChooser.checkbox.exportChildren")); this.add(exportChildren, "spanx, wrap"); + //// Remove origin offset + this.removeOffset = new JCheckBox(trans.get("OBJOptionChooser.checkbox.removeOffset")); + this.removeOffset.setToolTipText(trans.get("OBJOptionChooser.checkbox.removeOffset.ttip")); + this.add(removeOffset, "spanx, wrap unrel"); + //// Export appearance this.exportAppearance = new JCheckBox(trans.get("OBJOptionChooser.checkbox.exportAppearance")); this.exportAppearance.setToolTipText(trans.get("OBJOptionChooser.checkbox.exportAppearance.ttip")); @@ -49,12 +59,17 @@ public class OBJOptionChooser extends JPanel { //// Export as separate files this.exportAsSeparateFiles = new JCheckBox(trans.get("OBJOptionChooser.checkbox.exportAsSeparateFiles")); this.exportAsSeparateFiles.setToolTipText(trans.get("OBJOptionChooser.checkbox.exportAsSeparateFiles.ttip")); - this.add(exportAsSeparateFiles, "spanx, wrap"); + this.add(exportAsSeparateFiles, "spanx, wrap unrel"); - //// Remove offsets - this.removeOffset = new JCheckBox(trans.get("OBJOptionChooser.checkbox.removeOffset")); - this.removeOffset.setToolTipText(trans.get("OBJOptionChooser.checkbox.removeOffset.ttip")); - this.add(removeOffset, "spanx, wrap para"); + //// Scaling + JLabel scalingLabel = new JLabel(trans.get("OBJOptionChooser.lbl.Scaling")); + scalingLabel.setToolTipText(trans.get("OBJOptionChooser.lbl.Scaling.ttip")); + this.add(scalingLabel, "spanx, split 2"); + this.scalingModel = new DoubleModel(opts, "ScalingDouble", UnitGroup.UNITS_SCALING, 0, 10000); + JSpinner spin = new JSpinner(scalingModel.getSpinnerModel()); + spin.setToolTipText(trans.get("OBJOptionChooser.lbl.Scaling.ttip")); + spin.setEditor(new SpinnerEditor(spin)); + this.add(spin, "wrap para"); // ------------ Advanced options ------------ @@ -69,27 +84,23 @@ public class OBJOptionChooser extends JPanel { advancedOptionsPanel.setLayout(new MigLayout("ins 0")); advancedOptionsPanel.setVisible(false); - //// Triangulate - this.triangulate = new JCheckBox(trans.get("OBJOptionChooser.checkbox.triangulate")); - this.triangulate.setToolTipText(trans.get("OBJOptionChooser.checkbox.triangulate.ttip")); - advancedOptionsPanel.add(triangulate, "spanx, wrap"); - //// Export colors in sRGB this.sRGB = new JCheckBox(trans.get("OBJOptionChooser.checkbox.sRGB")); this.sRGB.setToolTipText(trans.get("OBJOptionChooser.checkbox.sRGB.ttip")); advancedOptionsPanel.add(sRGB, "spanx, wrap"); + //// Triangulate + this.triangulate = new JCheckBox(trans.get("OBJOptionChooser.checkbox.triangulate")); + this.triangulate.setToolTipText(trans.get("OBJOptionChooser.checkbox.triangulate.ttip")); + advancedOptionsPanel.add(triangulate, "spanx, wrap"); + //// Level of detail JLabel LODLabel = new JLabel(trans.get("OBJOptionChooser.lbl.LevelOfDetail")); LODLabel.setToolTipText(trans.get("OBJOptionChooser.lbl.LevelOfDetail.ttip")); - advancedOptionsPanel.add(LODLabel); + advancedOptionsPanel.add(LODLabel, "spanx, split 2"); this.LOD = new JComboBox<>(ObjUtils.LevelOfDetail.values()); this.LOD.setToolTipText(trans.get("OBJOptionChooser.lbl.LevelOfDetail.ttip")); - advancedOptionsPanel.add(LOD, "spanx, wrap para"); - - - //// Scale - // TODO: + (add tooltip text that mm is useful for 3D printing) + advancedOptionsPanel.add(LOD, "growx, wrap para"); //// Coordinate transformer @@ -131,6 +142,8 @@ public class OBJOptionChooser extends JPanel { this.triangulate.setSelected(opts.isTriangulate()); this.sRGB.setSelected(opts.isUseSRGB()); + this.scalingModel.setValue(opts.getScaling()); + this.LOD.setSelectedItem(opts.getLOD()); } @@ -151,6 +164,7 @@ public class OBJOptionChooser extends JPanel { opts.setRemoveOffset(removeOffset.isSelected()); opts.setTriangulate(triangulate.isSelected()); opts.setUseSRGB(sRGB.isSelected()); + opts.setScaling((float) scalingModel.getValue()); opts.setLOD((ObjUtils.LevelOfDetail) LOD.getSelectedItem()); }