| /******************************************************************************* |
| * 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; |
| } |
| |
| } |