]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/InstancingShapeNode.java
Configurable connection crossing styles
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / g2d / nodes / InstancingShapeNode.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.scenegraph.g2d.nodes;
13
14 import java.awt.Graphics2D;
15 import java.awt.Paint;
16 import java.awt.Shape;
17 import java.awt.geom.AffineTransform;
18 import java.awt.geom.Rectangle2D;
19
20 /**
21  * A scene graph node that renders multiple separately transformed instances of
22  * a {@link Shape} by optionally filling or stroking it.
23  * 
24  * If filling is enabled, it will be performed before stroking the shape.
25  * 
26  * @author Tuukka Lehtonen
27  */
28 public class InstancingShapeNode extends ShapeNode {
29
30     private static final long serialVersionUID = -681327976554446434L;
31
32     AffineTransform[] transforms = {};
33     Paint[] paints = {};
34
35     @SyncField({"instances", "paints"})
36     public void setInstances(AffineTransform[] transforms, Paint[] paints) {
37         if (transforms.length != paints.length)
38             throw new IllegalArgumentException("transforms.length (" + transforms.length + ") != paints.length (" + paints.length + ")");
39
40         this.transforms = transforms;
41         this.paints = paints;
42     }
43
44     @Override
45     public void render(Graphics2D g2d) {
46         if (shape == null)
47             return;
48         if (transforms == null || transforms.length == 0)
49             return;
50
51         setupRender(g2d);
52
53         AffineTransform startTr = g2d.getTransform();
54         Paint startPaint = g2d.getPaint();
55
56         for (int i = 0; i < transforms.length; ++i) {
57             if (transforms[i] != null)
58                 g2d.transform(transforms[i]);
59
60             if (paints[i] != null)
61                 g2d.setPaint(paints[i]);
62             else
63                 g2d.setPaint(startPaint);
64
65             renderShape(g2d, shape);
66
67             g2d.setTransform(startTr);
68         }
69     }
70
71     @Override
72     public Rectangle2D getBoundsInLocal() {
73         if (shape == null)
74             return null;
75         if (transforms == null || transforms.length == 0)
76             return null;
77
78         Rectangle2D result = null;
79         Rectangle2D sb = shape.getBounds2D();
80         for (AffineTransform at : transforms) {
81             Rectangle2D instanceBounds = at.createTransformedShape(sb).getBounds2D();
82             if (result == null)
83                 result = instanceBounds;
84             else
85                 Rectangle2D.union(result, instanceBounds, result);
86         }
87
88         return result;
89     }
90
91 }