MeVisLab Toolbox Reference
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 
34 namespace
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  {
50  isMaxPointingToScreenZ = false;
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;
80  SbVec3f worldDirection;
81  float worldLength;
82 
83  SbVec3f screenStart;
84  SbVec3f screenEnd;
85  SbVec3f screenDirection;
86 
87  SbVec3f tickDirection;
88  SbVec2f textScreenShift;
89 
92 };
93 
94 struct LabelText
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 
107  SbVec3f textPosition;
109 
110  float fontSize;
111 
112  SbColor textColor;
113  float textAlpha;
114 
117 };
118 
119 struct 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 
158  SbVec3f tickPosition;
159  SbVec3f tickDirection;
160  SbColor tickColor;
161  float tickAlpha;
162 
163  SbVec2f screenBoundingBox[2];
164  bool isVisible;
166 
168 };
169 
170 class SoCoordinateSystem : public SoShape
171 {
172  SO_NODE_HEADER(SoCoordinateSystem);
173 
174 public:
175 
176  static void initClass();
177 
179 
181  {
182  AUTO = 0,
183  USER = 1
184  };
185 
187  {
188  ROUND_UP = 0,
191  PRECISE = 3
192  };
193 
195  {
199  };
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 
212  SoSFColor numbersFontColor;
213  SoSFFloat numbersFontAlpha;
214 
215  SoSFColor lettersFontColor;
216  SoSFFloat lettersFontAlpha;
218 
219  SoSFBool useTextShadow;
220  SoSFColor textShadowColor;
221 
222  SoSFFloat fontSize;
223 
224  SoSFFloat arrowLengthFactor;
227 
229  SoSFNode inNode;
230  SoSFVec3f userScale;
231  SoSFVec3f userTranslate;
232  SoSFTypedEnum<UserTransformMode> userTransformMode;
233 
234 protected:
235 
237 
238 private:
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()
SoSFBool useVoxelAlignedBoundingBox
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
DT abs(DT val)
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
SbVec3f textPosition
SbColor textShadowColor
float tickAlpha
SbVec3f tickDirection
void initializeScreenBoundingBox()
LabelText labelText
SbColor tickColor
SbVec3f tickPosition
bool overlaps(const Label &otherLabel) const
SbVec2f screenBoundingBox[2]