ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
cvConstrainedContourRepresentation.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
9 
10 #include <vtkActor2D.h>
11 #include <vtkMath.h>
12 #include <vtkObjectFactory.h>
13 #include <vtkPoints.h>
14 #include <vtkPolyData.h>
15 #include <vtkRenderer.h>
16 #include <vtkTextActor.h>
17 #include <vtkTextProperty.h>
18 
20 
21 //----------------------------------------------------------------------------
23  : LabelSuffix(nullptr), ShowLabel(1) {
24  // Create the label actor
25  this->LabelActor = vtkSmartPointer<vtkTextActor>::New();
26 
27  // Configure label text properties
28  vtkTextProperty* textProp = this->LabelActor->GetTextProperty();
29  textProp->SetFontSize(20);
30  textProp->SetBold(1);
31  textProp->SetColor(1.0, 1.0, 1.0); // White text
32  textProp->SetShadow(1);
33  textProp->SetJustificationToCentered();
34  textProp->SetVerticalJustificationToCentered();
35 
36  // Default label text
37  this->LabelActor->SetInput("Contour");
38 
39  // Initially visible
40  this->LabelActor->SetVisibility(1);
41 }
42 
43 //----------------------------------------------------------------------------
45  // Remove label actor from renderer before destruction
46  if (this->Renderer && this->LabelActor) {
47  this->Renderer->RemoveActor2D(this->LabelActor);
48  }
49 
50  if (this->LabelSuffix) {
51  delete[] this->LabelSuffix;
52  this->LabelSuffix = nullptr;
53  }
54 }
55 
56 //----------------------------------------------------------------------------
58  if (this->LabelSuffix) {
59  delete[] this->LabelSuffix;
60  this->LabelSuffix = nullptr;
61  }
62 
63  if (suffix) {
64  size_t len = strlen(suffix);
65  this->LabelSuffix = new char[len + 1];
66  strcpy(this->LabelSuffix, suffix);
67  }
68 
69  this->UpdateLabel();
70  this->Modified();
71 }
72 
73 //----------------------------------------------------------------------------
75  return this->LabelSuffix;
76 }
77 
78 //----------------------------------------------------------------------------
80  if (this->ShowLabel != show) {
81  this->ShowLabel = show;
82  if (this->LabelActor) {
83  this->LabelActor->SetVisibility(show && this->GetVisibility());
84  }
85  this->Modified();
86  }
87 }
88 
89 //----------------------------------------------------------------------------
91  // Remove from old renderer
92  if (this->Renderer && this->LabelActor) {
93  this->Renderer->RemoveActor2D(this->LabelActor);
94  }
95 
96  // Call parent
97  this->Superclass::SetRenderer(ren);
98 
99  // Add to new renderer
100  if (this->Renderer && this->LabelActor) {
101  this->Renderer->AddActor2D(this->LabelActor);
102  }
103 }
104 
105 //----------------------------------------------------------------------------
107  // Call parent
108  this->Superclass::SetVisibility(visible);
109 
110  // Control label visibility
111  if (this->LabelActor) {
112  this->LabelActor->SetVisibility(visible && this->ShowLabel);
113  }
114 }
115 
116 //----------------------------------------------------------------------------
118  // Call parent to build contour representation
119  this->Superclass::BuildRepresentation();
120 
121  // Update label position and text
122  this->UpdateLabel();
123 }
124 
125 //----------------------------------------------------------------------------
127  if (!this->LabelActor) {
128  return;
129  }
130 
131  // Update label text
132  std::string labelText = "Contour";
133  if (this->LabelSuffix) {
134  labelText += " ";
135  labelText += this->LabelSuffix;
136  }
137  this->LabelActor->SetInput(labelText.c_str());
138 
139  // Calculate label position (centroid of contour nodes)
140  int numNodes = this->GetNumberOfNodes();
141  if (numNodes > 0 && this->Renderer) {
142  double centroid[3] = {0.0, 0.0, 0.0};
143 
144  // Calculate centroid in world coordinates
145  for (int i = 0; i < numNodes; ++i) {
146  double pos[3];
147  this->GetNthNodeWorldPosition(i, pos);
148  centroid[0] += pos[0];
149  centroid[1] += pos[1];
150  centroid[2] += pos[2];
151  }
152 
153  centroid[0] /= numNodes;
154  centroid[1] /= numNodes;
155  centroid[2] /= numNodes;
156 
157  // Convert world coordinates to display coordinates
158  this->Renderer->SetWorldPoint(centroid[0], centroid[1], centroid[2],
159  1.0);
160  this->Renderer->WorldToDisplay();
161  double* displayCoord = this->Renderer->GetDisplayPoint();
162 
163  // Position label slightly above the centroid
164  this->LabelActor->SetPosition(displayCoord[0], displayCoord[1] + 20);
165  } else {
166  // No nodes yet - position at default location
167  this->LabelActor->SetPosition(50, 50);
168  }
169 }
Extended contour representation with instance label support.
const char * GetLabelSuffix() const
Get the current label suffix.
void SetShowLabel(int show)
Show or hide the instance label.
void SetRenderer(vtkRenderer *ren) override
Set the renderer (override to add label actor)
void UpdateLabel()
Update the label text and position.
void SetLabelSuffix(const char *suffix)
Set the label suffix to identify this contour instance.
void BuildRepresentation() override
Build the representation (override to update label position)
void SetVisibility(vtkTypeBool visible) override
Set visibility (override to control label visibility)
vtkStandardNewMacro(cvConstrainedContourRepresentation)