diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties
index d5b1f3809..43dca9b4c 100644
--- a/core/resources/l10n/messages.properties
+++ b/core/resources/l10n/messages.properties
@@ -89,7 +89,7 @@ BasicFrame.WarningDialog.txt2 = Some design features may not have been loaded co
BasicFrame.WarningDialog.saving.txt1 = The following problems were encountered while saving
BasicFrame.WarningDialog.saving.txt2 = Some design features may not have exported correctly.
BasicFrame.WarningDialog.title = Warnings while opening file
-BasicFrame.WarningDialog.saving.title = Warnings while opening file
+BasicFrame.WarningDialog.saving.title = Warnings while saving file
BasicFrame.ErrorWarningDialog.txt1 = Please correct the errors.
BasicFrame.ErrorWarningDialog.saving.title = Errors/Warnings while saving file
BasicFrame.lbl.SaveRocketInfo = Save Design Info
@@ -1048,7 +1048,7 @@ RocketCompCfg.lbl.Length = Length:
RocketCompCfg.lbl.Thickness = Thickness:
RocketCompCfg.checkbox.Endcapped = End capped
RocketCompCfg.checkbox.Endcapped.ttip = Caps (closes) the end of the shoulder.
-RocketCompCfg.title.Aftshoulder = Aft shoulder
+RocketCompCfg.border.Aftshoulder = Aft shoulder
RocketCompCfg.border.Foreshoulder = Fore shoulder
RocketCompCfg.tab.Outside = Outside
RocketCompCfg.tab.Inside = Inside
@@ -2097,6 +2097,7 @@ Warning.TUBE_OVERLAP = Overlapping tube fins may not simulate accurately.
Warning.EMPTY_BRANCH = Simulation branch contains no data
Warning.SEPARATION_ORDER = Stages separated in an unreasonable order
Warning.EARLY_SEPARATION = Stages separated before clearing launch rod/rail
+Warning.OBJ_ZERO_THICKNESS = Zero-thickness component can cause issues for 3D printing
! Scale dialog
ScaleDialog.lbl.scaleRocket = Entire rocket
diff --git a/core/resources/l10n/messages_ar.properties b/core/resources/l10n/messages_ar.properties
index 5a957d4cc..363b0bd02 100644
--- a/core/resources/l10n/messages_ar.properties
+++ b/core/resources/l10n/messages_ar.properties
@@ -951,7 +951,7 @@ RocketCompCfg.lbl.Length = :الطول
RocketCompCfg.lbl.Thickness = :السماكة
RocketCompCfg.checkbox.Endcapped = نهاية مغلقة
RocketCompCfg.checkbox.Endcapped.ttip = .يغلق نهاية الكتف
-RocketCompCfg.title.Aftshoulder = مؤخرة الكتف
+RocketCompCfg.border.Aftshoulder = مؤخرة الكتف
RocketCompCfg.border.Foreshoulder = مقدمة الكتف
!RocketCompCfg.lbl.Length = :الطول
RocketCompCfg.tab.Outside = من الخارج
diff --git a/core/resources/l10n/messages_cs.properties b/core/resources/l10n/messages_cs.properties
index a1b326463..04106b5b8 100644
--- a/core/resources/l10n/messages_cs.properties
+++ b/core/resources/l10n/messages_cs.properties
@@ -651,7 +651,7 @@ RocketCompCfg.lbl.Length = D
RocketCompCfg.lbl.Thickness = Tlou\u0161tka:
RocketCompCfg.checkbox.Endcapped = Zslepka
RocketCompCfg.ttip.Endcapped = Zdali je konec ramene zaslepen.
-RocketCompCfg.title.Aftshoulder = Dr\u017Ek zdi
+RocketCompCfg.border.Aftshoulder = Dr\u017Ek zdi
RocketCompCfg.border.Foreshoulder = Dr\u017Ek prdi
!RocketCompCfg.lbl.Length = Dlka:
diff --git a/core/resources/l10n/messages_de.properties b/core/resources/l10n/messages_de.properties
index 007a46da3..e888f8944 100644
--- a/core/resources/l10n/messages_de.properties
+++ b/core/resources/l10n/messages_de.properties
@@ -708,7 +708,7 @@ RocketCompCfg.lbl.Length = L
RocketCompCfg.lbl.Thickness = Wandstrke:
RocketCompCfg.checkbox.Endcapped = Verschlossenes Ende
RocketCompCfg.ttip.Endcapped = Gibt an, ob das Ende der Schulter geschlossen ist.
-RocketCompCfg.title.Aftshoulder = Schulter hinten
+RocketCompCfg.border.Aftshoulder = Schulter hinten
RocketCompCfg.border.Foreshoulder = Schulter vorn
!RocketCompCfg.lbl.Length = Length:
diff --git a/core/resources/l10n/messages_es.properties b/core/resources/l10n/messages_es.properties
index db5dc37d1..49c52554e 100644
--- a/core/resources/l10n/messages_es.properties
+++ b/core/resources/l10n/messages_es.properties
@@ -857,7 +857,7 @@ RocketCompCfg.tab.Figure = Estilo
RocketCompCfg.tab.Override.ttip = Especificar la Masa y el CG del componente.
RocketCompCfg.tab.Override = Masa y CG
RocketCompCfg.tab.Comment.ttip = Especifique un comentario para el componente
-RocketCompCfg.title.Aftshoulder = Trasera del acople
+RocketCompCfg.border.Aftshoulder = Trasera del acople
RocketCompCfg.ttip.Endcapped = Si el extremo del soporte est\u00e1 truncado.
RocketCompCfg.lbl.Componentname.ttip = El nombre del componente.
diff --git a/core/resources/l10n/messages_fr.properties b/core/resources/l10n/messages_fr.properties
index fbbdd38e5..65686aca6 100644
--- a/core/resources/l10n/messages_fr.properties
+++ b/core/resources/l10n/messages_fr.properties
@@ -849,7 +849,7 @@ RocketCompCfg.tab.Figure = Forme
RocketCompCfg.tab.Override.ttip = For\u00E7age de la Masse et du CG
RocketCompCfg.tab.Override = Forcer la valeur
RocketCompCfg.tab.Comment.ttip = Commentaires concernant la pi\u00E8ce
-RocketCompCfg.title.Aftshoulder = Epaulement arri\u00E8re
+RocketCompCfg.border.Aftshoulder = Epaulement arri\u00E8re
RocketCompCfg.ttip.Endcapped = Pr\u00E9cise si l'arri\u00E8re du c\u00F4ne est clos.
RocketCompCfg.lbl.Componentname.ttip = Le nom de la pi\u00E8ce.
diff --git a/core/resources/l10n/messages_it.properties b/core/resources/l10n/messages_it.properties
index 58d24f634..14fa090db 100644
--- a/core/resources/l10n/messages_it.properties
+++ b/core/resources/l10n/messages_it.properties
@@ -709,7 +709,7 @@ RocketCompCfg.lbl.Length = Lunghezza:
RocketCompCfg.lbl.Thickness = Spessore:
RocketCompCfg.checkbox.Endcapped = Chiuso
RocketCompCfg.ttip.Endcapped = Se la fine della spalla e' chiusa.
-RocketCompCfg.title.Aftshoulder = Spalla posteriore
+RocketCompCfg.border.Aftshoulder = Spalla posteriore
RocketCompCfg.border.Foreshoulder = Spalla anteriore
!RocketCompCfg.lbl.Length = Lunghezza:
diff --git a/core/resources/l10n/messages_ja.properties b/core/resources/l10n/messages_ja.properties
index a593c4c62..bba01aa9b 100644
--- a/core/resources/l10n/messages_ja.properties
+++ b/core/resources/l10n/messages_ja.properties
@@ -739,7 +739,7 @@ RocketCompCfg.lbl.Length = \u9577\u3055\uFF1A
RocketCompCfg.lbl.Thickness = \u539A\u3055\uFF1A
RocketCompCfg.checkbox.Endcapped = \u7AEF\u306B\u30D5\u30BF\u3092\u3059\u308B
RocketCompCfg.ttip.Endcapped = \u30D5\u30BF\u304C\u3042\u308B\u304B\u3069\u3046\u304B
-RocketCompCfg.title.Aftshoulder = \u5F8C\u65B9\u30B7\u30E7\u30EB\u30C0\u30FC
+RocketCompCfg.border.Aftshoulder = \u5F8C\u65B9\u30B7\u30E7\u30EB\u30C0\u30FC
RocketCompCfg.border.Foreshoulder = \u524D\u65B9\u30B7\u30E7\u30EB\u30C0\u30FC
!RocketCompCfg.lbl.Length
diff --git a/core/resources/l10n/messages_nl.properties b/core/resources/l10n/messages_nl.properties
index 9b9615c49..2b45dbd5f 100644
--- a/core/resources/l10n/messages_nl.properties
+++ b/core/resources/l10n/messages_nl.properties
@@ -898,7 +898,7 @@ RocketCompCfg.lbl.Length = Lengte:
RocketCompCfg.lbl.Thickness = Dikte:
RocketCompCfg.checkbox.Endcapped = Einde afgetopt
RocketCompCfg.ttip.Endcapped = Of het einde van de schouder is afgedekt.
-RocketCompCfg.title.Aftshoulder = Achterschouder
+RocketCompCfg.border.Aftshoulder = Achterschouder
RocketCompCfg.border.Foreshoulder = Voorschouder
!RocketCompCfg.lbl.Length = Lengte:
RocketCompCfg.tab.Outside = Buitenkant
diff --git a/core/resources/l10n/messages_pl.properties b/core/resources/l10n/messages_pl.properties
index 69ba91cdb..f75ac3382 100644
--- a/core/resources/l10n/messages_pl.properties
+++ b/core/resources/l10n/messages_pl.properties
@@ -653,7 +653,7 @@ update.dlg.latestVersion = Korzystasz z najnowszej wersji OpenRocket: %s.
RocketCompCfg.lbl.Thickness = Grubo\u015B\u0107:
RocketCompCfg.checkbox.Endcapped = Zasklepiony koniec
RocketCompCfg.ttip.Endcapped = Czy koniec wpustu jest zasklepiony.
- RocketCompCfg.title.Aftshoulder = Wpust tylny
+ RocketCompCfg.border.Aftshoulder = Wpust tylny
RocketCompCfg.border.Foreshoulder = Wpust przedni
!RocketCompCfg.lbl.Length
diff --git a/core/resources/l10n/messages_pt.properties b/core/resources/l10n/messages_pt.properties
index 89feaa3e6..f4984a407 100644
--- a/core/resources/l10n/messages_pt.properties
+++ b/core/resources/l10n/messages_pt.properties
@@ -832,7 +832,7 @@ RocketCompCfg.tab.Figure = Figura
RocketCompCfg.tab.Override.ttip = Op\u00e7\u00f5es de modifica\u00e7\u00e3o de massa e CG
RocketCompCfg.tab.Override = Modificar
RocketCompCfg.tab.Comment.ttip = Especifique um coment\u00e1rio para o componente
-RocketCompCfg.title.Aftshoulder = Ressalto traseiro
+RocketCompCfg.border.Aftshoulder = Ressalto traseiro
RocketCompCfg.ttip.Endcapped = Quando a extremidade do ressalto \u00e9 limitada.
RocketCompCfg.lbl.Componentname.ttip = Nome do componente.
diff --git a/core/resources/l10n/messages_ru.properties b/core/resources/l10n/messages_ru.properties
index 7da3fd403..6b4db81ef 100644
--- a/core/resources/l10n/messages_ru.properties
+++ b/core/resources/l10n/messages_ru.properties
@@ -929,7 +929,7 @@ RocketCompCfg.lbl.Length = \u0414\u043B\u0438\u043D\u0430:
RocketCompCfg.lbl.Thickness = \u0422\u043E\u043B\u0449\u0438\u043D\u0430:
RocketCompCfg.checkbox.Endcapped = \u0422\u043E\u0440\u0435\u0446 \u0437\u0430\u0433\u043B\u0443\u0448\u0435\u043D
RocketCompCfg.checkbox.Endcapped.ttip = \u0417\u0430\u0433\u043B\u0443\u0448\u0430\u0435\u0442 \u0442\u043E\u0440\u0435\u0446 \u043A\u0440\u044B\u0448\u043A\u043E\u0439.
-RocketCompCfg.title.Aftshoulder = \u0417\u0430\u0434\u043D\u0438\u0439 \u0432\u044B\u0441\u0442\u0443\u043F
+RocketCompCfg.border.Aftshoulder = \u0417\u0430\u0434\u043D\u0438\u0439 \u0432\u044B\u0441\u0442\u0443\u043F
RocketCompCfg.border.Foreshoulder = \u041F\u0435\u0440\u0435\u0434\u043D\u0438\u0439 \u0432\u044B\u0441\u0442\u0443\u043F
!RocketCompCfg.lbl.Length = \u0414\u043B\u0438\u043D\u0430:
RocketCompCfg.tab.Outside = \u0421\u043D\u0430\u0440\u0443\u0436\u0438
diff --git a/core/resources/l10n/messages_uk_UA.properties b/core/resources/l10n/messages_uk_UA.properties
index 08550fd70..e2c53e030 100644
--- a/core/resources/l10n/messages_uk_UA.properties
+++ b/core/resources/l10n/messages_uk_UA.properties
@@ -811,7 +811,7 @@ RocketCompCfg.lbl.Length = Length:
RocketCompCfg.lbl.Thickness = Thickness:
RocketCompCfg.checkbox.Endcapped = End capped
RocketCompCfg.ttip.Endcapped = Whether the end of the shoulder is capped.
-RocketCompCfg.title.Aftshoulder = Aft shoulder
+RocketCompCfg.border.Aftshoulder = Aft shoulder
RocketCompCfg.border.Foreshoulder = Fore shoulder
!RocketCompCfg.lbl.Length = Length:
diff --git a/core/resources/l10n/messages_zh_CN.properties b/core/resources/l10n/messages_zh_CN.properties
index 0a6180ad8..f3c543eae 100644
--- a/core/resources/l10n/messages_zh_CN.properties
+++ b/core/resources/l10n/messages_zh_CN.properties
@@ -921,7 +921,7 @@ RocketCompCfg.tab.Figure = \u6837\u5F0F
RocketCompCfg.tab.Override.ttip = \u8D28\u91CF\u53CA\u91CD\u5FC3\u9009\u9879
RocketCompCfg.tab.Override = \u8986\u5199
RocketCompCfg.tab.Comment.ttip = \u7EC4\u4EF6\u6CE8\u91CA
-RocketCompCfg.title.Aftshoulder = \u524D\u8FDE\u63A5\u5904
+RocketCompCfg.border.Aftshoulder = \u524D\u8FDE\u63A5\u5904
RocketCompCfg.ttip.Endcapped = \u8FDE\u63A5\u5904\u7EC8\u7AEF\u662F\u5426\u6709\u76D6.
RocketCompCfg.lbl.Componentname.ttip = \u7EC4\u4EF6\u540D\u79F0.
diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java b/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java
index 6995c8210..2984b3505 100644
--- a/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java
@@ -234,7 +234,8 @@ class DocumentConfig {
false));
setters.put("Transition:foreshoulderradius", new DoubleSetter(
- Reflection.findMethod(Transition.class, "setForeShoulderRadius", double.class)));
+ Reflection.findMethod(Transition.class, "setForeShoulderRadius", double.class, boolean.class),
+ null, null, false));
setters.put("Transition:foreshoulderlength", new DoubleSetter(
Reflection.findMethod(Transition.class, "setForeShoulderLength", double.class)));
setters.put("Transition:foreshoulderthickness", new DoubleSetter(
@@ -243,7 +244,8 @@ class DocumentConfig {
Reflection.findMethod(Transition.class, "setForeShoulderCapped", boolean.class)));
setters.put("Transition:aftshoulderradius", new DoubleSetter(
- Reflection.findMethod(Transition.class, "setAftShoulderRadius", double.class)));
+ Reflection.findMethod(Transition.class, "setAftShoulderRadius", double.class, boolean.class),
+ null, null, false));
setters.put("Transition:aftshoulderlength", new DoubleSetter(
Reflection.findMethod(Transition.class, "setAftShoulderLength", double.class)));
setters.put("Transition:aftshoulderthickness", new DoubleSetter(
diff --git a/core/src/net/sf/openrocket/file/wavefrontobj/export/OBJExporterFactory.java b/core/src/net/sf/openrocket/file/wavefrontobj/export/OBJExporterFactory.java
index 8e856cc64..a71739583 100644
--- a/core/src/net/sf/openrocket/file/wavefrontobj/export/OBJExporterFactory.java
+++ b/core/src/net/sf/openrocket/file/wavefrontobj/export/OBJExporterFactory.java
@@ -18,6 +18,7 @@ import net.sf.openrocket.file.wavefrontobj.export.components.RocketComponentExpo
import net.sf.openrocket.file.wavefrontobj.export.components.RingComponentExporter;
import net.sf.openrocket.file.wavefrontobj.export.components.TransitionExporter;
import net.sf.openrocket.file.wavefrontobj.export.components.TubeFinSetExporter;
+import net.sf.openrocket.logging.WarningSet;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.MotorConfiguration;
import net.sf.openrocket.rocketcomponent.BodyTube;
@@ -69,6 +70,7 @@ public class OBJExporterFactory {
private final FlightConfiguration configuration;
private final OBJExportOptions options;
private final File file;
+ private final WarningSet warnings;
private static final Logger log = LoggerFactory.getLogger(OBJExporterFactory.class);
@@ -93,11 +95,12 @@ public class OBJExporterFactory {
* @param file The file to export the OBJ to
*/
public OBJExporterFactory(List components, FlightConfiguration configuration, File file,
- OBJExportOptions options) {
+ OBJExportOptions options, WarningSet warnings) {
this.components = components;
this.configuration = configuration;
this.file = file;
this.options = options;
+ this.warnings = warnings;
}
/**
@@ -152,7 +155,7 @@ public class OBJExporterFactory {
// Component exporting
String groupName = idx + "_" + component.getName();
handleComponent(obj, this.configuration, this.options.getTransformer(), component, groupName,
- materials.get(obj), this.options.getLOD(), options);
+ materials.get(obj), this.options.getLOD(), options, warnings);
// If separate export, add this object to the map of objects to export
if (exportAsSeparateFiles) {
@@ -225,7 +228,8 @@ public class OBJExporterFactory {
@SuppressWarnings("unchecked") // This is safe because of the structure we set up.
private void handleComponent(DefaultObj obj, FlightConfiguration config, CoordTransform transformer,
T component, String groupName, List materials,
- ObjUtils.LevelOfDetail LOD, OBJExportOptions options) {
+ ObjUtils.LevelOfDetail LOD, OBJExportOptions options,
+ WarningSet warnings) {
ExporterFactory factory = null;
Class> currentClass = component.getClass();
@@ -254,7 +258,7 @@ public class OBJExporterFactory {
}
// Export component
- final RocketComponentExporter exporter = factory.create(obj, config, transformer, component, groupName, LOD);
+ final RocketComponentExporter exporter = factory.create(obj, config, transformer, component, groupName, LOD, warnings);
exporter.addToObj();
// Export motor
@@ -272,7 +276,7 @@ public class OBJExporterFactory {
}
// Export the motor geometry
- MotorExporter motorExporter = new MotorExporter(obj, config, transformer, component, groupName, LOD);
+ MotorExporter motorExporter = new MotorExporter(obj, config, transformer, component, groupName, LOD, warnings);
motorExporter.addToObj();
}
}
@@ -300,6 +304,6 @@ public class OBJExporterFactory {
interface ExporterFactory {
RocketComponentExporter create(DefaultObj obj, FlightConfiguration config, CoordTransform transformer,
- T component, String groupName, ObjUtils.LevelOfDetail LOD);
+ T component, String groupName, ObjUtils.LevelOfDetail LOD, WarningSet warnings);
}
}
diff --git a/core/src/net/sf/openrocket/file/wavefrontobj/export/components/BodyTubeExporter.java b/core/src/net/sf/openrocket/file/wavefrontobj/export/components/BodyTubeExporter.java
index d6a482b87..f40b53d2e 100644
--- a/core/src/net/sf/openrocket/file/wavefrontobj/export/components/BodyTubeExporter.java
+++ b/core/src/net/sf/openrocket/file/wavefrontobj/export/components/BodyTubeExporter.java
@@ -4,6 +4,8 @@ import net.sf.openrocket.file.wavefrontobj.CoordTransform;
import net.sf.openrocket.file.wavefrontobj.DefaultObj;
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
import net.sf.openrocket.file.wavefrontobj.export.shapes.TubeExporter;
+import net.sf.openrocket.logging.Warning;
+import net.sf.openrocket.logging.WarningSet;
import net.sf.openrocket.rocketcomponent.BodyTube;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.InstanceContext;
@@ -11,8 +13,8 @@ import net.sf.openrocket.util.Coordinate;
public class BodyTubeExporter extends RocketComponentExporter {
public BodyTubeExporter(DefaultObj obj, FlightConfiguration config, CoordTransform transformer, BodyTube component,
- String groupName, ObjUtils.LevelOfDetail LOD) {
- super(obj, config, transformer, component, groupName, LOD);
+ String groupName, ObjUtils.LevelOfDetail LOD, WarningSet warnings) {
+ super(obj, config, transformer, component, groupName, LOD, warnings);
}
@Override
@@ -24,6 +26,10 @@ public class BodyTubeExporter extends RocketComponentExporter {
final float length = (float) component.getLength();
final boolean isFilled = component.isFilled();
+ if (Double.compare(component.getThickness(), 0) == 0) {
+ warnings.add(Warning.OBJ_ZERO_THICKNESS, component.getName());
+ }
+
// Generate the mesh
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
generateMesh(outerRadius, innerRadius, length, isFilled, context);
diff --git a/core/src/net/sf/openrocket/file/wavefrontobj/export/components/FinSetExporter.java b/core/src/net/sf/openrocket/file/wavefrontobj/export/components/FinSetExporter.java
index abfb6ca8f..7176857cf 100644
--- a/core/src/net/sf/openrocket/file/wavefrontobj/export/components/FinSetExporter.java
+++ b/core/src/net/sf/openrocket/file/wavefrontobj/export/components/FinSetExporter.java
@@ -6,6 +6,8 @@ import net.sf.openrocket.file.wavefrontobj.CoordTransform;
import net.sf.openrocket.file.wavefrontobj.DefaultObj;
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
import net.sf.openrocket.file.wavefrontobj.export.shapes.PolygonExporter;
+import net.sf.openrocket.logging.Warning;
+import net.sf.openrocket.logging.WarningSet;
import net.sf.openrocket.rocketcomponent.FinSet;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.InstanceContext;
@@ -16,8 +18,8 @@ import java.util.List;
public class FinSetExporter extends RocketComponentExporter {
public FinSetExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
- FinSet component, String groupName, ObjUtils.LevelOfDetail LOD) {
- super(obj, config, transformer, component, groupName, LOD);
+ FinSet component, String groupName, ObjUtils.LevelOfDetail LOD, WarningSet warnings) {
+ super(obj, config, transformer, component, groupName, LOD, warnings);
}
@Override
@@ -35,6 +37,10 @@ public class FinSetExporter extends RocketComponentExporter {
final float thickness = (float) component.getThickness();
boolean hasTabs = component.getTabLength() > 0 && component.getTabHeight() > 0;
+ if (Float.compare(thickness, 0) == 0) {
+ warnings.add(Warning.OBJ_ZERO_THICKNESS, component.getName());
+ }
+
// Generate the fin meshes
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
generateMesh(floatPoints, floatTabPoints, thickness, hasTabs, context);
diff --git a/core/src/net/sf/openrocket/file/wavefrontobj/export/components/LaunchLugExporter.java b/core/src/net/sf/openrocket/file/wavefrontobj/export/components/LaunchLugExporter.java
index ddd5351d3..af88edcf4 100644
--- a/core/src/net/sf/openrocket/file/wavefrontobj/export/components/LaunchLugExporter.java
+++ b/core/src/net/sf/openrocket/file/wavefrontobj/export/components/LaunchLugExporter.java
@@ -5,6 +5,8 @@ import net.sf.openrocket.file.wavefrontobj.CoordTransform;
import net.sf.openrocket.file.wavefrontobj.DefaultObj;
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
import net.sf.openrocket.file.wavefrontobj.export.shapes.TubeExporter;
+import net.sf.openrocket.logging.Warning;
+import net.sf.openrocket.logging.WarningSet;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.InstanceContext;
import net.sf.openrocket.rocketcomponent.LaunchLug;
@@ -12,8 +14,8 @@ import net.sf.openrocket.util.Coordinate;
public class LaunchLugExporter extends RocketComponentExporter {
public LaunchLugExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
- LaunchLug component, String groupName, ObjUtils.LevelOfDetail LOD) {
- super(obj, config, transformer, component, groupName, LOD);
+ LaunchLug component, String groupName, ObjUtils.LevelOfDetail LOD, WarningSet warnings) {
+ super(obj, config, transformer, component, groupName, LOD, warnings);
}
@Override
@@ -24,6 +26,10 @@ public class LaunchLugExporter extends RocketComponentExporter {
final float innerRadius = (float) component.getInnerRadius();
final float length = (float) component.getLength();
+ if (Double.compare(component.getThickness(), 0) == 0) {
+ warnings.add(Warning.OBJ_ZERO_THICKNESS, component.getName());
+ }
+
// Generate the mesh
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
generateMesh(outerRadius, innerRadius, length, context);
diff --git a/core/src/net/sf/openrocket/file/wavefrontobj/export/components/MassObjectExporter.java b/core/src/net/sf/openrocket/file/wavefrontobj/export/components/MassObjectExporter.java
index 4eb2e43f3..470aac6bf 100644
--- a/core/src/net/sf/openrocket/file/wavefrontobj/export/components/MassObjectExporter.java
+++ b/core/src/net/sf/openrocket/file/wavefrontobj/export/components/MassObjectExporter.java
@@ -5,6 +5,7 @@ import net.sf.openrocket.file.wavefrontobj.CoordTransform;
import net.sf.openrocket.file.wavefrontobj.DefaultObj;
import net.sf.openrocket.file.wavefrontobj.DefaultObjFace;
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
+import net.sf.openrocket.logging.WarningSet;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.InstanceContext;
import net.sf.openrocket.rocketcomponent.MassObject;
@@ -13,8 +14,8 @@ import net.sf.openrocket.util.RocketComponentUtils;
public class MassObjectExporter extends RocketComponentExporter {
public MassObjectExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
- MassObject component, String groupName, ObjUtils.LevelOfDetail LOD) {
- super(obj, config, transformer, component, groupName, LOD);
+ MassObject component, String groupName, ObjUtils.LevelOfDetail LOD, WarningSet warnings) {
+ super(obj, config, transformer, component, groupName, LOD, warnings);
}
@Override
diff --git a/core/src/net/sf/openrocket/file/wavefrontobj/export/components/MotorExporter.java b/core/src/net/sf/openrocket/file/wavefrontobj/export/components/MotorExporter.java
index cbf07bff9..d04dbae94 100644
--- a/core/src/net/sf/openrocket/file/wavefrontobj/export/components/MotorExporter.java
+++ b/core/src/net/sf/openrocket/file/wavefrontobj/export/components/MotorExporter.java
@@ -6,6 +6,7 @@ import net.sf.openrocket.file.wavefrontobj.DefaultObjFace;
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
import net.sf.openrocket.file.wavefrontobj.export.shapes.CylinderExporter;
import net.sf.openrocket.file.wavefrontobj.export.shapes.DiskExporter;
+import net.sf.openrocket.logging.WarningSet;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.MotorConfiguration;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
@@ -24,6 +25,7 @@ public class MotorExporter {
protected final String groupName;
protected final ObjUtils.LevelOfDetail LOD;
protected final CoordTransform transformer;
+ protected final WarningSet warnings;
/**
* Wavefront OBJ exporter for a rocket component.
@@ -36,7 +38,7 @@ public class MotorExporter {
* @param LOD Level of detail to use for the export (e.g. '80')
*/
public MotorExporter(DefaultObj obj, FlightConfiguration config, CoordTransform transformer, RocketComponent mount,
- String groupName, ObjUtils.LevelOfDetail LOD) {
+ String groupName, ObjUtils.LevelOfDetail LOD, WarningSet warnings) {
if (!(mount instanceof MotorMount)) {
throw new IllegalArgumentException("Motor exporter can only be used for motor mounts");
}
@@ -46,6 +48,7 @@ public class MotorExporter {
this.mount = mount;
this.groupName = groupName;
this.LOD = LOD;
+ this.warnings = warnings;
}
public void addToObj() {
diff --git a/core/src/net/sf/openrocket/file/wavefrontobj/export/components/RailButtonExporter.java b/core/src/net/sf/openrocket/file/wavefrontobj/export/components/RailButtonExporter.java
index 36a16a70b..475b8563c 100644
--- a/core/src/net/sf/openrocket/file/wavefrontobj/export/components/RailButtonExporter.java
+++ b/core/src/net/sf/openrocket/file/wavefrontobj/export/components/RailButtonExporter.java
@@ -8,6 +8,7 @@ import net.sf.openrocket.file.wavefrontobj.DefaultObjFace;
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
import net.sf.openrocket.file.wavefrontobj.export.shapes.CylinderExporter;
import net.sf.openrocket.file.wavefrontobj.export.shapes.DiskExporter;
+import net.sf.openrocket.logging.WarningSet;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.InstanceContext;
import net.sf.openrocket.rocketcomponent.RailButton;
@@ -26,8 +27,8 @@ public class RailButtonExporter extends RocketComponentExporter {
* @param LOD Level of detail to use for the export (e.g. '80')
*/
public RailButtonExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
- RailButton component, String groupName, ObjUtils.LevelOfDetail LOD) {
- super(obj, config, transformer, component, groupName, LOD);
+ RailButton component, String groupName, ObjUtils.LevelOfDetail LOD, WarningSet warnings) {
+ super(obj, config, transformer, component, groupName, LOD, warnings);
}
@Override
diff --git a/core/src/net/sf/openrocket/file/wavefrontobj/export/components/RingComponentExporter.java b/core/src/net/sf/openrocket/file/wavefrontobj/export/components/RingComponentExporter.java
index 798a82169..08c3f7751 100644
--- a/core/src/net/sf/openrocket/file/wavefrontobj/export/components/RingComponentExporter.java
+++ b/core/src/net/sf/openrocket/file/wavefrontobj/export/components/RingComponentExporter.java
@@ -5,6 +5,8 @@ import net.sf.openrocket.file.wavefrontobj.CoordTransform;
import net.sf.openrocket.file.wavefrontobj.DefaultObj;
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
import net.sf.openrocket.file.wavefrontobj.export.shapes.TubeExporter;
+import net.sf.openrocket.logging.Warning;
+import net.sf.openrocket.logging.WarningSet;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.InstanceContext;
import net.sf.openrocket.rocketcomponent.RingComponent;
@@ -12,8 +14,8 @@ import net.sf.openrocket.util.Coordinate;
public class RingComponentExporter extends RocketComponentExporter {
public RingComponentExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
- RingComponent component, String groupName, ObjUtils.LevelOfDetail LOD) {
- super(obj, config, transformer, component, groupName, LOD);
+ RingComponent component, String groupName, ObjUtils.LevelOfDetail LOD, WarningSet warnings) {
+ super(obj, config, transformer, component, groupName, LOD, warnings);
}
@Override
@@ -24,6 +26,10 @@ public class RingComponentExporter extends RocketComponentExporter {
protected final String groupName;
protected final ObjUtils.LevelOfDetail LOD;
protected final CoordTransform transformer;
+ protected final WarningSet warnings;
/**
* Wavefront OBJ exporter for a rocket component.
@@ -31,13 +33,15 @@ public abstract class RocketComponentExporter {
* @param LOD Level of detail to use for the export (e.g. '80')
*/
public RocketComponentExporter(@NotNull DefaultObj obj, @NotNull FlightConfiguration config, @NotNull CoordTransform transformer,
- T component, String groupName, ObjUtils.LevelOfDetail LOD) {
+ T component, String groupName, ObjUtils.LevelOfDetail LOD,
+ WarningSet warnings) {
this.obj = obj;
this.config = config;
this.component = component;
this.groupName = groupName;
this.LOD = LOD;
this.transformer = transformer;
+ this.warnings = warnings;
}
public abstract void addToObj();
diff --git a/core/src/net/sf/openrocket/file/wavefrontobj/export/components/TransitionExporter.java b/core/src/net/sf/openrocket/file/wavefrontobj/export/components/TransitionExporter.java
index 2157a17d1..537afaa33 100644
--- a/core/src/net/sf/openrocket/file/wavefrontobj/export/components/TransitionExporter.java
+++ b/core/src/net/sf/openrocket/file/wavefrontobj/export/components/TransitionExporter.java
@@ -9,9 +9,13 @@ import net.sf.openrocket.file.wavefrontobj.ObjUtils;
import net.sf.openrocket.file.wavefrontobj.export.shapes.CylinderExporter;
import net.sf.openrocket.file.wavefrontobj.export.shapes.DiskExporter;
import net.sf.openrocket.file.wavefrontobj.export.shapes.TubeExporter;
+import net.sf.openrocket.l10n.Translator;
+import net.sf.openrocket.logging.Warning;
+import net.sf.openrocket.logging.WarningSet;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.InstanceContext;
import net.sf.openrocket.rocketcomponent.Transition;
+import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.Coordinate;
import java.util.ArrayList;
@@ -20,10 +24,11 @@ import java.util.List;
public class TransitionExporter extends RocketComponentExporter {
private static final double RADIUS_EPSILON = 1e-4;
private final int nrOfSides;
+ private static final Translator trans = Application.getTranslator();
public TransitionExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
- Transition component, String groupName, ObjUtils.LevelOfDetail LOD) {
- super(obj, config, transformer, component, groupName, LOD);
+ Transition component, String groupName, ObjUtils.LevelOfDetail LOD, WarningSet warnings) {
+ super(obj, config, transformer, component, groupName, LOD, warnings);
this.nrOfSides = LOD.getNrOfSides(Math.max(component.getForeRadius(), component.getAftRadius()));
}
@@ -31,6 +36,10 @@ public class TransitionExporter extends RocketComponentExporter {
public void addToObj() {
obj.setActiveGroupNames(groupName);
+ if (Double.compare(component.getThickness(), 0) == 0) {
+ warnings.add(Warning.OBJ_ZERO_THICKNESS, component.getName());
+ }
+
// Generate the mesh
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
generateMesh(context);
@@ -40,15 +49,30 @@ public class TransitionExporter extends RocketComponentExporter {
private void generateMesh(InstanceContext context) {
int startIdx = obj.getNumVertices();
- final boolean hasForeShoulder = Double.compare(component.getForeShoulderRadius(), 0) > 0
- && Double.compare(component.getForeShoulderLength(), 0) > 0
+ final boolean hasForeShoulder = Double.compare(component.getForeShoulderLength(), 0) > 0
&& component.getForeRadius() > 0;
- final boolean hasAftShoulder = Double.compare(component.getAftShoulderRadius(), 0) > 0
- && Double.compare(component.getAftShoulderLength(), 0) > 0
+ final boolean hasAftShoulder = Double.compare(component.getAftShoulderLength(), 0) > 0
&& component.getAftRadius() > 0;
+
+ final boolean foreSmallerThickn = Double.compare(component.getForeRadius(), component.getThickness()) <= 0;
+ final boolean aftSmallerThickn = Double.compare(component.getAftRadius(), component.getThickness()) <= 0;
+ final boolean foreShoulderCapped = hasForeShoulder && component.isForeShoulderCapped();
+ final boolean aftShoulderCapped = hasAftShoulder && component.isAftShoulderCapped();
final boolean isFilled = component.isFilled() ||
- (Double.compare(component.getForeRadius(), component.getThickness()) <= 0 &&
- Double.compare(component.getAftRadius(), component.getThickness()) <= 0);
+ (foreSmallerThickn && aftSmallerThickn) ||
+ (foreSmallerThickn && aftShoulderCapped) ||
+ (aftSmallerThickn && foreShoulderCapped) ||
+ (foreShoulderCapped && aftShoulderCapped);
+
+ // Warn for zero-thickness shoulders
+ if (hasForeShoulder && Double.compare(component.getForeShoulderThickness(), 0) == 0) {
+ warnings.add(Warning.OBJ_ZERO_THICKNESS, component.getName() +
+ " (" + trans.get("RocketCompCfg.border.Foreshoulder") + ")");
+ }
+ if (hasAftShoulder && Double.compare(component.getAftShoulderThickness(), 0) == 0) {
+ warnings.add(Warning.OBJ_ZERO_THICKNESS, component.getName() +
+ " (" + trans.get("RocketCompCfg.border.Aftshoulder") + ")");
+ }
final List outsideForeRingVertices = new ArrayList<>();
final List outsideAftRingVertices = new ArrayList<>();
@@ -127,8 +151,11 @@ public class TransitionExporter extends RocketComponentExporter {
final double actualLength = estimateActualLength(offsetRadius, dxBase); // Actual length of the transition (due to reduced step size near the fore/aft end)
// Get the location where the fore/aft shoulder would end (due to its thickness)
- final double xForeShoulder = component.getForeShoulderThickness();
- final double xAftShoulder = component.getLength() - component.getAftShoulderThickness();
+ final double shoulderMargin = 0.001; // Margin to prevent the shoulder from being too close to the transition end
+ final double foreShoulderMargin = hasForeShoulder ? shoulderMargin : 0;
+ final double aftShoulderMargin = hasAftShoulder ? shoulderMargin : 0;
+ final double xForeShoulder = component.getForeShoulderThickness() + foreShoulderMargin;
+ final double xAftShoulder = component.getLength() - component.getAftShoulderThickness() - aftShoulderMargin;
// Generate vertices and normals
float x = 0; // Distance from the fore end
diff --git a/core/src/net/sf/openrocket/file/wavefrontobj/export/components/TubeFinSetExporter.java b/core/src/net/sf/openrocket/file/wavefrontobj/export/components/TubeFinSetExporter.java
index 30175d809..68eb6a6ba 100644
--- a/core/src/net/sf/openrocket/file/wavefrontobj/export/components/TubeFinSetExporter.java
+++ b/core/src/net/sf/openrocket/file/wavefrontobj/export/components/TubeFinSetExporter.java
@@ -5,6 +5,8 @@ import net.sf.openrocket.file.wavefrontobj.CoordTransform;
import net.sf.openrocket.file.wavefrontobj.DefaultObj;
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
import net.sf.openrocket.file.wavefrontobj.export.shapes.TubeExporter;
+import net.sf.openrocket.logging.Warning;
+import net.sf.openrocket.logging.WarningSet;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.InstanceContext;
import net.sf.openrocket.rocketcomponent.TubeFinSet;
@@ -12,8 +14,8 @@ import net.sf.openrocket.util.Coordinate;
public class TubeFinSetExporter extends RocketComponentExporter {
public TubeFinSetExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
- TubeFinSet component, String groupName, ObjUtils.LevelOfDetail LOD) {
- super(obj, config, transformer, component, groupName, LOD);
+ TubeFinSet component, String groupName, ObjUtils.LevelOfDetail LOD, WarningSet warnings) {
+ super(obj, config, transformer, component, groupName, LOD, warnings);
}
@Override
@@ -24,6 +26,10 @@ public class TubeFinSetExporter extends RocketComponentExporter {
final float innerRadius = (float) component.getInnerRadius();
final float length = (float) component.getLength();
+ if (Double.compare(component.getThickness(), 0) == 0) {
+ warnings.add(Warning.OBJ_ZERO_THICKNESS, component.getName());
+ }
+
// Generate the fin meshes
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
generateMesh(outerRadius, innerRadius, length, context);
diff --git a/core/src/net/sf/openrocket/logging/Warning.java b/core/src/net/sf/openrocket/logging/Warning.java
index 23c4bcb90..c3b9db1fb 100644
--- a/core/src/net/sf/openrocket/logging/Warning.java
+++ b/core/src/net/sf/openrocket/logging/Warning.java
@@ -386,6 +386,8 @@ public abstract class Warning extends Message {
public static final Warning TUBE_SEPARATION = new Other(trans.get("Warning.TUBE_SEPARATION"));
public static final Warning TUBE_OVERLAP = new Other(trans.get("Warning.TUBE_OVERLAP"));
+ public static final Warning OBJ_ZERO_THICKNESS = new Other(trans.get("Warning.OBJ_ZERO_THICKNESS"));
+
/** A Warning
that stage separation occurred at other than the last stage */
public static final Warning SEPARATION_ORDER = new Other(trans.get("Warning.SEPARATION_ORDER"));
diff --git a/core/src/net/sf/openrocket/rocketcomponent/Transition.java b/core/src/net/sf/openrocket/rocketcomponent/Transition.java
index bba87bd3a..bc1679f09 100644
--- a/core/src/net/sf/openrocket/rocketcomponent/Transition.java
+++ b/core/src/net/sf/openrocket/rocketcomponent/Transition.java
@@ -119,7 +119,7 @@ public class Transition extends SymmetricComponent implements InsideColorCompone
clearPreset();
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
- setForeShoulderRadius(getForeShoulderRadius());
+ setForeShoulderRadius(getForeShoulderRadius(), doClamping);
}
public void setForeRadius(double radius) {
@@ -396,21 +396,31 @@ public class Transition extends SymmetricComponent implements InsideColorCompone
return foreShoulderRadius;
}
- public void setForeShoulderRadius(double foreShoulderRadius) {
+ public void setForeShoulderRadius(double foreShoulderRadius, boolean doClamping) {
for (RocketComponent listener : configListeners) {
if (listener instanceof Transition) {
- ((Transition) listener).setForeShoulderRadius(foreShoulderRadius);
+ ((Transition) listener).setForeShoulderRadius(foreShoulderRadius, doClamping);
}
}
foreShoulderRadius = Math.min(foreShoulderRadius, getForeRadius());
if (MathUtil.equals(this.foreShoulderRadius, foreShoulderRadius))
return;
+
this.foreShoulderRadius = foreShoulderRadius;
+
+ if (doClamping) {
+ this.foreShoulderThickness = Math.min(this.foreShoulderRadius, this.foreShoulderThickness);
+ }
+
clearPreset();
fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
}
+ public void setForeShoulderRadius(double foreShoulderRadius) {
+ setForeShoulderRadius(foreShoulderRadius, true);
+ }
+
public double getForeShoulderThickness() {
return foreShoulderThickness;
}
@@ -469,10 +479,10 @@ public class Transition extends SymmetricComponent implements InsideColorCompone
return aftShoulderRadius;
}
- public void setAftShoulderRadius(double aftShoulderRadius) {
+ public void setAftShoulderRadius(double aftShoulderRadius, boolean doClamping) {
for (RocketComponent listener : configListeners) {
if (listener instanceof Transition) {
- ((Transition) listener).setAftShoulderRadius(aftShoulderRadius);
+ ((Transition) listener).setAftShoulderRadius(aftShoulderRadius, doClamping);
}
}
@@ -480,11 +490,21 @@ public class Transition extends SymmetricComponent implements InsideColorCompone
if (MathUtil.equals(this.aftShoulderRadius, aftShoulderRadius))
return;
+
this.aftShoulderRadius = aftShoulderRadius;
+
+ if (doClamping) {
+ this.aftShoulderThickness = Math.min(this.aftShoulderRadius, this.aftShoulderThickness);
+ }
+
clearPreset();
fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
}
+ public void setAftShoulderRadius(double aftShoulderRadius) {
+ setAftShoulderRadius(aftShoulderRadius, true);
+ }
+
public double getAftShoulderThickness() {
return aftShoulderThickness;
}
diff --git a/core/test/net/sf/openrocket/file/wavefrontobj/export/OBJExporterFactoryTest.java b/core/test/net/sf/openrocket/file/wavefrontobj/export/OBJExporterFactoryTest.java
index f8dca2bb2..af5f5dd5c 100644
--- a/core/test/net/sf/openrocket/file/wavefrontobj/export/OBJExporterFactoryTest.java
+++ b/core/test/net/sf/openrocket/file/wavefrontobj/export/OBJExporterFactoryTest.java
@@ -8,16 +8,12 @@ import com.google.inject.util.Modules;
import net.sf.openrocket.ServicesForTesting;
import net.sf.openrocket.database.ComponentPresetDao;
import net.sf.openrocket.database.motor.MotorDatabase;
-import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.document.OpenRocketDocumentFactory;
-import net.sf.openrocket.file.GeneralRocketLoader;
-import net.sf.openrocket.file.RocketLoadException;
import net.sf.openrocket.file.openrocket.OpenRocketSaverTest;
-import net.sf.openrocket.file.wavefrontobj.CoordTransform;
-import net.sf.openrocket.file.wavefrontobj.DefaultCoordTransform;
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
import net.sf.openrocket.l10n.DebugTranslator;
import net.sf.openrocket.l10n.Translator;
+import net.sf.openrocket.logging.WarningSet;
import net.sf.openrocket.plugin.PluginModule;
import net.sf.openrocket.rocketcomponent.AxialStage;
import net.sf.openrocket.rocketcomponent.BodyTube;
@@ -43,6 +39,7 @@ import java.nio.file.Path;
import java.util.List;
import static org.junit.Assert.fail;
+import static org.junit.Assert.assertEquals;
public class OBJExporterFactoryTest {
private static final File TMP_DIR = new File("./tmp/");
@@ -165,8 +162,11 @@ public class OBJExporterFactoryTest {
options.setScaling(30);
options.setExportChildren(true);
options.setRemoveOffset(true);
- OBJExporterFactory exporterFactory = new OBJExporterFactory(components, rocket.getSelectedConfiguration(), tempFile.toFile(), options);
+ WarningSet warnings = new WarningSet();
+ OBJExporterFactory exporterFactory = new OBJExporterFactory(components, rocket.getSelectedConfiguration(), tempFile.toFile(), options, warnings);
exporterFactory.doExport();
+ //// Just hope for no exceptions :)
+ assertEquals(warnings.size(), 0);
// Test with other parameters
@@ -180,8 +180,18 @@ public class OBJExporterFactoryTest {
options.setScaling(1000);
options.setLOD(ObjUtils.LevelOfDetail.LOW_QUALITY);
- exporterFactory = new OBJExporterFactory(components, rocket.getSelectedConfiguration(), tempFile.toFile(), options);
+ exporterFactory = new OBJExporterFactory(components, rocket.getSelectedConfiguration(), tempFile.toFile(), options, warnings);
exporterFactory.doExport();
+ //// Just hope for no exceptions :)
+ assertEquals(warnings.size(), 0);
+
+ // Test zero-thickness nose cone
+ noseCone.setThickness(0);
+
+ exporterFactory = new OBJExporterFactory(components, rocket.getSelectedConfiguration(), tempFile.toFile(), options, warnings);
+ exporterFactory.doExport();
+ //// Just hope for no exceptions :)
+ assertEquals(warnings.size(), 1);
// Clean up
Files.delete(tempFile);
diff --git a/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java b/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java
index 6a8dad3ef..e5a985341 100644
--- a/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java
+++ b/swing/src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java
@@ -836,7 +836,7 @@ public class RocketComponentConfig extends JPanel {
sub.setBorder(null);
} else {
//// Aft shoulder
- sub.setBorder(BorderFactory.createTitledBorder(trans.get("RocketCompCfg.title.Aftshoulder")));
+ sub.setBorder(BorderFactory.createTitledBorder(trans.get("RocketCompCfg.border.Aftshoulder")));
}
diff --git a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java
index 08870e1ab..4a10abb00 100644
--- a/swing/src/net/sf/openrocket/gui/main/BasicFrame.java
+++ b/swing/src/net/sf/openrocket/gui/main/BasicFrame.java
@@ -1530,8 +1530,9 @@ public class BasicFrame extends JFrame {
// // Some design features may not have been exported correctly.
trans.get("BasicFrame.WarningDialog.saving.txt2")
},
- // // Warnings while opening file
- trans.get("BasicFrame.WarningDialog.saving.title"), warnings);
+ //// Warnings while saving file
+ trans.get("BasicFrame.WarningDialog.saving.title"),
+ warnings);
} else if (!errors.isEmpty()) {
ErrorWarningDialog.showErrorsAndWarnings(BasicFrame.this,
new Object[]{
@@ -1677,10 +1678,21 @@ public class BasicFrame extends JFrame {
* @return true if the file was written
*/
private boolean saveWavefrontOBJFile(File file, OBJExportOptions options) {
+ WarningSet warnings = new WarningSet();
OBJExporterFactory exporter = new OBJExporterFactory(getSelectedComponents(), rocket.getSelectedConfiguration(),
- file, options);
+ file, options, warnings);
exporter.doExport();
+ // Show warning dialog
+ if (!warnings.isEmpty()) {
+ WarningDialog.showWarnings(this,
+ //// The following problems were encountered while saving
+ trans.get("BasicFrame.WarningDialog.saving.txt1") + " '" + file.getName() + "'.",
+ //// Warnings while saving file
+ trans.get("BasicFrame.WarningDialog.saving.title"),
+ warnings);
+ }
+
return true;
}