org.simantics.g3d.scenegraph,
org.simantics.g3d.scenegraph.base,
org.simantics.g3d.scenegraph.structural,
+ org.simantics.g3d.scl,
org.simantics.g3d.shape,
org.simantics.g3d.toolbar,
org.simantics.g3d.tools,
--- /dev/null
+import "g3d/math/Vector3d"
+import "g3d/math/Quat4d"
+
+importJava "org.simantics.g3d.scenegraph.G3DNode" where
+ data G3DNode
+
+ getOrientation :: G3DNode -> Quat4d
+ getPosition :: G3DNode -> Vector3d
+
+ setOrientation :: G3DNode -> Quat4d -> ()
+ setPosition :: G3DNode -> Vector3d -> ()
+
+ getWorldOrientation :: G3DNode -> Quat4d
+ getWorldPosition :: G3DNode -> Vector3d
+
+ setWorldOrientation :: G3DNode -> Quat4d -> ()
+ setWorldPosition :: G3DNode -> Vector3d -> ()
\ No newline at end of file
--- /dev/null
+import "g3d/math/Vector3d"
+import "g3d/math/Quat4d"
+
+importJava "org.simantics.g3d.scenegraph.G3DparentNode" where
+ data G3DParentNode
+
+ getOrientation :: G3DParentNode -> Quat4d
+ getPosition :: G3DParentNode -> Vector3d
+
+ setOrientation :: G3DParentNode -> Quat4d -> ()
+ setPosition :: G3DParentNode -> Vector3d -> ()
+
+ getWorldOrientation :: G3DParentNode -> Quat4d
+ getWorldPosition :: G3DParentNode -> Vector3d
+
+ setWorldOrientation :: G3DParentNode -> Quat4d -> ()
+ setWorldPosition :: G3DParentNode -> Vector3d -> ()
\ No newline at end of file
--- /dev/null
+
+
+importJava "org.simantics.g3d.scenegraph.base.INode" where
+ data INode
+
+importJava "org.simantics.g3d.scenegraph.base.ParentNode" where
+ data ParentNode
+
+ addNode :: ParentNode -> String -> INode -> ()
+ removeNode :: ParentNode -> String -> INode -> Boolean
+ deattachNode :: ParentNode -> String -> INode -> Boolean
+
+ removeNodes :: ParentNode -> String ->()
+ getNodes :: ParentNode -> String -> [INode]
+ @JavaName getNodes
+ getAllNodes :: ParentNode -> [INode]
+ remove :: ParentNode -> ()
+
+importJava "org.simantics.g3d.scenegraph.base.Node" where
+ data Node
+
+ getParent :: Node -> Maybe ParentNode
+ getRootNode :: Node -> Maybe ParentNode
+ deattach :: Node -> ()
--- /dev/null
+package org.simantics.g3d.scl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Stack;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Session;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.util.Layer0Utils;
+import org.simantics.g3d.ontology.G3D;
+import org.simantics.g3d.scenegraph.NodeMap;
+import org.simantics.g3d.scenegraph.base.INode;
+import org.simantics.g3d.scenegraph.base.NodeListener;
+import org.simantics.g3d.scenegraph.base.ParentNode;
+import org.simantics.objmap.exceptions.MappingException;
+import org.simantics.objmap.graph.IMapping;
+import org.simantics.objmap.graph.IMappingListener;
+import org.simantics.utils.datastructures.MapSet;
+import org.simantics.utils.datastructures.Pair;
+
+/**
+ * NodeMap implementation used with SCL scripts.
+ *
+ * In practice, there are no visible objects to synchronize.
+ *
+ * TODO:
+ * This implementation is Copy-paste of AbstractVTKNodeMap with VTK references removed.
+ * There may be more sensible way to do this.
+ *
+ *
+ * @author luukkainen
+ *
+ * @param <E>
+ */
+public abstract class ScriptNodeMap<E extends INode> implements NodeMap<Object,E>, IMappingListener, NodeListener {
+
+ private static final boolean DEBUG = false;
+
+ protected Session session;
+ protected IMapping<Object,E> mapping;
+
+ protected ParentNode<E> rootNode;
+
+ protected Set<E> nodes = new HashSet<E>();
+
+ private boolean dirty = false;
+
+ public ScriptNodeMap(Session session, IMapping<Object,E> mapping, ParentNode<E> rootNode) {
+ this.session = session;
+ this.mapping = mapping;
+ this.rootNode = rootNode;
+ mapping.addMappingListener(this);
+ rootNode.addListener(this);
+ }
+
+
+
+ protected abstract void addActor(E node);
+ protected abstract void removeActor(E node);
+ protected abstract void updateActor(E node,Set<String> ids);
+
+ public void repaint() {
+ dirty = true;
+ }
+
+ public void populate() {
+ for (E node : rootNode.getNodes()) {
+ receiveAdd(node, node.getParentRel(),true);
+ }
+ repaint();
+ }
+
+ @Override
+ public E getNode(Object o) {
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Collection<Object> getRenderObjects(INode node) {
+ return Collections.EMPTY_LIST;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public ParentNode<E> getRootNode() {
+ return (ParentNode<E>)rootNode;
+ }
+
+
+
+ @Override
+ public boolean isChangeTracking() {
+ return changeTracking;
+ }
+
+ @Override
+ public void setChangeTracking(boolean enabled) {
+ changeTracking = enabled;
+ }
+
+ private boolean changeTracking = true;
+
+ protected Object syncMutex = new Object();
+
+
+ private List<Pair<E,String>> added = new ArrayList<Pair<E,String>>();
+ private List<Pair<E,String>> removed = new ArrayList<Pair<E,String>>();
+ private MapSet<E, String> updated = new MapSet.Hash<E, String>();
+
+ private boolean rangeModified = false;
+
+
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void updateRenderObjectsFor(E node) {
+ nodes.add((E)node);
+
+ }
+
+ @SuppressWarnings("unchecked")
+ private void receiveAdd(E node, String id, boolean db) {
+ if (DEBUG) System.out.println("receiveAdd " + debugString(node) + " " + id + " " + db);
+ synchronized (syncMutex) {
+ for (Pair<E, String> n : added) {
+ if (n.first.equals(node))
+ return;
+ }
+ if (changeTracking) {
+ mapping.rangeModified((E)node.getParent());
+ }
+ added.add(new Pair<E, String>(node, id));
+ rangeModified = true;
+ }
+ repaint();
+ }
+
+ @SuppressWarnings("unchecked")
+ private void receiveRemove(E node, String id, boolean db) {
+ if (DEBUG) System.out.println("receiveRemove " + debugString(node) + " " + id + " " + db);
+ synchronized (syncMutex) {
+ for (Pair<E, String> n : removed) {
+ if (n.first.equals(node))
+ return;
+ }
+ if (changeTracking && !db)
+ mapping.rangeModified((E)node.getParent());
+ removed.add(new Pair<E, String>(node, id));
+ rangeModified = true;
+ }
+ repaint();
+ }
+
+ @SuppressWarnings("unchecked")
+ private void receiveUpdate(E node, String id, boolean db) {
+ if (DEBUG) System.out.println("receiveUpdate " + debugString(node) + " " + id + " " + db);
+ synchronized (syncMutex) {
+// for (Pair<E, String> n : updated) {
+// if (n.first.equals(node))
+// return;
+// }
+ if (changeTracking && !db)
+ mapping.rangeModified(node);
+ //updated.add(new Pair<E, String>(node, id));
+ updated.add(node, id);
+ rangeModified = true;
+ }
+ repaint();
+ }
+
+ private boolean graphUpdates = false;
+ private Set<E> graphModified = new HashSet<E>();
+
+ private boolean requestCommit = false;
+ private String commitMessage = null;
+
+ @Override
+ public void commit(String message) {
+ requestCommit = true;
+ commitMessage = message;
+ }
+
+ protected void doCommit() throws DatabaseException {
+ session.syncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ if (DEBUG) System.out.println("Commit " + commitMessage);
+ if (commitMessage != null) {
+ Layer0Utils.addCommentMetadata(graph, commitMessage);
+ graph.markUndoPoint();
+ commitMessage = null;
+ }
+ commit(graph);
+ }
+
+ });
+ }
+
+ protected void commit(WriteGraph graph) throws DatabaseException {
+ synchronized(syncMutex) {
+ if (DEBUG) System.out.println("Commit");
+ graphUpdates = true;
+ mapping.updateDomain(graph);
+ graphUpdates = false;
+ clearDeletes();
+ if (DEBUG) System.out.println("Commit done");
+ }
+ }
+
+
+
+ @Override
+ public void domainModified() {
+ if (graphUpdates)
+ return;
+ if (DEBUG)System.out.println("domainModified");
+ // FIXME : this is called by IMapping id DB thread
+ session.asyncRequest(new ReadRequest() {
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void run(ReadGraph graph) throws DatabaseException {
+ update(graph);
+ }
+ });
+
+ }
+
+ protected void reset(ReadGraph graph) throws MappingException {
+ if (DEBUG) System.out.println("Reset");
+ synchronized (syncMutex) {
+ graphUpdates = true;
+ mapping.getRangeModified().clear();
+ for (Object o : mapping.getDomain())
+ mapping.domainModified(o);
+ mapping.updateRange(graph);
+ graphModified.clear();
+ graphUpdates = false;
+ }
+ }
+
+
+ protected void update(ReadGraph graph) throws DatabaseException {
+ if (DEBUG) System.out.println("Graph update start");
+ synchronized (syncMutex) {
+ graphUpdates = true;
+ for (Object domainObject : mapping.getDomainModified()) {
+ E rangeObject = mapping.get(domainObject);
+ if (rangeObject != null)
+ graphModified.add(rangeObject);
+ }
+ mapping.updateRange(graph);
+ graphModified.clear();
+ syncDeletes();
+ clearDeletes();
+ graphUpdates = false;
+ }
+
+
+ //if (mapping.isRangeModified() && !runUndo) // FIXME : redo?
+ if (mapping.isRangeModified())
+ commit((String)null);
+ if (DEBUG) System.out.println("Graph update done");
+ }
+
+ @Override
+ public void rangeModified() {
+ //System.out.println("rangeModified");
+
+ }
+
+ public void update() throws DatabaseException{
+ while (dirty) {
+ dirty = false;
+ // preRender
+ updateCycle();
+ // postRender
+ if (requestCommit && !rangeModified) { // FIXME : not thread safe.
+ requestCommit = false;
+ doCommit();
+ }
+ }
+ }
+
+
+
+ // Reusable containers for data synchronisation
+ List<Pair<E, String>> rem = new ArrayList<Pair<E,String>>(); // Removed objects
+ List<Pair<E, String>> add = new ArrayList<Pair<E,String>>(); // Added objects
+ MapSet<E, String> mod = new MapSet.Hash<E, String>(); // Modified objects
+ Set<E> propagation = new HashSet<E>(); // Objects with propagated changes
+ Stack<E> stack = new Stack<E>(); // Stack for handling propagation
+ Set<E> delete = Collections.synchronizedSet(new HashSet<E>()); // Objects to be completely deleted
+ Set<E> deleteUC = new HashSet<E>();
+
+
+
+
+ /**
+ * When objects are removed (either from Java or Graph), after remove processing the Java objects remain in mapping cache.
+ * This causes problems with Undo and Redo, whcih the end up re-using the removed objects from mapping cache.
+ *
+ * This code here synchronizes removed and added objects to collect deletable objects. (a deletable object is one which is removed but not added).
+ *
+ */
+ protected void syncDeletes() {
+ deleteUC.clear();
+ for (Pair<E, String> n : removed) {
+ deleteUC.add(n.first);
+ }
+ for (Pair<E, String> n : added) {
+ deleteUC.remove(n.first);
+ }
+ if (DEBUG && deleteUC.size() > 0) {
+ System.out.println("Delete sync");
+ for (E n : delete) {
+ System.out.println(debugString(n));
+ }
+ }
+ delete.addAll(deleteUC);
+ deleteUC.clear();
+ }
+
+ /**
+ * Clears deletable objects from mapping cache.
+ */
+ protected void clearDeletes() {
+ if (DEBUG && delete.size() > 0) System.out.println("Delete");
+ for (E n : delete) {
+ if (DEBUG) System.out.println(debugString(n));
+ mapping.getRange().remove(n);
+ }
+ delete.clear();
+ }
+
+ protected String debugString(E n) {
+ return n + "@" + Integer.toHexString(n.hashCode());
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void updateCycle() {
+ rem.clear();
+ add.clear();
+ mod.clear();
+ propagation.clear();
+
+
+ synchronized (syncMutex) {
+ rem.addAll(removed);
+ add.addAll(added);
+ for (E e : updated.getKeys()) {
+ for (String s : updated.getValues(e)) {
+ mod.add(e, s);
+ }
+ }
+ syncDeletes();
+ removed.clear();
+ added.clear();
+ updated.clear();
+ }
+
+ for (Pair<E, String> n : rem) {
+ stopListening(n.first);
+ removeActor(n.first);
+ }
+
+ for (Pair<E, String> n : add) {
+ addActor(n.first);
+ listen(n.first);
+ }
+
+ for (E e : mod.getKeys()) {
+ Set<String> ids = mod.getValues(e);
+ if (ids.contains(G3D.URIs.hasPosition) || ids.contains(G3D.URIs.hasOrientation)) {
+ if (!propagation.contains(e))
+ propagation.add(e);
+ }
+ }
+
+ if (propagation.size() > 0) {
+ stack.clear();
+ stack.addAll(propagation);
+ propagation.clear();
+ while (!stack.isEmpty()) {
+ E node = stack.pop();
+ if (propagation.contains(node))
+ continue;
+ propagation.add(node);
+ for (NodeListener l : node.getListeners()) {
+ if (l == this) {
+ //changeTracking = false;
+ //l.propertyChanged(node, G3D.URIs.hasPosition);
+ //changeTracking = true;
+ } else {
+ l.propertyChanged(node, G3D.URIs.hasWorldPosition);
+ }
+ }
+ if (node instanceof ParentNode) {
+ stack.addAll(((ParentNode<E>)node).getNodes());
+ }
+ }
+ }
+
+// synchronized (syncMutex) {
+// rem.addAll(removed);
+// add.addAll(added);
+// //mod.addAll(updated);
+// for (E e : updated.getKeys()) {
+// for (String s : updated.getValues(e))
+// mod.add(e, s);
+// }
+//
+// removed.clear();
+// added.clear();
+// updated.clear();
+// }
+
+ for (E e : mod.getKeys()) {
+ Set<String> ids = mod.getValues(e);
+ updateActor(e,ids);
+ }
+
+
+ for (Pair<E, String> n : rem) {
+ for (NodeListener l : nodeListeners)
+ l.nodeRemoved(null, n.first, n.second);
+ }
+ for (Pair<E, String> n : add) {
+ for (NodeListener l : nodeListeners)
+ l.nodeAdded(n.first.getParent(), n.first, n.second);
+ }
+// for (Pair<E, String> n : mod) {
+// for (NodeListener l : nodeListeners)
+// l.propertyChanged(n.first, n.second);
+// }
+ for (E e : mod.getKeys()) {
+ for (NodeListener l : nodeListeners)
+ for (String s : mod.getValues(e))
+ l.propertyChanged(e, s);
+ }
+
+ synchronized (syncMutex) {
+ if (added.isEmpty() && removed.isEmpty() && updated.getKeys().size() == 0)
+ rangeModified = false;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void listen(INode node) {
+ node.addListener(this);
+ if (node instanceof ParentNode<?>) {
+ ParentNode<INode> parentNode = (ParentNode<INode>)node;
+ for (INode n : parentNode.getNodes())
+ listen(n);
+ }
+ }
+
+ private void stopListening(INode node) {
+ node.removeListener(this);
+ if (node instanceof ParentNode<?>) {
+ @SuppressWarnings("unchecked")
+ ParentNode<INode> parentNode = (ParentNode<INode>)node;
+ for (INode n : parentNode.getNodes())
+ stopListening(n);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void propertyChanged(INode node, String id) {
+ //receiveUpdate((E)node, id, graphUpdates);
+ receiveUpdate((E)node, id, graphModified.contains(node));
+
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T extends INode> void nodeAdded(ParentNode<T> node, INode child,
+ String rel) {
+ if (DEBUG) System.out.println("Node added " + child + " parent " + node);
+ //receiveAdd((E)child, rel ,graphUpdates);
+ receiveAdd((E)child, rel ,graphModified.contains(node));
+
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T extends INode> void nodeRemoved(ParentNode<T> node, INode child,
+ String rel) {
+ if (DEBUG) System.out.println("Node removed " + child + " parent " + node);
+ //receiveRemove((E)child, rel, graphUpdates);
+ receiveRemove((E)child, rel, graphModified.contains(node));
+
+ //FIXME : sometimes removed structural models cause ObjMap to add their children again.
+ // removing the listener here prevents corruption of visual model, but better fix is needed.
+ stopListening(child);
+ }
+
+ @Override
+ public void delete() {
+
+ changeTracking = false;
+ mapping.removeMappingListener(this);
+
+ for (E node : nodes) {
+ node.removeListener(this);
+ removeActor(node);
+ node.cleanup();
+ }
+ nodes.clear();
+ }
+
+
+ private List<NodeListener> nodeListeners = new ArrayList<NodeListener>();
+ @Override
+ public void addListener(NodeListener listener) {
+ nodeListeners.add(listener);
+
+ }
+
+ @Override
+ public void removeListener(NodeListener listener) {
+ nodeListeners.remove(listener);
+
+ }
+
+ public IMapping<Object,E> getMapping() {
+ return mapping;
+ }
+
+
+}
import "./PipelineComponent"
-import "./PipeRun"
importJava "org.simantics.plant3d.scenegraph.EndComponent" where
data EndComponent
import "./PipelineComponent"
-import "./PipeRun"
importJava "org.simantics.plant3d.scenegraph.InlineComponent" where
data InlineComponent
import "./PipelineComponent"
-import "./PipeRun"
importJava "org.simantics.plant3d.scenegraph.Nozzle" where
data Nozzle
--- /dev/null
+import "g3d/math/Vector3d"
+import "g3d/math/Quat4d"
+import "g3d/scenegraph/Node"
+
+importJava "org.simantics.plant3d.scenegraph.P3DRootNode" where
+ data P3DRootNode
+
+ addChild :: P3DRootNode -> INode -> ()
+ getChild :: P3DRootNode -> [INode]
+ remChild :: P3DRootNode -> INode -> ()
+
+++ /dev/null
-import "g3d/math/Tuple3d"
-
-importJava "org.simantics.plant3d.scenegraph.PipeRun" where
- data PipeRun
\ No newline at end of file
import "g3d/math/Tuple3d"
-
-import "./PipeRun"
+import "g3d/math/Quat4d"
+import "g3d/math/Vector3d"
importJava "org.simantics.plant3d.scenegraph.PipelineComponent" where
data PipelineComponent
getFlowLength :: PipelineComponent -> Maybe Double
getEnds :: PipelineComponent -> Tuple3d -> Tuple3d -> ()
-importJava "org.simantics.plant3d.scenegraph.PipeControlPoint$Type" where
+ getOrientation :: PipelineComponent -> Quat4d
+ getPosition :: PipelineComponent -> Vector3d
+
+ setOrientation :: PipelineComponent -> Quat4d -> ()
+ setPosition :: PipelineComponent -> Vector3d -> ()
+
+ getWorldOrientation :: PipelineComponent -> Quat4d
+ getWorldPosition :: PipelineComponent -> Vector3d
+
+ setWorldOrientation :: PipelineComponent -> Quat4d -> ()
+ setWorldPosition :: PipelineComponent -> Vector3d -> ()
+
+importJava "org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint$PointType" where
data PointType
-importJava "org.simantics.plant3d.scenegraph.PipeControlPoint.Direction" where
+ INLINE :: PointType
+ TURN :: PointType
+ END :: PointType
+
+importJava "org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint$Direction" where
data Direction
-importJava "org.simantics.plant3d.scenegraph.PipeControlPoint.PositionType" where
+ @JavaName NEXT
+ DNEXT :: Direction
+ @JavaName PREVIOUS
+ DPREVIOUS :: Direction
+
+importJava "org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint$PositionType" where
data PositionType
+
+ NEXT :: PositionType
+ PREVIOUS :: PositionType
+ SPLIT :: PositionType
+ PORT :: PositionType
importJava "org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint" where
data PipeControlPoint
isFixed :: PipeControlPoint -> Boolean
getSubPoint :: PipeControlPoint -> [PipeControlPoint]
- getParentPoint :: PipeControlPoint -> Maybe PipeControlPoint
\ No newline at end of file
+ getParentPoint :: PipeControlPoint -> Maybe PipeControlPoint
+
+importJava "org.simantics.plant3d.scenegraph.PipeRun" where
+ data PipeRun
+
+ getTurnRadius :: PipeRun -> Double
+ setTurnRadius :: PipeRun -> Double -> ()
+
+ getPipeDiameter :: PipeRun -> Double
+ setPipeDiameter :: PipeRun -> Double -> ()
+
+ addChild :: PipeRun -> PipelineComponent -> ()
+ getChild :: PipeRun -> [PipelineComponent]
+ remChild :: PipeRun -> PipelineComponent -> ()
+
+ getSortedChild :: PipeRun -> [PipelineComponent]
\ No newline at end of file
import "./PipelineComponent"
-import "./PipeRun"
import "g3d/math/Vector3d"
--- /dev/null
+import "Simantics/DB"
+import "plant3d/scenegraph/P3DRootNode"
+import "./P3DScriptNodeMap"
+import "JavaBuiltin"
+
+importJava "org.simantics.plant3d.scl.SCLUtil" where
+
+ loadReadOnly :: Resource -> P3DRootNode
+ load :: Resource -> P3DScriptNodeMap
+
+safeCoerce :: a -> Maybe b
+safeCoerce a = do
+ (Just $ unsafeCoerce a) `catch` (\(_ :: Exception) -> Nothing)
\ No newline at end of file
--- /dev/null
+importJava "org.simantics.plant3d.scl.P3DScriptNodeMap" where
+ data P3DScriptNodeMap
\ No newline at end of file
public class P3DContentOutlinePage extends VTKContentOutlinePage<Resource, Object>{
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = true;
protected Menu contextMenu;
private LocalResourceManager manager = new LocalResourceManager(JFaceResources.getResources());
@RelatedElementsAdd(Plant3D.URIs.childen)
- public void addChild(IP3DVisualNode node) {
+ public void addChild(INode node) {
+ //public void addChild(IP3DVisualNode node) {
addNode(Plant3D.URIs.childen,node);
}
}
@RelatedElementsRem(Plant3D.URIs.childen)
- public void remChild(IP3DNode node) {
+ public void remChild(INode node) {
+ //public void remChild(IP3DNode node) {
removeNode(Plant3D.URIs.childen, node);
}
import org.simantics.objmap.graph.annotations.RelatedSetObj;
import org.simantics.plant3d.ontology.Plant3D;
import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint;
-import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.Type;
+import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.PointType;
import org.simantics.plant3d.scenegraph.controlpoint.PipingRules;
/**
return null;
branchPoint = new PipeControlPoint(this,branch0.getPipeRun());
branchPoint.setFixed(false);
- branchPoint.setType(Type.END);
+ branchPoint.setType(PointType.END);
branchPoint.parent = getControlPoint();
getControlPoint().children.add(branchPoint);
branchPoint.setWorldOrientation(getControlPoint().getWorldOrientation());
import org.simantics.db.request.Read;
import org.simantics.plant3d.ontology.Plant3D;
import org.simantics.plant3d.scenegraph.PipelineComponent;
-import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.Type;
+import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint.PointType;
import org.simantics.plant3d.utils.Item;
import org.simantics.plant3d.utils.P3DUtil;
private static class Instruction {
- Type type;
+ PointType type;
boolean fixed;
boolean isOffset;
boolean isSizeChange;
i.isSizeChange = false;
i.isRotate = false;
i.isReverse = false;
- i.type = Type.INLINE;
+ i.type = PointType.INLINE;
if (graph.isInheritedFrom(res, p3d.Nozzle)) {
i.fixed = true;
i.isOffset = false;
i.isSizeChange = false;
- i.type = Type.END;
+ i.type = PointType.END;
} else if (graph.isInheritedFrom(res, p3d.InlineComponent)){
- i.type = Type.INLINE;
+ i.type = PointType.INLINE;
if (graph.hasStatement(res,p3d.VariableLengthInlineComponent)) {
i.fixed = false;
} else if (graph.hasStatement(res,p3d.FixedLengthInlineComponent)) {
}
} else if (graph.isInheritedFrom(res, p3d.TurnComponent)) {
- i.type = Type.TURN;
+ i.type = PointType.TURN;
if (graph.hasStatement(res,p3d.VariableAngleTurnComponent)) {
i.fixed = false;
} else if (graph.hasStatement(res,p3d.FixedAngleTurnComponent)) {
}
} else if (graph.isInheritedFrom(res, p3d.EndComponent)) {
i.fixed = false;
- i.type = Type.END;
+ i.type = PointType.END;
} else {
return null;
}
private static boolean DEBUG = false;
- public enum Type{INLINE,TURN,END};
+ public enum PointType{INLINE,TURN,END};
public enum Direction{NEXT,PREVIOUS};
public enum PositionType {SPLIT,NEXT,PREVIOUS,PORT}
private PipelineComponent component;
- private Type type;
+ private PointType type;
private boolean fixed = true;
private boolean rotate = false;
private boolean reverse = false;
return component;
}
- public Type getType() {
+ public PointType getType() {
return type;
}
- public void setType(Type type) {
+ public void setType(PointType type) {
this.type = type;
}
}
public boolean isPathLegEnd() {
- return type != Type.INLINE;
+ return type != PointType.INLINE;
}
public boolean isEnd() {
- return type == Type.END;
+ return type == PointType.END;
}
public boolean isTurn() {
- return type == Type.TURN;
+ return type == PointType.TURN;
}
public boolean isInline() {
- return type == Type.INLINE;
+ return type == PointType.INLINE;
}
public boolean isDirected() {
}
public double getInlineLength() {
- if (type == Type.TURN)
+ if (type == PointType.TURN)
return length;
- else if (type == Type.INLINE)
+ else if (type == PointType.INLINE)
return length * 0.5;
return 0;
}
--- /dev/null
+package org.simantics.plant3d.scl;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Session;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.g3d.ontology.G3D;
+import org.simantics.g3d.scenegraph.base.INode;
+import org.simantics.g3d.scenegraph.base.ParentNode;
+import org.simantics.g3d.scl.ScriptNodeMap;
+import org.simantics.g3d.vtk.common.VtkView;
+import org.simantics.objmap.graph.IMapping;
+import org.simantics.plant3d.ontology.Plant3D;
+import org.simantics.plant3d.scenegraph.IP3DNode;
+import org.simantics.plant3d.scenegraph.IP3DVisualNode;
+import org.simantics.plant3d.scenegraph.P3DParentNode;
+import org.simantics.plant3d.scenegraph.P3DRootNode;
+import org.simantics.plant3d.scenegraph.ParameterizedNode;
+import org.simantics.plant3d.scenegraph.PipeRun;
+import org.simantics.plant3d.scenegraph.controlpoint.PipeControlPoint;
+import org.simantics.plant3d.scenegraph.controlpoint.PipingRules;
+
+import vtk.vtkProp3D;
+
+public class P3DScriptNodeMap extends ScriptNodeMap<INode>{
+
+ private static final boolean DEBUG = false;
+
+ public P3DScriptNodeMap(Session session, IMapping mapping, P3DRootNode rootNode) {
+ super(session,mapping,rootNode);
+ //rootNode.setNodeMap(this);
+ }
+
+ @Override
+ protected void updateActor(INode n, Set<String> ids) {
+ if (DEBUG) System.out.println("P3DNodeMap update " + n);
+ if (!(n instanceof IP3DVisualNode)) {
+ if (n instanceof PipeControlPoint) {
+ n = ((PipeControlPoint)n).getPipelineComponent();
+ if (n == null)
+ return;
+ } else {
+ return;
+ }
+ }
+
+ IP3DVisualNode node = (IP3DVisualNode)n;
+
+ if (DEBUG) {
+ System.out.print("P3DNodeMap update " + node);
+ for (String s : ids)
+ System.out.print(" " + s);
+ System.out.println();
+ }
+
+ if (ids.contains(Plant3D.URIs.hasGeometry)) {
+ //node.visualize(view);
+ //updateRenderObjectsFor(node);
+ updateTransform(node);
+ }
+ if (n instanceof ParameterizedNode) {
+ ParameterizedNode geom = (ParameterizedNode)n;
+ for (String id : geom.getParameterMap().keySet()) {
+ if (ids.contains(id)) {
+// node.visualize(view);
+// updateRenderObjectsFor(node);
+ updateTransform(node);
+ break;
+ }
+ }
+ } else if (n instanceof PipeRun) {
+ // FIXME: may require rule based update!
+ PipeRun run = (PipeRun)n;
+ Set<String> ids2 = new HashSet<String>();
+ ids2.add(Plant3D.URIs.hasGeometry);
+ for (PipeControlPoint pcp : run.getControlPoints()) {
+ updateActor(pcp, ids2);
+ }
+ }
+
+ if (ids.contains(G3D.URIs.hasPosition) ||
+ ids.contains(G3D.URIs.hasOrientation) ||
+ ids.contains(G3D.URIs.hasWorldPosition) ||
+ ids.contains(G3D.URIs.hasWorldOrientation)) {
+ updateTransform(node);
+ }
+ }
+
+ private void updateTransform(IP3DNode node) {
+ if (DEBUG) System.out.println("P3DNodeMap update Transform " + node);
+
+
+ if (node instanceof ParentNode<?>) {
+ ParentNode<IP3DNode> p = (ParentNode<IP3DNode>)node;
+ for (IP3DNode n : p.getNodes())
+ updateTransform(n);
+ }
+ }
+
+ @Override
+ protected void removeActor(INode n) {
+ if (DEBUG) System.out.println("P3DNodeMap.removeActor " + n);
+ if (!(n instanceof IP3DVisualNode))
+ return;
+ IP3DVisualNode node = (IP3DVisualNode)n;
+// remActor(node);
+
+ if (node instanceof P3DParentNode<?>) {
+ for (IP3DNode n2 : ((P3DParentNode<?>)node).getNodes())
+ if (n2 instanceof IP3DVisualNode)
+ removeActor((IP3DVisualNode)n2);
+ }
+ }
+
+ @Override
+ protected void addActor(INode n) {
+ if (DEBUG) System.out.println("P3DNodeMap.addActor " + n);
+ if (!(n instanceof IP3DVisualNode))
+ return;
+ IP3DVisualNode node = (IP3DVisualNode)n;
+
+// if (hasActor(node))
+// return;
+
+ if (node instanceof P3DParentNode<?>) {
+ for (IP3DNode n2 : ((P3DParentNode<?>)node).getNodes())
+ if (n2 instanceof IP3DVisualNode)
+ addActor((IP3DVisualNode)n2);
+ }
+
+ updateTransform(node);
+ }
+
+ @Override
+ protected void update(ReadGraph graph) throws DatabaseException {
+ validate();
+// System.out.println("Graph updates");
+ super.update(graph);
+ validate();
+ }
+
+ @Override
+ public void commit(String commitMessage) {
+ validate();
+// System.out.println("Graph commit");
+ super.commit(commitMessage);
+
+ }
+ @Override
+ protected void doCommit() throws DatabaseException{
+// System.out.println("Do commit");
+ validate();
+ super.doCommit();
+ }
+
+ private void validate() {
+ for (INode node : rootNode.getNodes()) {
+ if (node instanceof PipeRun)
+ PipingRules.validate((PipeRun)node);
+ }
+ }
+
+ @Override
+ public void update() throws DatabaseException {
+ try {
+ boolean b = true;
+ while (b) {
+ updateCycle();
+ b = PipingRules.update();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ super.update();
+ }
+
+}
--- /dev/null
+package org.simantics.plant3d.scl;
+
+
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.request.Read;
+import org.simantics.objmap.graph.IMapping;
+import org.simantics.objmap.graph.Mappings;
+import org.simantics.objmap.graph.schema.IMappingSchema;
+import org.simantics.plant3d.scenegraph.P3DRootNode;
+import org.simantics.plant3d.scenegraph.SchemaBuilder;
+import org.simantics.plant3d.scenegraph.controlpoint.ControlPointFactory;
+import org.simantics.plant3d.scenegraph.controlpoint.PipingRules;
+import org.simantics.plant3d.utils.ComponentUtils;
+import org.simantics.plant3d.utils.P3DUtil;
+
+public class SCLUtil {
+
+ public static P3DScriptNodeMap load(final Resource root) throws DatabaseException {
+ try {
+ ControlPointFactory.preloadCache();
+ ComponentUtils.preloadCache();
+ } catch (Exception e) {
+ throw new DatabaseException(e);
+ }
+ return Simantics.getSession().syncRequest(new Read<P3DScriptNodeMap>() {
+ @Override
+ public P3DScriptNodeMap perform(ReadGraph graph) throws DatabaseException {
+ PipingRules.setEnabled(false);
+ IMappingSchema<Resource, Object> schema = SchemaBuilder.getSchema(graph);
+ IMapping mapping = Mappings.createWithListening(schema);
+ P3DRootNode rootNode = (P3DRootNode)mapping.map(graph, root);
+ try {
+ P3DUtil.finalizeDBLoad(rootNode);
+ } catch (Exception e) {
+ throw new DatabaseException(e);
+ }
+ P3DScriptNodeMap nodeMap = new P3DScriptNodeMap(Simantics.getSession(), mapping, rootNode);
+ return nodeMap;
+
+ }
+ });
+
+ }
+
+ public static P3DRootNode loadReadOnly(final Resource root) throws DatabaseException {
+ try {
+ ControlPointFactory.preloadCache();
+ ComponentUtils.preloadCache();
+ } catch (Exception e) {
+ throw new DatabaseException(e);
+ }
+ return Simantics.getSession().syncRequest(new Read<P3DRootNode>() {
+ @Override
+ public P3DRootNode perform(ReadGraph graph) throws DatabaseException {
+ PipingRules.setEnabled(false);
+ IMappingSchema<Resource, Object> schema = SchemaBuilder.getSchema(graph);
+ IMapping mapping = Mappings.createWithoutListening(schema);
+ P3DRootNode rootNode = (P3DRootNode)mapping.map(graph, root);
+ try {
+ P3DUtil.finalizeDBLoad(rootNode);
+ } catch (Exception e) {
+ throw new DatabaseException(e);
+ }
+ return rootNode;
+
+ }
+ });
+ }
+
+}