[#2316] Add warning for zero-thickness component OBJ export
This commit is contained in:
parent
0092269b73
commit
5c68fda00e
@ -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.txt1 = The following problems were encountered while saving
|
||||||
BasicFrame.WarningDialog.saving.txt2 = Some design features may not have exported correctly.
|
BasicFrame.WarningDialog.saving.txt2 = Some design features may not have exported correctly.
|
||||||
BasicFrame.WarningDialog.title = Warnings while opening file
|
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.txt1 = <html>Please <b>correct the errors</b>.</html>
|
||||||
BasicFrame.ErrorWarningDialog.saving.title = Errors/Warnings while saving file
|
BasicFrame.ErrorWarningDialog.saving.title = Errors/Warnings while saving file
|
||||||
BasicFrame.lbl.SaveRocketInfo = Save Design Info
|
BasicFrame.lbl.SaveRocketInfo = Save Design Info
|
||||||
@ -2097,6 +2097,7 @@ Warning.TUBE_OVERLAP = Overlapping tube fins may not simulate accurately.
|
|||||||
Warning.EMPTY_BRANCH = Simulation branch contains no data
|
Warning.EMPTY_BRANCH = Simulation branch contains no data
|
||||||
Warning.SEPARATION_ORDER = Stages separated in an unreasonable order
|
Warning.SEPARATION_ORDER = Stages separated in an unreasonable order
|
||||||
Warning.EARLY_SEPARATION = Stages separated before clearing launch rod/rail
|
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
|
! Scale dialog
|
||||||
ScaleDialog.lbl.scaleRocket = Entire rocket
|
ScaleDialog.lbl.scaleRocket = Entire rocket
|
||||||
|
@ -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.RingComponentExporter;
|
||||||
import net.sf.openrocket.file.wavefrontobj.export.components.TransitionExporter;
|
import net.sf.openrocket.file.wavefrontobj.export.components.TransitionExporter;
|
||||||
import net.sf.openrocket.file.wavefrontobj.export.components.TubeFinSetExporter;
|
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.Motor;
|
||||||
import net.sf.openrocket.motor.MotorConfiguration;
|
import net.sf.openrocket.motor.MotorConfiguration;
|
||||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||||
@ -69,6 +70,7 @@ public class OBJExporterFactory {
|
|||||||
private final FlightConfiguration configuration;
|
private final FlightConfiguration configuration;
|
||||||
private final OBJExportOptions options;
|
private final OBJExportOptions options;
|
||||||
private final File file;
|
private final File file;
|
||||||
|
private final WarningSet warnings;
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(OBJExporterFactory.class);
|
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
|
* @param file The file to export the OBJ to
|
||||||
*/
|
*/
|
||||||
public OBJExporterFactory(List<RocketComponent> components, FlightConfiguration configuration, File file,
|
public OBJExporterFactory(List<RocketComponent> components, FlightConfiguration configuration, File file,
|
||||||
OBJExportOptions options) {
|
OBJExportOptions options, WarningSet warnings) {
|
||||||
this.components = components;
|
this.components = components;
|
||||||
this.configuration = configuration;
|
this.configuration = configuration;
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
this.warnings = warnings;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -152,7 +155,7 @@ public class OBJExporterFactory {
|
|||||||
// Component exporting
|
// Component exporting
|
||||||
String groupName = idx + "_" + component.getName();
|
String groupName = idx + "_" + component.getName();
|
||||||
handleComponent(obj, this.configuration, this.options.getTransformer(), component, groupName,
|
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 separate export, add this object to the map of objects to export
|
||||||
if (exportAsSeparateFiles) {
|
if (exportAsSeparateFiles) {
|
||||||
@ -225,7 +228,8 @@ public class OBJExporterFactory {
|
|||||||
@SuppressWarnings("unchecked") // This is safe because of the structure we set up.
|
@SuppressWarnings("unchecked") // This is safe because of the structure we set up.
|
||||||
private <T extends RocketComponent> void handleComponent(DefaultObj obj, FlightConfiguration config, CoordTransform transformer,
|
private <T extends RocketComponent> void handleComponent(DefaultObj obj, FlightConfiguration config, CoordTransform transformer,
|
||||||
T component, String groupName, List<DefaultMtl> materials,
|
T component, String groupName, List<DefaultMtl> materials,
|
||||||
ObjUtils.LevelOfDetail LOD, OBJExportOptions options) {
|
ObjUtils.LevelOfDetail LOD, OBJExportOptions options,
|
||||||
|
WarningSet warnings) {
|
||||||
ExporterFactory<T> factory = null;
|
ExporterFactory<T> factory = null;
|
||||||
Class<?> currentClass = component.getClass();
|
Class<?> currentClass = component.getClass();
|
||||||
|
|
||||||
@ -254,7 +258,7 @@ public class OBJExporterFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Export component
|
// 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();
|
exporter.addToObj();
|
||||||
|
|
||||||
// Export motor
|
// Export motor
|
||||||
@ -272,7 +276,7 @@ public class OBJExporterFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Export the motor geometry
|
// 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();
|
motorExporter.addToObj();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -300,6 +304,6 @@ public class OBJExporterFactory {
|
|||||||
|
|
||||||
interface ExporterFactory<T extends RocketComponent> {
|
interface ExporterFactory<T extends RocketComponent> {
|
||||||
RocketComponentExporter<T> create(DefaultObj obj, FlightConfiguration config, CoordTransform transformer,
|
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.DefaultObj;
|
||||||
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
|
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
|
||||||
import net.sf.openrocket.file.wavefrontobj.export.shapes.TubeExporter;
|
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.BodyTube;
|
||||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||||
import net.sf.openrocket.rocketcomponent.InstanceContext;
|
import net.sf.openrocket.rocketcomponent.InstanceContext;
|
||||||
@ -11,8 +13,8 @@ import net.sf.openrocket.util.Coordinate;
|
|||||||
|
|
||||||
public class BodyTubeExporter extends RocketComponentExporter<BodyTube> {
|
public class BodyTubeExporter extends RocketComponentExporter<BodyTube> {
|
||||||
public BodyTubeExporter(DefaultObj obj, FlightConfiguration config, CoordTransform transformer, BodyTube component,
|
public BodyTubeExporter(DefaultObj obj, FlightConfiguration config, CoordTransform transformer, BodyTube component,
|
||||||
String groupName, ObjUtils.LevelOfDetail LOD) {
|
String groupName, ObjUtils.LevelOfDetail LOD, WarningSet warnings) {
|
||||||
super(obj, config, transformer, component, groupName, LOD);
|
super(obj, config, transformer, component, groupName, LOD, warnings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -24,6 +26,10 @@ public class BodyTubeExporter extends RocketComponentExporter<BodyTube> {
|
|||||||
final float length = (float) component.getLength();
|
final float length = (float) component.getLength();
|
||||||
final boolean isFilled = component.isFilled();
|
final boolean isFilled = component.isFilled();
|
||||||
|
|
||||||
|
if (Double.compare(component.getThickness(), 0) == 0) {
|
||||||
|
warnings.add(Warning.OBJ_ZERO_THICKNESS, component.getName());
|
||||||
|
}
|
||||||
|
|
||||||
// Generate the mesh
|
// Generate the mesh
|
||||||
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
|
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
|
||||||
generateMesh(outerRadius, innerRadius, length, isFilled, context);
|
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.DefaultObj;
|
||||||
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
|
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
|
||||||
import net.sf.openrocket.file.wavefrontobj.export.shapes.PolygonExporter;
|
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.FinSet;
|
||||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||||
import net.sf.openrocket.rocketcomponent.InstanceContext;
|
import net.sf.openrocket.rocketcomponent.InstanceContext;
|
||||||
@ -16,8 +18,8 @@ import java.util.List;
|
|||||||
|
|
||||||
public class FinSetExporter extends RocketComponentExporter<FinSet> {
|
public class FinSetExporter extends RocketComponentExporter<FinSet> {
|
||||||
public FinSetExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
|
public FinSetExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
|
||||||
FinSet component, String groupName, ObjUtils.LevelOfDetail LOD) {
|
FinSet component, String groupName, ObjUtils.LevelOfDetail LOD, WarningSet warnings) {
|
||||||
super(obj, config, transformer, component, groupName, LOD);
|
super(obj, config, transformer, component, groupName, LOD, warnings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -35,6 +37,10 @@ public class FinSetExporter extends RocketComponentExporter<FinSet> {
|
|||||||
final float thickness = (float) component.getThickness();
|
final float thickness = (float) component.getThickness();
|
||||||
boolean hasTabs = component.getTabLength() > 0 && component.getTabHeight() > 0;
|
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
|
// Generate the fin meshes
|
||||||
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
|
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
|
||||||
generateMesh(floatPoints, floatTabPoints, thickness, hasTabs, context);
|
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.DefaultObj;
|
||||||
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
|
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
|
||||||
import net.sf.openrocket.file.wavefrontobj.export.shapes.TubeExporter;
|
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.FlightConfiguration;
|
||||||
import net.sf.openrocket.rocketcomponent.InstanceContext;
|
import net.sf.openrocket.rocketcomponent.InstanceContext;
|
||||||
import net.sf.openrocket.rocketcomponent.LaunchLug;
|
import net.sf.openrocket.rocketcomponent.LaunchLug;
|
||||||
@ -12,8 +14,8 @@ import net.sf.openrocket.util.Coordinate;
|
|||||||
|
|
||||||
public class LaunchLugExporter extends RocketComponentExporter<LaunchLug> {
|
public class LaunchLugExporter extends RocketComponentExporter<LaunchLug> {
|
||||||
public LaunchLugExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
|
public LaunchLugExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
|
||||||
LaunchLug component, String groupName, ObjUtils.LevelOfDetail LOD) {
|
LaunchLug component, String groupName, ObjUtils.LevelOfDetail LOD, WarningSet warnings) {
|
||||||
super(obj, config, transformer, component, groupName, LOD);
|
super(obj, config, transformer, component, groupName, LOD, warnings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -24,6 +26,10 @@ public class LaunchLugExporter extends RocketComponentExporter<LaunchLug> {
|
|||||||
final float innerRadius = (float) component.getInnerRadius();
|
final float innerRadius = (float) component.getInnerRadius();
|
||||||
final float length = (float) component.getLength();
|
final float length = (float) component.getLength();
|
||||||
|
|
||||||
|
if (Double.compare(component.getThickness(), 0) == 0) {
|
||||||
|
warnings.add(Warning.OBJ_ZERO_THICKNESS, component.getName());
|
||||||
|
}
|
||||||
|
|
||||||
// Generate the mesh
|
// Generate the mesh
|
||||||
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
|
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
|
||||||
generateMesh(outerRadius, innerRadius, length, context);
|
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.DefaultObj;
|
||||||
import net.sf.openrocket.file.wavefrontobj.DefaultObjFace;
|
import net.sf.openrocket.file.wavefrontobj.DefaultObjFace;
|
||||||
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
|
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
|
||||||
|
import net.sf.openrocket.logging.WarningSet;
|
||||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||||
import net.sf.openrocket.rocketcomponent.InstanceContext;
|
import net.sf.openrocket.rocketcomponent.InstanceContext;
|
||||||
import net.sf.openrocket.rocketcomponent.MassObject;
|
import net.sf.openrocket.rocketcomponent.MassObject;
|
||||||
@ -13,8 +14,8 @@ import net.sf.openrocket.util.RocketComponentUtils;
|
|||||||
|
|
||||||
public class MassObjectExporter extends RocketComponentExporter<MassObject> {
|
public class MassObjectExporter extends RocketComponentExporter<MassObject> {
|
||||||
public MassObjectExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
|
public MassObjectExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
|
||||||
MassObject component, String groupName, ObjUtils.LevelOfDetail LOD) {
|
MassObject component, String groupName, ObjUtils.LevelOfDetail LOD, WarningSet warnings) {
|
||||||
super(obj, config, transformer, component, groupName, LOD);
|
super(obj, config, transformer, component, groupName, LOD, warnings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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.ObjUtils;
|
||||||
import net.sf.openrocket.file.wavefrontobj.export.shapes.CylinderExporter;
|
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.DiskExporter;
|
||||||
|
import net.sf.openrocket.logging.WarningSet;
|
||||||
import net.sf.openrocket.motor.Motor;
|
import net.sf.openrocket.motor.Motor;
|
||||||
import net.sf.openrocket.motor.MotorConfiguration;
|
import net.sf.openrocket.motor.MotorConfiguration;
|
||||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||||
@ -24,6 +25,7 @@ public class MotorExporter {
|
|||||||
protected final String groupName;
|
protected final String groupName;
|
||||||
protected final ObjUtils.LevelOfDetail LOD;
|
protected final ObjUtils.LevelOfDetail LOD;
|
||||||
protected final CoordTransform transformer;
|
protected final CoordTransform transformer;
|
||||||
|
protected final WarningSet warnings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wavefront OBJ exporter for a rocket component.
|
* 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')
|
* @param LOD Level of detail to use for the export (e.g. '80')
|
||||||
*/
|
*/
|
||||||
public MotorExporter(DefaultObj obj, FlightConfiguration config, CoordTransform transformer, RocketComponent mount,
|
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)) {
|
if (!(mount instanceof MotorMount)) {
|
||||||
throw new IllegalArgumentException("Motor exporter can only be used for motor mounts");
|
throw new IllegalArgumentException("Motor exporter can only be used for motor mounts");
|
||||||
}
|
}
|
||||||
@ -46,6 +48,7 @@ public class MotorExporter {
|
|||||||
this.mount = mount;
|
this.mount = mount;
|
||||||
this.groupName = groupName;
|
this.groupName = groupName;
|
||||||
this.LOD = LOD;
|
this.LOD = LOD;
|
||||||
|
this.warnings = warnings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addToObj() {
|
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.ObjUtils;
|
||||||
import net.sf.openrocket.file.wavefrontobj.export.shapes.CylinderExporter;
|
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.DiskExporter;
|
||||||
|
import net.sf.openrocket.logging.WarningSet;
|
||||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||||
import net.sf.openrocket.rocketcomponent.InstanceContext;
|
import net.sf.openrocket.rocketcomponent.InstanceContext;
|
||||||
import net.sf.openrocket.rocketcomponent.RailButton;
|
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')
|
* @param LOD Level of detail to use for the export (e.g. '80')
|
||||||
*/
|
*/
|
||||||
public RailButtonExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
|
public RailButtonExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
|
||||||
RailButton component, String groupName, ObjUtils.LevelOfDetail LOD) {
|
RailButton component, String groupName, ObjUtils.LevelOfDetail LOD, WarningSet warnings) {
|
||||||
super(obj, config, transformer, component, groupName, LOD);
|
super(obj, config, transformer, component, groupName, LOD, warnings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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.DefaultObj;
|
||||||
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
|
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
|
||||||
import net.sf.openrocket.file.wavefrontobj.export.shapes.TubeExporter;
|
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.FlightConfiguration;
|
||||||
import net.sf.openrocket.rocketcomponent.InstanceContext;
|
import net.sf.openrocket.rocketcomponent.InstanceContext;
|
||||||
import net.sf.openrocket.rocketcomponent.RingComponent;
|
import net.sf.openrocket.rocketcomponent.RingComponent;
|
||||||
@ -12,8 +14,8 @@ import net.sf.openrocket.util.Coordinate;
|
|||||||
|
|
||||||
public class RingComponentExporter extends RocketComponentExporter<RingComponent> {
|
public class RingComponentExporter extends RocketComponentExporter<RingComponent> {
|
||||||
public RingComponentExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
|
public RingComponentExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
|
||||||
RingComponent component, String groupName, ObjUtils.LevelOfDetail LOD) {
|
RingComponent component, String groupName, ObjUtils.LevelOfDetail LOD, WarningSet warnings) {
|
||||||
super(obj, config, transformer, component, groupName, LOD);
|
super(obj, config, transformer, component, groupName, LOD, warnings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -24,6 +26,10 @@ public class RingComponentExporter extends RocketComponentExporter<RingComponent
|
|||||||
final float innerRadius = (float) component.getInnerRadius();
|
final float innerRadius = (float) component.getInnerRadius();
|
||||||
final float length = (float) component.getLength();
|
final float length = (float) component.getLength();
|
||||||
|
|
||||||
|
if (Double.compare(component.getThickness(), 0) == 0) {
|
||||||
|
warnings.add(Warning.OBJ_ZERO_THICKNESS, component.getName());
|
||||||
|
}
|
||||||
|
|
||||||
// Generate the mesh
|
// Generate the mesh
|
||||||
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
|
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
|
||||||
generateMesh(outerRadius, innerRadius, length, context);
|
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.CoordTransform;
|
||||||
import net.sf.openrocket.file.wavefrontobj.DefaultObj;
|
import net.sf.openrocket.file.wavefrontobj.DefaultObj;
|
||||||
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
|
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
|
||||||
|
import net.sf.openrocket.logging.WarningSet;
|
||||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
|
|
||||||
@ -20,6 +21,7 @@ public abstract class RocketComponentExporter<T extends RocketComponent> {
|
|||||||
protected final String groupName;
|
protected final String groupName;
|
||||||
protected final ObjUtils.LevelOfDetail LOD;
|
protected final ObjUtils.LevelOfDetail LOD;
|
||||||
protected final CoordTransform transformer;
|
protected final CoordTransform transformer;
|
||||||
|
protected final WarningSet warnings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wavefront OBJ exporter for a rocket component.
|
* 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')
|
* @param LOD Level of detail to use for the export (e.g. '80')
|
||||||
*/
|
*/
|
||||||
public RocketComponentExporter(@NotNull DefaultObj obj, @NotNull FlightConfiguration config, @NotNull CoordTransform transformer,
|
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.obj = obj;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.component = component;
|
this.component = component;
|
||||||
this.groupName = groupName;
|
this.groupName = groupName;
|
||||||
this.LOD = LOD;
|
this.LOD = LOD;
|
||||||
this.transformer = transformer;
|
this.transformer = transformer;
|
||||||
|
this.warnings = warnings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void addToObj();
|
public abstract void addToObj();
|
||||||
|
@ -9,6 +9,8 @@ import net.sf.openrocket.file.wavefrontobj.ObjUtils;
|
|||||||
import net.sf.openrocket.file.wavefrontobj.export.shapes.CylinderExporter;
|
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.DiskExporter;
|
||||||
import net.sf.openrocket.file.wavefrontobj.export.shapes.TubeExporter;
|
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.FlightConfiguration;
|
||||||
import net.sf.openrocket.rocketcomponent.InstanceContext;
|
import net.sf.openrocket.rocketcomponent.InstanceContext;
|
||||||
import net.sf.openrocket.rocketcomponent.Transition;
|
import net.sf.openrocket.rocketcomponent.Transition;
|
||||||
@ -22,8 +24,8 @@ public class TransitionExporter extends RocketComponentExporter<Transition> {
|
|||||||
private final int nrOfSides;
|
private final int nrOfSides;
|
||||||
|
|
||||||
public TransitionExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
|
public TransitionExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
|
||||||
Transition component, String groupName, ObjUtils.LevelOfDetail LOD) {
|
Transition component, String groupName, ObjUtils.LevelOfDetail LOD, WarningSet warnings) {
|
||||||
super(obj, config, transformer, component, groupName, LOD);
|
super(obj, config, transformer, component, groupName, LOD, warnings);
|
||||||
this.nrOfSides = LOD.getNrOfSides(Math.max(component.getForeRadius(), component.getAftRadius()));
|
this.nrOfSides = LOD.getNrOfSides(Math.max(component.getForeRadius(), component.getAftRadius()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,6 +33,10 @@ public class TransitionExporter extends RocketComponentExporter<Transition> {
|
|||||||
public void addToObj() {
|
public void addToObj() {
|
||||||
obj.setActiveGroupNames(groupName);
|
obj.setActiveGroupNames(groupName);
|
||||||
|
|
||||||
|
if (Double.compare(component.getThickness(), 0) == 0) {
|
||||||
|
warnings.add(Warning.OBJ_ZERO_THICKNESS, component.getName());
|
||||||
|
}
|
||||||
|
|
||||||
// Generate the mesh
|
// Generate the mesh
|
||||||
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
|
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
|
||||||
generateMesh(context);
|
generateMesh(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.DefaultObj;
|
||||||
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
|
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
|
||||||
import net.sf.openrocket.file.wavefrontobj.export.shapes.TubeExporter;
|
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.FlightConfiguration;
|
||||||
import net.sf.openrocket.rocketcomponent.InstanceContext;
|
import net.sf.openrocket.rocketcomponent.InstanceContext;
|
||||||
import net.sf.openrocket.rocketcomponent.TubeFinSet;
|
import net.sf.openrocket.rocketcomponent.TubeFinSet;
|
||||||
@ -12,8 +14,8 @@ import net.sf.openrocket.util.Coordinate;
|
|||||||
|
|
||||||
public class TubeFinSetExporter extends RocketComponentExporter<TubeFinSet> {
|
public class TubeFinSetExporter extends RocketComponentExporter<TubeFinSet> {
|
||||||
public TubeFinSetExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
|
public TubeFinSetExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
|
||||||
TubeFinSet component, String groupName, ObjUtils.LevelOfDetail LOD) {
|
TubeFinSet component, String groupName, ObjUtils.LevelOfDetail LOD, WarningSet warnings) {
|
||||||
super(obj, config, transformer, component, groupName, LOD);
|
super(obj, config, transformer, component, groupName, LOD, warnings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -24,6 +26,10 @@ public class TubeFinSetExporter extends RocketComponentExporter<TubeFinSet> {
|
|||||||
final float innerRadius = (float) component.getInnerRadius();
|
final float innerRadius = (float) component.getInnerRadius();
|
||||||
final float length = (float) component.getLength();
|
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
|
// Generate the fin meshes
|
||||||
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
|
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
|
||||||
generateMesh(outerRadius, innerRadius, length, context);
|
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_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 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 */
|
/** 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"));
|
public static final Warning SEPARATION_ORDER = new Other(trans.get("Warning.SEPARATION_ORDER"));
|
||||||
|
|
||||||
|
@ -8,16 +8,12 @@ import com.google.inject.util.Modules;
|
|||||||
import net.sf.openrocket.ServicesForTesting;
|
import net.sf.openrocket.ServicesForTesting;
|
||||||
import net.sf.openrocket.database.ComponentPresetDao;
|
import net.sf.openrocket.database.ComponentPresetDao;
|
||||||
import net.sf.openrocket.database.motor.MotorDatabase;
|
import net.sf.openrocket.database.motor.MotorDatabase;
|
||||||
import net.sf.openrocket.document.OpenRocketDocument;
|
|
||||||
import net.sf.openrocket.document.OpenRocketDocumentFactory;
|
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.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.file.wavefrontobj.ObjUtils;
|
||||||
import net.sf.openrocket.l10n.DebugTranslator;
|
import net.sf.openrocket.l10n.DebugTranslator;
|
||||||
import net.sf.openrocket.l10n.Translator;
|
import net.sf.openrocket.l10n.Translator;
|
||||||
|
import net.sf.openrocket.logging.WarningSet;
|
||||||
import net.sf.openrocket.plugin.PluginModule;
|
import net.sf.openrocket.plugin.PluginModule;
|
||||||
import net.sf.openrocket.rocketcomponent.AxialStage;
|
import net.sf.openrocket.rocketcomponent.AxialStage;
|
||||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||||
@ -43,6 +39,7 @@ import java.nio.file.Path;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
public class OBJExporterFactoryTest {
|
public class OBJExporterFactoryTest {
|
||||||
private static final File TMP_DIR = new File("./tmp/");
|
private static final File TMP_DIR = new File("./tmp/");
|
||||||
@ -165,8 +162,11 @@ public class OBJExporterFactoryTest {
|
|||||||
options.setScaling(30);
|
options.setScaling(30);
|
||||||
options.setExportChildren(true);
|
options.setExportChildren(true);
|
||||||
options.setRemoveOffset(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();
|
exporterFactory.doExport();
|
||||||
|
//// Just hope for no exceptions :)
|
||||||
|
assertEquals(warnings.size(), 0);
|
||||||
|
|
||||||
|
|
||||||
// Test with other parameters
|
// Test with other parameters
|
||||||
@ -180,8 +180,18 @@ public class OBJExporterFactoryTest {
|
|||||||
options.setScaling(1000);
|
options.setScaling(1000);
|
||||||
options.setLOD(ObjUtils.LevelOfDetail.LOW_QUALITY);
|
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();
|
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
|
// Clean up
|
||||||
Files.delete(tempFile);
|
Files.delete(tempFile);
|
||||||
|
@ -1530,8 +1530,9 @@ public class BasicFrame extends JFrame {
|
|||||||
// // Some design features may not have been exported correctly.
|
// // Some design features may not have been exported correctly.
|
||||||
trans.get("BasicFrame.WarningDialog.saving.txt2")
|
trans.get("BasicFrame.WarningDialog.saving.txt2")
|
||||||
},
|
},
|
||||||
// // Warnings while opening file
|
//// Warnings while saving file
|
||||||
trans.get("BasicFrame.WarningDialog.saving.title"), warnings);
|
trans.get("BasicFrame.WarningDialog.saving.title"),
|
||||||
|
warnings);
|
||||||
} else if (!errors.isEmpty()) {
|
} else if (!errors.isEmpty()) {
|
||||||
ErrorWarningDialog.showErrorsAndWarnings(BasicFrame.this,
|
ErrorWarningDialog.showErrorsAndWarnings(BasicFrame.this,
|
||||||
new Object[]{
|
new Object[]{
|
||||||
@ -1677,10 +1678,21 @@ public class BasicFrame extends JFrame {
|
|||||||
* @return true if the file was written
|
* @return true if the file was written
|
||||||
*/
|
*/
|
||||||
private boolean saveWavefrontOBJFile(File file, OBJExportOptions options) {
|
private boolean saveWavefrontOBJFile(File file, OBJExportOptions options) {
|
||||||
|
WarningSet warnings = new WarningSet();
|
||||||
OBJExporterFactory exporter = new OBJExporterFactory(getSelectedComponents(), rocket.getSelectedConfiguration(),
|
OBJExporterFactory exporter = new OBJExporterFactory(getSelectedComponents(), rocket.getSelectedConfiguration(),
|
||||||
file, options);
|
file, options, warnings);
|
||||||
exporter.doExport();
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user