blob: 786c2d36fdf46cf9808d891864213893bed81222 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 Agence spatiale canadienne / Canadian Space Agency
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pierre Allard,
* Regent L'Archeveque,
* Olivier L. Larouche - initial API and implementation
*
* SPDX-License-Identifier: EPL-1.0
*******************************************************************************/
package org.eclipse.apogy.core.topology.ui.internal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.apogy.common.math.ApogyCommonMathFacade;
import org.eclipse.apogy.common.topology.ApogyCommonTopologyFacade;
import org.eclipse.apogy.common.topology.ApogyCommonTopologyFactory;
import org.eclipse.apogy.common.topology.ApogyCommonTopologyPackage;
import org.eclipse.apogy.common.topology.GroupNode;
import org.eclipse.apogy.common.topology.Node;
import org.eclipse.apogy.common.topology.TransformNode;
import org.eclipse.apogy.common.topology.ui.MeshPresentationMode;
import org.eclipse.apogy.common.topology.ui.NodePresentation;
import org.eclipse.apogy.common.topology.ui.URLNodePresentation;
import org.eclipse.apogy.core.ApogySystem;
import org.eclipse.apogy.core.AssemblyLink;
import org.eclipse.apogy.core.ConnectionPoint;
import org.eclipse.apogy.core.invocator.Type;
import org.eclipse.apogy.core.invocator.TypeMember;
import org.eclipse.apogy.core.topology.ApogyCoreTopologyFactory;
import org.eclipse.apogy.core.topology.ApogyCoreTopologyPackage;
import org.eclipse.apogy.core.topology.TemporaryAssemblyNode;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ApogySystem3dUtils {
private static final Logger Logger = LoggerFactory.getLogger(ApogySystem3dUtils.class);
public static Node assembleSubSystem(ApogySystem apogySystem) {
Map<Node, Node> originalNodesToCopy = new HashMap<Node, Node>();
Map<AssemblyLink, Node> originalAssemblyLinkGeometryToCopy = new HashMap<AssemblyLink, Node>();
Map<Object, Node> systemsToRootNodeMap = ApogySystem3dUtils.createSubsystemTopologyCopies(apogySystem,
originalNodesToCopy, originalAssemblyLinkGeometryToCopy);
Node root = systemsToRootNodeMap.get(apogySystem);
// Assembles the system links.
if (apogySystem.getAssemblyLinksList() != null) {
for (AssemblyLink assemblyLink : apogySystem.getAssemblyLinksList().getAssemblyLinks()) {
ApogySystem3dUtils.assemble(assemblyLink, originalNodesToCopy, systemsToRootNodeMap,
originalAssemblyLinkGeometryToCopy);
}
}
return root;
}
public static List<TypeMember> getAllTypeMembers(final ApogySystem masterApogySystem) {
List<TypeMember> list = new ArrayList<TypeMember>();
for (TypeMember member : masterApogySystem.getMembers()) {
list.addAll(recursiveGetAllTypeMembers(masterApogySystem, member));
}
return list;
}
public static Map<Object, Node> createSubsystemTopologyCopies(final ApogySystem apogySystem,
Map<Node, Node> originalNodesToCopy, Map<AssemblyLink, Node> originalAssemblyLinkGeometryToCopy) {
List<TypeMember> typeMembers = getAllTypeMembers(apogySystem);
Map<Object, Node> typeMemberToRootNode = new HashMap<Object, Node>();
// Adds the apogySystem itself.
if (apogySystem.getTopologyRoot() != null && apogySystem.getTopologyRoot().getOriginNode() != null) {
Node originalRoot = apogySystem.getTopologyRoot().getOriginNode();
Node copyRoot = copyTopology(originalRoot, originalNodesToCopy);
typeMemberToRootNode.put(apogySystem, copyRoot);
}
// Adds the apogySystem AssemblyLink geometry.
if (apogySystem.getAssemblyLinksList() != null) {
for (AssemblyLink assemblyLink : apogySystem.getAssemblyLinksList().getAssemblyLinks()) {
if (assemblyLink.getGeometryNode() != null) {
Node originalGeometry = assemblyLink.getGeometryNode();
Node copyGeometry = copyTopology(originalGeometry, originalNodesToCopy);
originalAssemblyLinkGeometryToCopy.put(assemblyLink, copyGeometry);
}
}
}
// Adds all of the other Type members.
for (TypeMember typeMember : typeMembers) {
if (typeMember.getMemberType() instanceof ApogySystem) {
ApogySystem subSystem = (ApogySystem) typeMember.getMemberType();
if (subSystem.getTopologyRoot() != null && subSystem.getTopologyRoot().getOriginNode() != null) {
Node originalRoot = subSystem.getTopologyRoot().getOriginNode();
Node copyRoot = copyTopology(originalRoot, originalNodesToCopy);
typeMemberToRootNode.put(typeMember, copyRoot);
// Adds the apogySystem AssemblyLink geometry.
if (subSystem.getAssemblyLinksList() != null) {
for (AssemblyLink assemblyLink : subSystem.getAssemblyLinksList().getAssemblyLinks()) {
if (assemblyLink.getGeometryNode() != null) {
Node originalGeometry = assemblyLink.getGeometryNode();
Node copyGeometry = copyTopology(originalGeometry, originalNodesToCopy);
originalAssemblyLinkGeometryToCopy.put(assemblyLink, copyGeometry);
}
}
}
}
}
}
return typeMemberToRootNode;
}
public static void assemble(AssemblyLink originalAssemblyLink, final Map<Node, Node> originalNodesToCopy,
final Map<Object, Node> typeMemberToRootNode,
final Map<AssemblyLink, Node> originalAssemblyLinkGeometryToCopy) {
ConnectionPoint originalConnectionPoint = originalAssemblyLink.getParentConnectionPoint();
if (originalConnectionPoint != null) {
Node originalParentNode = originalConnectionPoint.getNode();
// Must not be null and must be a GroupNode
if (originalParentNode instanceof GroupNode) {
GroupNode copyParentNode = (GroupNode) originalNodesToCopy.get(originalParentNode);
if (copyParentNode != null) {
// Get the sub-system root node.
TypeMember subsSystemTypeMember = originalAssemblyLink.getSubSystemTypeMember();
Node subSystemRoot = typeMemberToRootNode.get(subsSystemTypeMember);
if (subSystemRoot != null) {
// Creates and attaches temporary node under the Connection point node.
TemporaryAssemblyNode temporaryAssemblyNode = ApogyCoreTopologyFactory.eINSTANCE
.createTemporaryAssemblyNode();
temporaryAssemblyNode.setNodeId(subsSystemTypeMember.getName());
copyParentNode.getChildren().add(temporaryAssemblyNode);
// Creates the transform node that takes care of the AssemblyLink
// transformation.
TransformNode transformNode = ApogyCommonTopologyFactory.eINSTANCE.createTransformNode();
transformNode.setNodeId("ASSEMBLY_LINK_" + originalAssemblyLink.getName());
transformNode.setDescription(originalAssemblyLink.getDescription());
if (originalAssemblyLink.getTransformationMatrix() != null) {
transformNode
.setTransformation(originalAssemblyLink.getTransformationMatrix().asMatrix4d());
} else {
transformNode.setTransformation(
ApogyCommonMathFacade.INSTANCE.createIdentityMatrix4x4().asMatrix4d());
}
temporaryAssemblyNode.getChildren().add(transformNode);
// Attaches the sub-system under the transform node.
if (subSystemRoot != null)
transformNode.getChildren().add(subSystemRoot);
// Attaches the assembly link geometry node.
if (originalAssemblyLink.getGeometryNode() != null) {
Node copyGeometry = originalAssemblyLinkGeometryToCopy.get(originalAssemblyLink);
// TODO : Verify where the geometry is attached.
temporaryAssemblyNode.getChildren().add(copyGeometry);
}
}
}
}
}
// Assemble the sys-system links.
if (originalAssemblyLink.getSubSystemTypeMember().getMemberType() instanceof ApogySystem) {
ApogySystem subSystem = (ApogySystem) originalAssemblyLink.getSubSystemTypeMember().getMemberType();
if (subSystem.getAssemblyLinksList() != null) {
for (AssemblyLink assemblyLink : subSystem.getAssemblyLinksList().getAssemblyLinks()) {
ApogySystem3dUtils.assemble(assemblyLink, originalNodesToCopy, typeMemberToRootNode,
originalAssemblyLinkGeometryToCopy);
}
}
}
}
public static Type load(Type type, ApogySystem master) {
if (type != null && type.eIsProxy()) {
Type loadedType = null;
ResourceSet resourceSet = master.eResource().getResourceSet();
Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
Map<String, Object> m = reg.getExtensionToFactoryMap();
m.put("*", new XMIResourceFactoryImpl());
URI uri = EcoreUtil.getURI(type);
// Get the resource
// Resource resource = resourceSet.getResource(uri, true);
Resource resource = resourceSet.createResource(uri);
// Gets the loaded type.
try {
loadedType = (Type) resource.getContents().get(0);
} catch (Exception e) {
Logger.error(e.getMessage(), e);
}
return loadedType;
} else {
return type;
}
}
public static Node copyTopology(Node originalRoot, Map<Node, Node> originalNodesToCopy) {
Node copyRoot = null;
if (originalRoot != null) {
EcoreUtil.Copier copier = new EcoreUtil.Copier();
// Copies the origin node.
copyRoot = (Node) copier.copy(originalRoot);
originalNodesToCopy.put(originalRoot, copyRoot);
for (EObject key : copier.keySet()) {
EObject value = copier.get(key);
if (key instanceof Node && value instanceof Node) {
Node nodeCopy = (Node) value;
nodeCopy.setNodeId(nodeCopy.getNodeId());
originalNodesToCopy.put((Node) key, (Node) value);
}
}
}
return copyRoot;
}
public static void setSubSystemVisibility(Node root, boolean visible) {
if (root != null) {
// Gets all the temporary Node.
List<Node> temporaryAssemblyNode = ApogyCommonTopologyFacade.INSTANCE
.findNodesByType(ApogyCoreTopologyPackage.Literals.TEMPORARY_ASSEMBLY_NODE, root);
for (Node node : temporaryAssemblyNode) {
NodePresentation nodePresentation = org.eclipse.apogy.common.topology.ui.Activator
.getTopologyPresentationRegistry().getPresentationNode(node);
if (nodePresentation != null)
nodePresentation.setVisible(visible);
}
}
}
public static void setSubSystemMode(Node root, MeshPresentationMode newMeshPresentationMode) {
if (root != null) {
// Gets all the temporary Node.
List<Node> temporaryAssemblyNodes = ApogyCommonTopologyFacade.INSTANCE
.findNodesByType(ApogyCoreTopologyPackage.Literals.TEMPORARY_ASSEMBLY_NODE, root);
for (Node temporaryAssemblyNode : temporaryAssemblyNodes) {
List<Node> urlNodes = ApogyCommonTopologyFacade.INSTANCE
.findNodesByType(ApogyCommonTopologyPackage.Literals.URL_NODE, temporaryAssemblyNode);
for (Node node : urlNodes) {
NodePresentation nodePresentation = org.eclipse.apogy.common.topology.ui.Activator
.getTopologyPresentationRegistry().getPresentationNode(node);
if (nodePresentation instanceof URLNodePresentation) {
URLNodePresentation urlNodePresentation = (URLNodePresentation) nodePresentation;
urlNodePresentation.setPresentationMode(newMeshPresentationMode);
}
}
}
}
}
protected static List<TypeMember> recursiveGetAllTypeMembers(final ApogySystem masterApogySystem,
TypeMember typeMember) {
List<TypeMember> list = new ArrayList<TypeMember>();
list.add(typeMember);
Type type = load(typeMember.getMemberType(), masterApogySystem);
if (type != null) {
for (TypeMember member : type.getMembers()) {
list.addAll(recursiveGetAllTypeMembers(masterApogySystem, member));
}
}
return list;
}
}