Fix loading custom materials from old OR files

This commit is contained in:
SiboVG 2024-08-07 11:12:22 +02:00
parent 8dcb120cc5
commit 28ca2e98c6
15 changed files with 195 additions and 11 deletions

View File

@ -201,7 +201,7 @@ public class Databases {
return m; return m;
} }
} }
return Material.newMaterial(type, name, density, group, true); return Material.newMaterial(type, name, density, group, true, true);
} }
/** /**

View File

@ -8,6 +8,7 @@ import java.io.InputStream;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
@ -18,6 +19,8 @@ import info.openrocket.core.document.OpenRocketDocumentFactory;
import info.openrocket.core.file.openrocket.importt.OpenRocketLoader; import info.openrocket.core.file.openrocket.importt.OpenRocketLoader;
import info.openrocket.core.file.rasaero.importt.RASAeroLoader; import info.openrocket.core.file.rasaero.importt.RASAeroLoader;
import info.openrocket.core.file.rocksim.importt.RockSimLoader; import info.openrocket.core.file.rocksim.importt.RockSimLoader;
import info.openrocket.core.material.Material;
import info.openrocket.core.rocketcomponent.RocketComponent;
import info.openrocket.core.util.ArrayUtils; import info.openrocket.core.util.ArrayUtils;
import info.openrocket.core.util.TextUtil; import info.openrocket.core.util.TextUtil;
@ -243,6 +246,23 @@ public class GeneralRocketLoader {
} }
} }
/**
* Load all materials that are user-defined and document materials to the document material database.
*/
private void loadMaterialsToDocument() {
for (RocketComponent c : doc.getRocket()) {
List<Material> materials = c.getAllMaterials();
if (materials == null) {
continue;
}
for (Material m : materials) {
if (m.isUserDefined() && m.isDocumentMaterial()) {
doc.getDocumentPreferences().addMaterial(m);
}
}
}
}
private void loadUsing(RocketLoader loader, InputStream source, String fileName) throws RocketLoadException { private void loadUsing(RocketLoader loader, InputStream source, String fileName) throws RocketLoadException {
warnings.clear(); warnings.clear();
DocumentLoadingContext context = new DocumentLoadingContext(); DocumentLoadingContext context = new DocumentLoadingContext();
@ -251,5 +271,8 @@ public class GeneralRocketLoader {
context.setAttachmentFactory(attachmentFactory); context.setAttachmentFactory(attachmentFactory);
loader.load(context, source, fileName); loader.load(context, source, fileName);
warnings.addAll(loader.getWarnings()); warnings.addAll(loader.getWarnings());
// Check for custom materials that need to be added to the document material database
loadMaterialsToDocument();
} }
} }

View File

@ -451,7 +451,7 @@ public class OpenRocketSaver extends RocketSaver {
writeln("<docmaterials>"); writeln("<docmaterials>");
indent++; indent++;
for (Material m : docPrefs.getAllMaterials()) { for (Material m : docPrefs.getAllMaterials()) {
writeln("<mat>" + m.toStorableString() + "</mat>"); writeln("<material>" + m.toStorableString() + "</material>");
} }
indent--; indent--;
writeln("</docmaterials>"); writeln("</docmaterials>");

View File

@ -3,10 +3,12 @@ package info.openrocket.core.file.openrocket.importt;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import info.openrocket.core.document.OpenRocketDocument;
import info.openrocket.core.logging.Warning; import info.openrocket.core.logging.Warning;
import info.openrocket.core.logging.WarningSet; import info.openrocket.core.logging.WarningSet;
import info.openrocket.core.database.Databases; import info.openrocket.core.database.Databases;
import info.openrocket.core.material.Material; import info.openrocket.core.material.Material;
import info.openrocket.core.material.MaterialGroup;
import info.openrocket.core.rocketcomponent.RocketComponent; import info.openrocket.core.rocketcomponent.RocketComponent;
import info.openrocket.core.util.Reflection; import info.openrocket.core.util.Reflection;
@ -67,7 +69,18 @@ class MaterialSetter implements Setter {
return; return;
} }
mat = Databases.findMaterial(type, name, density); // Check for material group
str = attributes.remove("group");
MaterialGroup group = null;
if (str != null) {
try {
group = MaterialGroup.loadFromDatabaseString(str);
} catch (IllegalArgumentException e) {
warnings.add(Warning.fromString("Illegal material group specified, ignoring."));
}
}
mat = Databases.findMaterial(type, name, density, group);
setMethod.invoke(c, mat); setMethod.invoke(c, mat);
} }

View File

