Merge pull request #2317 from SiboVG/issue-2316
[#2316] Add warning for zero-thickness component OBJ export @SiboVG
This commit is contained in:
commit
9741a9e868
@ -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 = <html>Please <b>correct the errors</b>.</html>
|
||||
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
|
||||
|
@ -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 = من الخارج
|
||||
|
@ -651,7 +651,7 @@ RocketCompCfg.lbl.Length = D
|
||||
RocketCompCfg.lbl.Thickness = Tlou\u0161tka:
|
||||
RocketCompCfg.checkbox.Endcapped = Záslepka
|
||||
RocketCompCfg.ttip.Endcapped = Zdali je konec ramene zaslepen.
|
||||
RocketCompCfg.title.Aftshoulder = Dr\u017Eák zádi
|
||||
RocketCompCfg.border.Aftshoulder = Dr\u017Eák zádi
|
||||
RocketCompCfg.border.Foreshoulder = Dr\u017Eák prídi
|
||||
!RocketCompCfg.lbl.Length = Délka:
|
||||
|
||||
|
@ -708,7 +708,7 @@ RocketCompCfg.lbl.Length = L
|
||||
RocketCompCfg.lbl.Thickness = Wandstärke:
|
||||
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:
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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<RocketComponent> 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 <T extends RocketComponent> void handleComponent(DefaultObj obj, FlightConfiguration config, CoordTransform transformer,
|
||||
T component, String groupName, List<DefaultMtl> materials,
|
||||
ObjUtils.LevelOfDetail LOD, OBJExportOptions options) {
|
||||
ObjUtils.LevelOfDetail LOD, OBJExportOptions options,
|
||||
WarningSet warnings) {
|
||||
ExporterFactory<T> factory = null;
|
||||
Class<?> currentClass = component.getClass();
|
||||
|
||||
@ -254,7 +258,7 @@ public class OBJExporterFactory {
|
||||
}
|
||||
|
||||
// Export component
|
||||
final RocketComponentExporter<T> exporter = factory.create(obj, config, transformer, component, groupName, LOD);
|
||||
final RocketComponentExporter<T> 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<T extends RocketComponent> {
|
||||
RocketComponentExporter<T> create(DefaultObj obj, FlightConfiguration config, CoordTransform transformer,
|
||||
T component, String groupName, ObjUtils.LevelOfDetail LOD);
|
||||
T component, String groupName, ObjUtils.LevelOfDetail LOD, WarningSet warnings);
|
||||
}
|
||||
}
|
||||
|
@ -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<BodyTube> {
|
||||
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<BodyTube> {
|
||||
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);
|
||||
|
@ -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<FinSet> {
|
||||
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<FinSet> {
|
||||
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);
|
||||
|
@ -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<LaunchLug> {
|
||||
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<LaunchLug> {
|
||||
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);
|
||||
|
@ -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<MassObject> {
|
||||
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
|
||||
|
@ -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() {
|
||||
|
@ -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<RailButton> {
|
||||
* @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
|
||||
|
@ -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<RingComponent> {
|
||||
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<RingComponent
|
||||
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);
|
||||
|
@ -4,6 +4,7 @@ import com.sun.istack.NotNull;
|
||||
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.logging.WarningSet;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
|
||||
@ -20,6 +21,7 @@ public abstract class RocketComponentExporter<T extends RocketComponent> {
|
||||
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<T extends RocketComponent> {
|
||||
* @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();
|
||||
|
@ -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<Transition> {
|
||||
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<Transition> {
|
||||
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<Transition> {
|
||||
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<Integer> outsideForeRingVertices = new ArrayList<>();
|
||||
final List<Integer> outsideAftRingVertices = new ArrayList<>();
|
||||
@ -127,8 +151,11 @@ public class TransitionExporter extends RocketComponentExporter<Transition> {
|
||||
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
|
||||
|
@ -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<TubeFinSet> {
|
||||
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<TubeFinSet> {
|
||||
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);
|
||||
|
@ -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 <code>Warning</code> that stage separation occurred at other than the last stage */
|
||||
public static final Warning SEPARATION_ORDER = new Other(trans.get("Warning.SEPARATION_ORDER"));
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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")));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user