MeVisLab Toolbox Reference
SoCSOLabelRenderer.h
Go to the documentation of this file.
1 /*************************************************************************************
2 **
3 ** Copyright 2012, 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 
15 
16 #pragma once
17 
19 #include "CSOLabelPlacement.h"
20 #include <set>
21 
22 ML_START_NAMESPACE
23 class CSOLabelRenderer;
24 ML_END_NAMESPACE
25 
27 
30 {
31  NotHit = 0,
32  N,
33  E,
34  S,
35  W,
36  NE,
37  NW,
38  SE,
39  SW
40 };
41 
43 
46 {
47  SO_NODE_HEADER(SoCSOLabelRenderer);
48 
49 public:
52 protected:
54  ~SoCSOLabelRenderer() override;
55 
56 public:
57 
58 
60  void setVisibleCSOs(const std::vector<CSODrawCSOInfos>& drawCSOInformation,
61  const CSODrawView2DInfos& view2DInfos, SoView2DCSOExtensibleEditor* editor ) override;
62 
64  void draw(const CSODrawCSOInfos& csoInfos, const CSODrawView2DInfos& view2DInfos, const CSODrawSliceInformation& drawSliceInfo, SoView2DCSOExtensibleEditor* editor) override;
65  void drawSecondPass(const CSODrawCSOInfos& csoInfos, const CSODrawView2DInfos& view2DInfos, const CSODrawSliceInformation& drawSliceInfo, SoView2DCSOExtensibleEditor* editor) override;
66  void drawOverlay(const CSODrawCSOInfos& csoInfos, const CSODrawView2DInfos& view2DInfos, const CSODrawSliceInformation& drawSliceInfo, SoView2DCSOExtensibleEditor* editor) override;
67 
69  static void initClass();
70 
71  bool isModificationEditor() const override { return true; }
72 
75 
76  SoPointingAction* labelMoveEndPress(ml::CSO* cso, int clickCount);
77 
79  void labelResizeDragMoveTo(ml::CSO* cso, const SoPointerPosition& pos, int resizeHandlerCode);
80 
82 
83  // just overload the methods below since we do not work
84  // with the standard actions
85  void createStartPressAt(const SoPointerPosition&) override {}
86  void createDragMoveTo(const SoPointerPosition&) override {}
87  bool createEndPress(int ) override { return false; }
89 
91  void selectAndMoveDragMoveTo(const SoPointerPosition&) override {}
92  SoPointingAction* selectAndMoveEndPress(int ) override {return nullptr; }
93 
94  void pointerPosition(const SoPointerPosition& pos) override;
95  void pointerLeftWindow() override;
96 
97  int cursorShape() const override { return SoViewerProxy::DEFAULT_CURSOR; }
98 
103 
104  bool shouldRenderGeneral(ml::CSO*) const override { return true; }
105 
106  void startDrawing(View2DSliceList* slicelist) override;
107 
109  ml::CSO* getLabelCSO(const std::string& currentViewerId, const SoPointerPosition& pos);
110 
112  ml::CSO* getHitResizeHandler(const std::string& currentViewerId, const SoPointerPosition& pos, int& resizeHandlerCode);
113 
115  void setOuterModule(ml::CSOLabelRenderer* labelRendererModule) { _labelRendererModule = labelRendererModule; }
116 
119 
121  void resetCache() override;
122 
125 
128 
155  SoSFTrigger repaintTrigger;
157  SoSFInt32 fontSize;
158 
165 
167 
169  SoSFInt32 inputInfoCSOId;
171  SoSFString inputInfoViewerId;
172 
188 
189 
192 
193  SoSFEnum scaleNCursor;
194  SoSFEnum scaleNWCursor;
195  SoSFEnum scaleWCursor;
196  SoSFEnum scaleSWCursor;
197  SoSFEnum scaleSCursor;
198  SoSFEnum scaleSECursor;
199  SoSFEnum scaleECursor;
200  SoSFEnum scaleNECursor;
201 
202 
203 private:
204 
206  ml::CSOLabelRenderer* _labelRendererModule;
207 
209  struct DeviceOffset
210  {
211  DeviceOffset() { xOffset = yOffset = 0; }
212  int xOffset;
213  int yOffset;
214  };
215 
217  std::map < int, std::string > _csoLabelStrings;
219  std::map < int, std::string > _csoLabelNames;
221  std::map < int, std::string > _csoLabelCaptions;
223  std::map < int, DeviceOffset > _csoDeviceOffsets;
225  std::map < int, bool > _shouldRenderLabel;
226 
228  std::multimap < std::string, CSOLabelRenderInformation > _viewerLabelRenderInformation;
230  void filterCSOLabelsForLayout(const std::vector<CSODrawCSOInfos>& drawCSOInfos,
231  const CSODrawView2DInfos& view2DInfos, SoView2DCSOExtensibleEditor* editor,
232  std::vector<CSODrawCSOInfos>& filteredDrawCSOInfos);
235  void clearInternalStructures();
237  void buildAllLabelStringsThatNeedUpdate(ml::CSOList* csoList);
239  void prepareLabel(const CSODrawCSOInfos& csoInfos, const CSODrawView2DInfos& view2DInfos, const CSODrawSliceInformation& drawSliceInfo, SoView2DCSOExtensibleEditor* editor);
241  bool getLabelRenderInformation(const std::string& viewerId, ml::CSO* cso, CSOLabelRenderInformation& labelRenderInfo);
243  bool getLabelRenderInformation(const std::string& viewerId, unsigned int csoId, CSOLabelRenderInformation& labelRenderInfo);
244 
247  void removeLabelRenderInformation(const std::string& viewerId, ml::CSO* cso);
249  void removeAllLabelRenderInformationForCSOId(int id, bool removeAll=false);
251  void cacheLabelRenderInformation(const std::string& viewerId, const CSOLabelRenderInformation& renderInfo);
253  bool isHit(const CSOLabelRenderInformation& labelRenderInfo, const SoPointerPosition& pos) const;
254  bool isHit(const CSOLabelRenderInformation& labelRenderInfo, float deviceX, float deviceY) const;
256  bool shouldRenderBecauseOfSliceAlignment(const CSODrawSliceInformation& drawSliceInfo);
258  bool isCSOGhosting(const CSODrawSliceInformation& drawSliceInfo);
259 
265  void buildLabelString(ml::CSO* cso);
267  void drawLabelBorder(const CSODrawCSOInfos& csoInfos, const CSODrawSliceInformation& drawSliceInfo, const SbVec2f& upperLeft, const SbVec2f& size);
269  void drawResizeHandlers(const SbVec2f& upperLeft, const SbVec2f& size);
271  void drawLabelName(const CSODrawCSOInfos& csoInfos, const CSODrawView2DInfos& view2DInfos, float fontColor[4], const std::string& labelName);
273  void drawLabelCSOConnectingLine(const CSODrawCSOInfos& csoInfos, const CSODrawView2DInfos& view2DInfos, const CSODrawSliceInformation& drawSliceInfo,
274  const SbVec2f& upperLeft, const SbVec2f& size);
275 
277  void computeConnectingLineCSOPosition(const CSODrawCSOInfos& csoInfos, const CSODrawView2DInfos& view2DInfos, const CSODrawSliceInformation& drawSliceInfo,
278  const SbVec2f& labelMidPoint, float& lineX1, float& lineY1);
279 
281  bool isMouseOverLabelOrCSOForInteraction(ml::CSO* cso);
283  bool isMouseOverLabelOrCSOForHighlighting(ml::CSO* cso);
284 
285 
288  void getCSOPoints( const CSODrawCSOInfos& csoInfos, std::vector< ml::Vector3 >& csoPoints );
289 
291  void ensureLabelIsVisible(View2DSlice* slice, SbVec2f& labelUpperLeft, SbVec2f& labelSize);
293  bool isLabelInsideViewer(View2DSlice* slice, SbVec2f& labelUpperLeft, SbVec2f& labelSize);
295  float fitFontSizeToBox(const CSOLabelRenderInformation& labelRenderInformation, const std::string& labelString, float originalFontSize);
296 
298  void moveLabelRelative(const std::string& viewerId, ml::CSO* cso, const SoPointerPosition& pos, const SbVec2f& relativeMovementOffset);
299 
301  void setLabelRelative(const std::string& viewerId, ml::CSO* cso, const SbVec2f relativePosition);
303  SbVec2f getRelativePositionOfCSOInViewer(const std::string& viewerId, ml::CSO* cso);
305  float getResizeDelta( const SbVec2f& currentDevicePosition, int resizeHandlerCode );
307  void drawGLRectangle(const SbVec2f& upperLeft, const SbVec2f& lowerRight, float offset=0, float lineWidth=1) const;
309  bool isInRectangle(const SbVec2f& rectUpperLeft, const SbVec2f& rectLowerRight, const SbVec2f& position) const;
310 
312  float distance(float x0, float y0, float x1, float y1) const;
314  void clipLineToRectangle(float& lineX0, float& lineY0, float& lineX1, float& lineY1, float rectMinX, float rectMinY, float rectMaxX, float rectMaxY) const;
316  int outcode(float lineX, float lineY, float rectMinX, float rectMinY, float rectMaxX, float rectMaxY) const;
317 
319  void getLabelSize(float fontSize, const std::string& labelString, int& labelWidth, int& labelHeight);
322  float getFontSize(ml::CSO* cso, SoView2D* viewer);
324  void setFontSize(ml::CSO* cso, SoView2D* viewer, float fontSize);
325 
327  void computeLabelBoxes(const std::vector<CSODrawCSOInfos>& filteredDrawCSOInfos, const CSODrawView2DInfos& view2DInfos, std::map < int, SbVec2f >& labelBoxes);
329  void getLabelBoxForCSO( ml::CSO* cso, const CSODrawView2DInfos& view2DInfos, int& labelWidth, int& labelHeight );
330 
332  View2DSlice* getCurrentSlice(const SoPointerPosition& pos);
333 
335  ml::CSOLabelPlacement* getLabelPlacement();
336 
337 
339  void getDetachedLabelPosition( const CSODrawCSOInfos& csoInfos, const CSODrawView2DInfos& view2DInfos, float& deviceX, float& deviceY );
341  SbVec2f computeNewDetachedLabelPositionWhileInteracting( const SbVec2f& lastRelativeLabelPosition, const SbVec2f& relativeMovementOffset, const CSOLabelRenderInformation& labelRenderInfo, ml::CSO* cso, View2DSlice* slice );
343  ml::Vector3 getDeviceAnchorPosition(ml::CSO* cso);
344 
347  void getFreePosition(float& deviceX, float& deviceY, const std::string& viewerId, float labelWidth, float labelHeight, View2DSlice* slice);
349  bool boundingBoxesIntersect(const CSOLabelRenderInformation& labelRenderInfo, float deviceX, float deviceY, float labelWidth, float labelHeight);
351  static void baseEventCB(void* userData, ml::BaseEvent* event);
354  bool needsUpdate(ml::CSO* cso);
357  void attachAsListenerTo(ml::CSOList* csoList);
359  static std::string getViewerId(const SoPointerPosition& pos);
360 
362  bool shouldRenderLabelString(unsigned int csoId, const std::string& viewerId);
364  SbBox2f getLabelDeviceRect(const CSOLabelRenderInformation& labelRenderInfo) const;
365 
367  ml::CSOList* _listenToCSOList;
369  std::set<int> _needsUpdateCSOIds;
370 
372  SbVec2f _startDragDevicePosition;
374  SbVec2f _startDragOffsetToCenter;
376  SbVec2f _currentFrameUpperLeft;
378  SbVec2f _currentFrameLowerRight;
380  SbVec2f _relativeLabelPosition;
382  ml::CSO* _csoLabelUnderMouseForInteraction;
384  ml::CSO* _csoLabelUnderMouseForHighlighting;
385 
387  float _minimumFontSize;
389  float _maximumFontSize;
390 
392  ml::CSOLabelPlacement _labelPlacement;
393 
394  friend class ml::CSOLabelPlacement;
395 };
396 
ResizeHotSpot
Enumeration of hot spots for resizing the label.
@ NotHit
#define SOCSO_EXPORT
Header file for system independent resolution.
Definition: SoCSOSystem.h:21
Base class for an editor extension for the SoView2DCSOExtensibleEditor.
Extension for rendering labels for CSOs.
int cursorShape() const override
Returns the cursor shape that indicates the next creation.
SoPointingAction * labelResizeEndPress(ml::CSO *cso, int clickCount)
void setVisibleCSOs(const std::vector< CSODrawCSOInfos > &drawCSOInformation, const CSODrawView2DInfos &view2DInfos, SoView2DCSOExtensibleEditor *editor) override
Set information about all the CSOs that are to be rendered.
void labelResizeStartPressAt(ml::CSO *cso, const SoPointerPosition &pos)
SoPointingAction * labelMoveEndPress(ml::CSO *cso, int clickCount)
SoSFEnum viewerBorderHandling
Handling of labels that move over the viewer's border.
SoSFString outputInfoLabelCaption
Output of the label's caption.
void drawOverlay(const CSODrawCSOInfos &csoInfos, const CSODrawView2DInfos &view2DInfos, const CSODrawSliceInformation &drawSliceInfo, SoView2DCSOExtensibleEditor *editor) override
Routine for drawing after the main routine has drawn.
void selectAndMoveStartPressAt(const SoPointerPosition &) override
void labelMoveStartPressAt(ml::CSO *cso, const SoPointerPosition &pos)
SoSFBool shouldDrawResizeHandlers
Shall resize handlers be drawn?
void createStartPressAt(const SoPointerPosition &) override
SoSFBool outputInfoIsValid
Flag to indicate whether the output info is valid.
ml::CSO * getLabelCSO(const std::string &currentViewerId, const SoPointerPosition &pos)
Returns the pointer to a CSO whose label is on the given viewer under the given position.
SoSFInt32 labelBorderMarginY
Sets the inner margin of the label border in y-direction.
bool createEndPress(int) override
void setLabelUnderMouseForHighlighting(ml::CSO *cso)
Sets the label for the given CSO as being under the mouse for highlighting.
void labelMoveDragMoveTo(ml::CSO *cso, const SoPointerPosition &pos)
void pointerPosition(const SoPointerPosition &pos) override
Is called when the mouse moves over a viewer.
~SoCSOLabelRenderer() override
Destructor.
bool isModificationEditor() const override
Returns whether the editor is a modification editor.
SoSFTrigger repaintTrigger
Just a dummy field to trigger a repaint.
SoSFInt32 labelBorderMarginX
Sets the inner margin of the label border in x-direction.
void drawSecondPass(const CSODrawCSOInfos &csoInfos, const CSODrawView2DInfos &view2DInfos, const CSODrawSliceInformation &drawSliceInfo, SoView2DCSOExtensibleEditor *editor) override
Drawing routine that comes between 'main' and 'overlay'.
static void initClass()
init class in inventor runtime
SoSFEnum detachedLabelPlacement
Positioning strategy for detached (manually moved) labels.
void createDragMoveTo(const SoPointerPosition &) override
ml::CSO * getHitResizeHandler(const std::string &currentViewerId, const SoPointerPosition &pos, int &resizeHandlerCode)
Returns the pointer to a CSO whose label is on the given viewer under the given position....
void computeOutputInformation()
Fills output information fields for a CSO on a viewer.
SoSFInt32 minConnectingLineLength
The minimum length of a connecting line to get drawn (in pixel).
SoSFVec2f outputInfoLabelBoundingBoxStart
Output of the upper left corner of the label's bounding box.
void labelResizeDragMoveTo(ml::CSO *cso, const SoPointerPosition &pos, int resizeHandlerCode)
SoSFMLBase inLabelPlacement
Option input of label placement.
SoSFBool shouldRenderLabelName
Shall the label name be rendered at the CSO when the label has been moved away?
SoSFVec2f outputInfoLabelBoundingBoxEnd
Output of the lower right corner of the label's bounding box.
SoSFBool shouldDrawConnectingLine
Shall a connecting line between the label and the CSO be drawn?
SoCSOLabelRenderer()
Standard constructor.
void pointerLeftWindow() override
Is called when mouse pointer leaves the window.
SoSFFloat connectingLineAlpha
Global alpha factor that is multiplied to the local alpha factor of connecting lines.
SoSFBool shouldShowLabelStringOfOutputInfoLabel
Should the label string be hidden for the label.
SoSFBool allowLabelResize
Shall the user be allowed to resize a label?
SoSFInt32 fontSize
Sets the font size of the text.
void setOuterModule(ml::CSOLabelRenderer *labelRendererModule)
Sets a pointer to the 'outer' module.
SoSFInt32 outputInfoLabelCaptionWidth
Output of the x-offset value of the label's string.
SoSFBool tryToPlaceLabelsWithoutOverlap
Should the renderer attempt to place a label without overlapping other labels?
SoPointingAction * selectAndMoveEndPress(int) override
SoSFBool drawLabelBorderForSelectedCSO
Shall a border be drawn around the label of a selected CSO?
void selectAndMoveDragMoveTo(const SoPointerPosition &) override
void resetCache() override
Resets the internal label string cache.
SoSFString inputInfoViewerId
Input of the viewer id string.
void pointerPositionIfAllowedAt(const SoPointerPosition &) override
Sets seed points while moving the mouse – but not while dragging.
void updateStringsInCache()
Updates all label strings in the cache.
SoSFBool drawConnectingLineToCenterOfCSO
Shall the connecting line be drawn to th center of a CSO? Or to the nearest point on the CSO?
void setLabelUnderMouseForInteraction(ml::CSO *cso)
Sets the label for the given CSO as being under the mouse for interaction (select,...
void startDrawing(View2DSliceList *slicelist) override
Is called before drawing.
SoSFBool shouldHighlightBorderOnMouseOver
Shall the label's border be highlighted on mouse over?
void draw(const CSODrawCSOInfos &csoInfos, const CSODrawView2DInfos &view2DInfos, const CSODrawSliceInformation &drawSliceInfo, SoView2DCSOExtensibleEditor *editor) override
Drawing routine.
bool shouldRenderGeneral(ml::CSO *) const override
Returns whether a given CSO should be rendered by this general extension.
SoSFInt32 inputInfoCSOId
Trade interface for retrieving the device position (and other information) of a label on a certain vi...
SoSFString outputInfoLabelString
Output of the label's string.
SoPointerPosition manages the current position of the mouse cursor.
SoPointingAction is the base class for any mouse based interaction.
The SoSFMLBase field is the interface used by Inventor Nodes to output ML Base objects to the outside...
Definition: SoSFMLBase.h:45
SoView2D is a 2D viewer for image data.
Definition: SoView2D.h:62
a list that holds all View2DSlice objects (lazily created) of a SoView2D
a single slice that is stored in a View2DSliceList, typically created by a View2DSliceList
Definition: View2DSlice.h:48
BaseEvent is the base class for all events emitted from EventSourceBase.
Definition: mlEventSource.h:86
Base module for providing custom label placement strategies.
Module encapsulation the SoView2D extension for rendering labels for CSOs.
A CSOList comprises a number of CSOs and CSOGroups and is the central object for contour segmentation...
Definition: CSOList.h:61
The CSO represents a contour segmentation object.
Definition: CSO.h:44
Structure to store render information for a certain CSO and viewer.
Definition: SoCSODefines.h:147