@ -9,6 +9,7 @@ import info.openrocket.core.startup.Application;
public class MaterialGroup implements Comparable<MaterialGroup> { public class MaterialGroup implements Comparable<MaterialGroup> {
private static final Translator trans = Application.getTranslator(); private static final Translator trans = Application.getTranslator();
// When modifying this list, also update the MaterialGroupDTO class in the preset.xml package! (and the ALL_GROUPS array)
public static final MaterialGroup METALS = new MaterialGroup(trans.get("MaterialGroup.Metals"), "Metals", 0, false); public static final MaterialGroup METALS = new MaterialGroup(trans.get("MaterialGroup.Metals"), "Metals", 0, false);
public static final MaterialGroup WOODS = new MaterialGroup(trans.get("MaterialGroup.Woods"), "Woods", 10, false); public static final MaterialGroup WOODS = new MaterialGroup(trans.get("MaterialGroup.Woods"), "Woods", 10, false);
public static final MaterialGroup PLASTICS = new MaterialGroup(trans.get("MaterialGroup.Plastics"), "Plastics", 20, false); public static final MaterialGroup PLASTICS = new MaterialGroup(trans.get("MaterialGroup.Plastics"), "Plastics", 20, false);
@ -72,6 +73,9 @@ public class MaterialGroup implements Comparable<MaterialGroup> {
} }
public static MaterialGroup loadFromDatabaseString(String name) { public static MaterialGroup loadFromDatabaseString(String name) {
if (name == null) {
return MaterialGroup.OTHER;
}
for (MaterialGroup group : ALL_GROUPS) { for (MaterialGroup group : ALL_GROUPS) {
if (group.getDatabaseString().equals(name)) { if (group.getDatabaseString().equals(name)) {
return group; return group;

View File

@ -132,6 +132,10 @@ public class DocumentPreferences implements ChangeSource, ORPreferences {
return allMaterials; return allMaterials;
} }
public void addMaterial(Material material) {
getDatabase(material.getType()).add(material);
}
public int getMaterialCount(Material.Type type) { public int getMaterialCount(Material.Type type) {
return getDatabase(type).size(); return getDatabase(type).size();
} }

View File

@ -7,6 +7,8 @@ import java.io.IOException;
import java.util.List; import java.util.List;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import info.openrocket.core.material.MaterialGroup;
import jakarta.xml.bind.DatatypeConverter; import jakarta.xml.bind.DatatypeConverter;
import jakarta.xml.bind.annotation.XmlAccessType; import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType; import jakarta.xml.bind.annotation.XmlAccessorType;
@ -186,8 +188,7 @@ public abstract class BaseComponentDTO {
if (dto == null) { if (dto == null) {
return null; return null;
} }
for (int i = 0; i < materialList.size(); i++) { for (MaterialDTO materialDTO : materialList) {
MaterialDTO materialDTO = materialList.get(i);
if (materialDTO.getType().name().equals(dto.type) && materialDTO.getName().equals(dto.material)) { if (materialDTO.getType().name().equals(dto.type) && materialDTO.getName().equals(dto.material)) {
return materialDTO.asMaterial(); return materialDTO.asMaterial();
} }
@ -199,7 +200,7 @@ public abstract class BaseComponentDTO {
return m; return m;
} }
return Databases.findMaterial(dto.getORMaterialType(), dto.material, 0.0); return Databases.findMaterial(dto.getORMaterialType(), dto.material, 0.0, MaterialGroup.loadFromDatabaseString(dto.materialGroup));
} }
@ -208,6 +209,8 @@ public abstract class BaseComponentDTO {
private String type; private String type;
@XmlValue @XmlValue
private String material; private String material;
@XmlAttribute(name = "Group")
private String materialGroup;
AnnotatedMaterialDTO() { AnnotatedMaterialDTO() {
} }
@ -215,6 +218,7 @@ public abstract class BaseComponentDTO {
AnnotatedMaterialDTO(Material theMaterial) { AnnotatedMaterialDTO(Material theMaterial) {
type = theMaterial.getType().name(); type = theMaterial.getType().name();
material = theMaterial.getName(); material = theMaterial.getName();
materialGroup = theMaterial.getEquivalentGroup().getDatabaseString();
} }
public Material.Type getORMaterialType() { public Material.Type getORMaterialType() {

View File

@ -28,6 +28,8 @@ public class MaterialDTO {
private MaterialTypeDTO type; private MaterialTypeDTO type;
@XmlAttribute(name = "UnitsOfMeasure") @XmlAttribute(name = "UnitsOfMeasure")
private String uom; private String uom;
@XmlElement(name = "Group")
private MaterialGroupDTO group;
/** /**
* Default constructor. * Default constructor.
@ -37,15 +39,20 @@ public class MaterialDTO {
public MaterialDTO(final Material theMaterial) { public MaterialDTO(final Material theMaterial) {
this(theMaterial.getName(), theMaterial.getDensity(), MaterialTypeDTO.asDTO(theMaterial.getType()), this(theMaterial.getName(), theMaterial.getDensity(), MaterialTypeDTO.asDTO(theMaterial.getType()),
theMaterial.getType().getUnitGroup().getDefaultUnit().toString()); theMaterial.getType().getUnitGroup().getDefaultUnit().toString(),
MaterialGroupDTO.asDTO(theMaterial.getEquivalentGroup()));
} }
public MaterialDTO(final String theName, final double theDensity, final MaterialTypeDTO theType, public MaterialDTO(final String theName, final double theDensity, final MaterialTypeDTO theType,
final String theUom) { final String theUom, final MaterialGroupDTO theGroup) {
name = theName; name = theName;
density = theDensity; density = theDensity;
type = theType; type = theType;
uom = theUom; uom = theUom;
group = theGroup;
if (group == null) {
group = MaterialGroupDTO.OTHER;
}
} }
public String getName() { public String getName() {
@ -80,8 +87,19 @@ public class MaterialDTO {
uom = theUom; uom = theUom;
} }
public MaterialGroupDTO getGroup() {
return group;
}
public void setGroup(MaterialGroupDTO group) {
this.group = group;
}
Material asMaterial() { Material asMaterial() {
return Databases.findMaterial(type.getORMaterialType(), name, density); if (group == null) {
group = MaterialGroupDTO.OTHER;
}
return Databases.findMaterial(type.getORMaterialType(), name, density, group.getORMaterialGroup());
} }
/** /**

View File

@ -0,0 +1,56 @@
package info.openrocket.core.preset.xml;
import info.openrocket.core.material.MaterialGroup;
import jakarta.xml.bind.annotation.XmlEnum;
import jakarta.xml.bind.annotation.XmlEnumValue;
/**
* A mirror enum of MaterialGroup, for the purposes of mapping to/from an XML
* representation.
*/
@XmlEnum
public enum MaterialGroupDTO {
@XmlEnumValue("Metals")
METALS(MaterialGroup.METALS),
@XmlEnumValue("Woods")
WOODS(MaterialGroup.WOODS),
@XmlEnumValue("Plastics")
PLASTICS(MaterialGroup.PLASTICS),
@XmlEnumValue("Fabrics")
FABRICS(MaterialGroup.FABRICS),
@XmlEnumValue("PaperProducts")
PAPER(MaterialGroup.PAPER),
@XmlEnumValue("Foams")
FOAMS(MaterialGroup.FOAMS),
@XmlEnumValue("Composites")
COMPOSITES(MaterialGroup.COMPOSITES),
@XmlEnumValue("Fibres")
FIBERS(MaterialGroup.FIBERS),
@XmlEnumValue("ThreadsLines")
THREADS_LINES(MaterialGroup.THREADS_LINES),
@XmlEnumValue("Other")
OTHER(MaterialGroup.OTHER),
@XmlEnumValue("Custom")
CUSTOM(MaterialGroup.CUSTOM);
private final MaterialGroup corollary;
MaterialGroupDTO(MaterialGroup materialGroup) {
this.corollary = materialGroup;
}
public MaterialGroup getORMaterialGroup() {
return corollary;
}
public static MaterialGroupDTO asDTO(MaterialGroup targetGroup) {
MaterialGroupDTO[] values = values();
for (MaterialGroupDTO value : values) {
if (value.corollary.equals(targetGroup)) {
return value;
}
}
//throw new IllegalArgumentException("Unknown MaterialGroup: " + targetGroup);
return OTHER; // default
}
}

View File

@ -1,5 +1,6 @@
package info.openrocket.core.rocketcomponent; package info.openrocket.core.rocketcomponent;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import info.openrocket.core.l10n.Translator; import info.openrocket.core.l10n.Translator;
@ -155,6 +156,14 @@ public abstract class ExternalComponent extends RocketComponent {
fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
} }
@Override
public List<Material> getAllMaterials() {
List<Material> materials = super.getAllMaterials();
materials = materials == null ? new ArrayList<>() : materials;
materials.add(material);
return materials;
}
public Finish getFinish() { public Finish getFinish() {
return finish; return finish;
} }

View File

@ -7,6 +7,9 @@ import info.openrocket.core.preset.ComponentPreset.Type;
import info.openrocket.core.startup.Application; import info.openrocket.core.startup.Application;
import info.openrocket.core.util.MathUtil; import info.openrocket.core.util.MathUtil;
import java.util.ArrayList;
import java.util.List;
public class Parachute extends RecoveryDevice { public class Parachute extends RecoveryDevice {
private static final Translator trans = Application.getTranslator(); private static final Translator trans = Application.getTranslator();
private final double DEFAULT_DIAMETER = 0.3; private final double DEFAULT_DIAMETER = 0.3;
@ -138,6 +141,14 @@ public class Parachute extends RecoveryDevice {
fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE); fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
} }
@Override
public List<Material> getAllMaterials() {
List<Material> materials = super.getAllMaterials();
materials = materials == null ? new ArrayList<>() : materials;
materials.add(lineMaterial);
return materials;
}
@Override @Override
public double getComponentMass() { public double getComponentMass() {
return super.getComponentMass() + return super.getComponentMass() +

View File

@ -5,6 +5,9 @@ import info.openrocket.core.preset.ComponentPreset;
import info.openrocket.core.startup.Application; import info.openrocket.core.startup.Application;
import info.openrocket.core.util.MathUtil; import info.openrocket.core.util.MathUtil;
import java.util.ArrayList;
import java.util.List;
/** /**
* RecoveryDevice is a class representing devices that slow down descent. * RecoveryDevice is a class representing devices that slow down descent.
* Recovery devices report that they have no aerodynamic effect, since they * Recovery devices report that they have no aerodynamic effect, since they
@ -104,6 +107,14 @@ public abstract class RecoveryDevice extends MassObject implements FlightConfigu
fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
} }
@Override
public List<Material> getAllMaterials() {
List<Material> materials = super.getAllMaterials();
materials = materials == null ? new ArrayList<>() : materials;
materials.add(material);
return materials;
}
public FlightConfigurableParameterSet<DeploymentConfiguration> getDeploymentConfigurations() { public FlightConfigurableParameterSet<DeploymentConfiguration> getDeploymentConfigurations() {
return deploymentConfigurations; return deploymentConfigurations;
} }

View File

@ -15,6 +15,7 @@ import info.openrocket.core.aerodynamics.AerodynamicForces;
import info.openrocket.core.aerodynamics.BarrowmanCalculator; import info.openrocket.core.aerodynamics.BarrowmanCalculator;
import info.openrocket.core.aerodynamics.FlightConditions; import info.openrocket.core.aerodynamics.FlightConditions;
import info.openrocket.core.logging.WarningSet; import info.openrocket.core.logging.WarningSet;
import info.openrocket.core.material.Material;
import info.openrocket.core.rocketcomponent.position.AnglePositionable; import info.openrocket.core.rocketcomponent.position.AnglePositionable;
import info.openrocket.core.startup.Application; import info.openrocket.core.startup.Application;
import info.openrocket.core.preferences.ApplicationPreferences; import info.openrocket.core.preferences.ApplicationPreferences;
@ -1081,6 +1082,14 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
} }
} }
/**
* Returns all materials present in this component, or null if it does not have a material.
* @return a list of materials
*/
public List<Material> getAllMaterials() {
return null;
}
/** /**
* placeholder. This allows code to generally test if this component represents multiple instances with just one function call. * placeholder. This allows code to generally test if this component represents multiple instances with just one function call.
* *

View File

@ -6,6 +6,9 @@ import info.openrocket.core.startup.Application;
import info.openrocket.core.util.BugException; import info.openrocket.core.util.BugException;
import info.openrocket.core.util.MathUtil; import info.openrocket.core.util.MathUtil;
import java.util.ArrayList;
import java.util.List;
public class ShockCord extends MassObject { public class ShockCord extends MassObject {
private static final Translator trans = Application.getTranslator(); private static final Translator trans = Application.getTranslator();
@ -38,6 +41,14 @@ public class ShockCord extends MassObject {
fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
} }
@Override
public List<Material> getAllMaterials() {
List<Material> materials = super.getAllMaterials();
materials = materials == null ? new ArrayList<>() : materials;
materials.add(material);
return materials;
}
public double getCordLength() { public double getCordLength() {
return cordLength; return cordLength;
} }

View File

@ -4,6 +4,9 @@ import info.openrocket.core.material.Material;
import info.openrocket.core.preset.ComponentPreset; import info.openrocket.core.preset.ComponentPreset;
import info.openrocket.core.startup.Application; import info.openrocket.core.startup.Application;
import java.util.ArrayList;
import java.util.List;
public abstract class StructuralComponent extends InternalComponent { public abstract class StructuralComponent extends InternalComponent {
private Material material; private Material material;
@ -59,4 +62,12 @@ public abstract class StructuralComponent extends InternalComponent {
clearPreset(); clearPreset();
fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
} }
@Override
public List<Material> getAllMaterials() {
List<Material> materials = super.getAllMaterials();
materials = materials == null ? new ArrayList<>() : materials;
materials.add(material);
return materials;
}
} }