MeVisLab Resolution Independence API
SoCoordinateSystem.h
Go to the documentation of this file.
1/*************************************************************************************
2**
3** Copyright 2021, MeVis Medical Solutions AG
4**
5** The user may use this file in accordance with the license agreement provided with
6** the Software or, alternatively, in accordance with the terms contained in a
7** written agreement between the user and MeVis Medical Solutions AG.
8**
9** For further information use the contact form at https://www.mevislab.de/contact
10**
11**************************************************************************************/
12
13#pragma once
14
15#include <ThirdPartyWarningsDisable.h>
16
17#include <Inventor/nodes/SoShape.h>
18#include <Inventor/fields/SoSFBool.h>
19#include <Inventor/fields/SoSFVec3f.h>
20#include <Inventor/fields/SoSFFloat.h>
21#include <Inventor/fields/SoSFDouble.h>
22#include <Inventor/fields/SoSFColor.h>
23#include <Inventor/fields/SoSFEnum.h>
24#include <Inventor/fields/SoSFNode.h>
25
26#include <SoSFMLImage.h>
27#include <SoSFMLBase.h>
28
29#include <ThirdPartyWarningsRestore.h>
30
31#include <sstream>
32#include <iostream>
33
34namespace
35{
36
37 inline float sign(float number)
38 {
39 return (number < 0) ? -1.f : 1.f;
40 }
41
42}
43
45{
46 CoordinateAxis(const SbVec3f& worldStart, const SbVec3f& worldEnd, const std::string& label, int logicalDirection) :
47 label(label),
49 {
51
53 }
54
55 void setWorldPositions(const SbVec3f& start, const SbVec3f& end)
56 {
57 worldStart = start;
58 worldEnd = end;
59 worldDirection = end - start;
60 worldLength = worldDirection.length();
61 worldDirection.normalize();
62
64 }
65
66 void setScreenPositions(const SbVec3f& start, const SbVec3f& end)
67 {
68 screenStart = start;
69 screenEnd = end;
70 screenDirection = end - start;
71 screenDirection.normalize();
72 }
73
74 std::string label;
75
77
78 SbVec3f worldStart;
79 SbVec3f worldEnd;
82
83 SbVec3f screenStart;
84 SbVec3f screenEnd;
86
89
92};
93
95{
97 {
98 fontSize = 10.f;
99 textColor.setValue(1, 1, 1);
100 textAlpha = 1.f;
101 useTextShadow = true;
102 textShadowColor.setValue(0, 0, 0);
103 }
104
105 std::string text;
106
109
110 float fontSize;
111
112 SbColor textColor;
114
117};
118
119struct Label
120{
122 {
124 }
125
127 {
128 screenBoundingBox[0].setValue(FLT_MAX, FLT_MAX);
129 screenBoundingBox[1].setValue(FLT_MAX, FLT_MAX);
130 isVisible = true;
131 isOnScreen = false;
132 }
133
134 bool overlaps(const Label& otherLabel) const
135 {
136 const auto margin = 3.0f;
137
138 const auto ax0 = screenBoundingBox[0][0] - margin;
139 const auto ay0 = screenBoundingBox[0][1] - margin;
140 const auto ax1 = screenBoundingBox[1][0] + margin;
141 const auto ay1 = screenBoundingBox[1][1] + margin;
142
143 const auto bx0 = otherLabel.screenBoundingBox[0][0] - margin;
144 const auto by0 = otherLabel.screenBoundingBox[0][1] - margin;
145 const auto bx1 = otherLabel.screenBoundingBox[1][0] + margin;
146 const auto by1 = otherLabel.screenBoundingBox[1][1] + margin;
147
148 const auto awidth = abs(ax0 - ax1);
149 const auto aheight = abs(ay0 - ay1);
150
151 const auto bwidth = abs(bx0 - bx1);
152 const auto bheight = abs(by0 - by1);
153
154 return (abs((ax0 + awidth / 2) - (bx0 + bwidth / 2)) * 2 < (awidth + bwidth)) &&
155 (abs((ay0 + aheight / 2) - (by0 + bheight / 2)) * 2 < (aheight + bheight));
156 }
157
160 SbColor tickColor;
162
166
168};
169
170class SoCoordinateSystem : public SoShape
171{
172 SO_NODE_HEADER(SoCoordinateSystem);
173
174public:
175
176 static void initClass();
177
179
181 {
182 AUTO = 0,
183 USER = 1
184 };
185
193
200
201 SoSFTypedEnum<StrideMode> strideMode;
202 SoSFDouble userStride;
203
204 SoSFTypedEnum<EndTickMode> endTickMode;
205
206 SoSFColor axisColor;
207 SoSFFloat axisAlpha;
208
209 SoSFColor tickColor;
210 SoSFFloat tickAlpha;
211
214
218
221
222 SoSFFloat fontSize;
223
227
229 SoSFNode inNode;
230 SoSFVec3f userScale;
231 SoSFVec3f userTranslate;
232 SoSFTypedEnum<UserTransformMode> userTransformMode;
233
234protected:
235
237
238private:
239 std::vector<CoordinateAxis> axes;
240 int _maxZAxisIndex;
241
242 void initializeAxes();
243 void applyUserTransform();
244
245 void computeScreenCoordinates(CoordinateAxis& axis);
246 void computeAndSetTickDirections();
247 SbVec2f computeTextShiftFactorVector(int axisIndex);
248 float computeTextShiftFactor(float angle0, float angle1);
249 void computeAndSetLabelVisibility(std::vector<Label>& labels);
250
251 float getTickScale();
252 int getEndTickModifier(int numTicks, float length);
253
254 double getStride();
255 double getAutoStride(float maxRange);
256 double getUserStride(float maxRange);
257 float getMaxAxisRange();
258
259 bool anyLabelOverlap(const std::vector<Label>& labels);
260 void generatePrimitives(SoAction *) override {}
261
262 void GLRender(SoGLRenderAction *action) override;
263 void glRenderTicks();
264 void glRenderAxisLines();
265 void glRenderOrigin();
266
267 void computeBBox(SoAction *action, SbBox3f &box, SbVec3f &center) override;
268
269
270 void updateAxes(SoField*);
271
272 void updateFromInputInventorScene();
273 void updateFromInputImage();
274
275 SbVec3f getImageExtent();
276 SbMatrix getImageVoxelToWorldMatrix();
277 float getScaleForLogicalDirection(const CoordinateAxis& axis);
278
279 void message(const std::string& messageText) const
280 {
281 std::cout << messageText << std::endl;
282 }
283};
static void initClass()
SoSFTypedEnum< EndTickMode > endTickMode
SoSFTypedEnum< UserTransformMode > userTransformMode
SoSFTypedEnum< StrideMode > strideMode
~SoCoordinateSystem() override
The SoSFMLImage field is the interface used by Inventor Nodes to access image data (in the current im...
Definition SoSFMLImage.h:70
void setWorldPositions(const SbVec3f &start, const SbVec3f &end)
void setScreenPositions(const SbVec3f &start, const SbVec3f &end)
CoordinateAxis(const SbVec3f &worldStart, const SbVec3f &worldEnd, const std::string &label, int logicalDirection)
float renderLengthForArrowPlacement
SbVec2f textShiftFactorScreen
std::string text
SbColor textShadowColor
SbVec3f tickDirection
void initializeScreenBoundingBox()
LabelText labelText
SbColor tickColor
SbVec3f tickPosition
bool overlaps(const Label &otherLabel) const
SbVec2f screenBoundingBox[2]