1 /**************************************************************************\
2  * Copyright (c) Kongsberg Oil & Gas Technologies AS
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  *
12  * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * Neither the name of the copyright holder nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 \**************************************************************************/
32 
33 /*!
34   \class SoGetPrimitiveCountAction SoGetPrimitiveCountAction.h Inventor/actions/SoGetPrimitiveCountAction.h
35   \brief The SoGetPrimitiveCountAction class counts the primitives in a scene.
36 
37   \ingroup actions
38 
39   Apply this action to a scene if you need to know the number of
40   primitives present in a scenegraph, or parts of a scenegraph.
41 
42 
43   One common mistake to make when using this action is to think that
44   it traverses just the parts currently in view, like SoGLRenderAction
45   does. (SoGLRenderAction culls away the scenegraph parts outside the
46   camera view volume and does not traverse those.) Like most other
47   action classes, SoGetPrimitiveCountAction actually traverses the
48   complete scenegraph, not just the parts currently in view.
49 
50   \since Coin 1.0
51   \since TGS Inventor 2.5
52 */
53 
54 #include <Inventor/actions/SoGetPrimitiveCountAction.h>
55 
56 #include <Inventor/SbName.h>
57 #include <Inventor/lists/SoEnabledElementsList.h>
58 #include <Inventor/nodes/SoNode.h>
59 #include <Inventor/elements/SoDecimationPercentageElement.h>
60 #include <Inventor/elements/SoDecimationTypeElement.h>
61 #include <Inventor/elements/SoViewportRegionElement.h>
62 
63 #include "actions/SoSubActionP.h"
64 
65 class SoGetPrimitiveCountActionP {
66 public:
67   SbViewportRegion viewport;
68 };
69 
70 SO_ACTION_SOURCE(SoGetPrimitiveCountAction);
71 
72 
73 // Override from parent class.
74 void
initClass(void)75 SoGetPrimitiveCountAction::initClass(void)
76 {
77   SO_ACTION_INTERNAL_INIT_CLASS(SoGetPrimitiveCountAction, SoAction);
78 
79   SO_ENABLE(SoGetPrimitiveCountAction, SoDecimationPercentageElement);
80   SO_ENABLE(SoGetPrimitiveCountAction, SoDecimationTypeElement);
81   SO_ENABLE(SoGetPrimitiveCountAction, SoViewportRegionElement);
82 }
83 
84 /*!
85   Constructor.
86 */
SoGetPrimitiveCountAction()87 SoGetPrimitiveCountAction::SoGetPrimitiveCountAction()
88 {
89   this->commonConstructor(SbViewportRegion(640, 512));
90 }
91 
92 /*!
93   Constructor. Supply the current viewport region to make SCREEN_SPACE counting correct.
94 */
SoGetPrimitiveCountAction(const SbViewportRegion & vp)95 SoGetPrimitiveCountAction::SoGetPrimitiveCountAction(const SbViewportRegion & vp)
96 {
97   this->commonConstructor(vp);
98 }
99 
100 void
commonConstructor(const SbViewportRegion & vp)101 SoGetPrimitiveCountAction::commonConstructor(const SbViewportRegion & vp)
102 {
103   SO_ACTION_CONSTRUCTOR(SoGetPrimitiveCountAction);
104 
105   this->textastris = TRUE;
106   this->approx = FALSE;
107   this->nonvertexastris = TRUE;
108   this->pimpl->viewport = vp;
109 }
110 
111 /*!
112   The destructor.
113 */
~SoGetPrimitiveCountAction()114 SoGetPrimitiveCountAction::~SoGetPrimitiveCountAction()
115 {
116 }
117 
118 /*!
119   Returns number of triangles in graph.
120 */
121 int
getTriangleCount(void) const122 SoGetPrimitiveCountAction::getTriangleCount(void) const
123 {
124   return this->numtris;
125 }
126 
127 /*!
128   Returns number of lines in graph.
129 */
130 int
getLineCount(void) const131 SoGetPrimitiveCountAction::getLineCount(void) const
132 {
133   return this->numlines;
134 }
135 
136 /*!
137   Returns number of points in graph.
138 
139   Note that by "point", it is meant an actual point primitive (for
140   rendering), such as in the SoPointSet shape node, not a polygon
141   vertice. For counting the total number of polygon vertices in a
142   scene (sub) graph, use instead the SoCallbackAction with the
143   appropriate callback.
144 */
145 int
getPointCount(void) const146 SoGetPrimitiveCountAction::getPointCount(void) const
147 {
148   return this->numpoints;
149 }
150 
151 /*!
152   Returns number of texts in the graph.
153 */
154 int
getTextCount(void) const155 SoGetPrimitiveCountAction::getTextCount(void) const
156 {
157   return this->numtexts;
158 }
159 
160 /*!
161   Returns the number of images in the graph.
162 */
163 int
getImageCount(void) const164 SoGetPrimitiveCountAction::getImageCount(void) const
165 {
166   return this->numimages;
167 }
168 
169 /*!
170   Returns whether there are any primitives in graph or not.
171 */
172 SbBool
containsNoPrimitives(void)173 SoGetPrimitiveCountAction::containsNoPrimitives(void)
174 {
175   return
176     this->numtris == 0 &&
177     this->numlines == 0 &&
178     this->numpoints == 0 &&
179     this->numtexts == 0 &&
180     this->numimages == 0;
181 }
182 
183 /*!
184   Returns whether there are non-triangular primitives in graph.
185 */
186 SbBool
containsNonTriangleShapes(void)187 SoGetPrimitiveCountAction::containsNonTriangleShapes(void)
188 {
189   return
190     this->numlines != 0 ||
191     this->numpoints != 0 ||
192     this->numtexts != 0 ||
193     this->numimages != 0;
194 }
195 
196 /*!
197   Sets whether SoText3 nodes are counted as the triangles of the
198   fonts in the text strings or the text itself. The default is to
199   count as triangles.
200 
201   \sa is3DTextCountedAsTriangles()
202 */
203 void
setCount3DTextAsTriangles(const SbBool flag)204 SoGetPrimitiveCountAction::setCount3DTextAsTriangles(const SbBool flag)
205 {
206   this->textastris = flag;
207 }
208 
209 /*!
210   Returns whether SoText3 nodes is counted as triangles or text.
211 
212   \sa is3DTextCountedAsTriangles()
213 */
214 SbBool
is3DTextCountedAsTriangles(void)215 SoGetPrimitiveCountAction::is3DTextCountedAsTriangles(void)
216 {
217   return this->textastris;
218 }
219 
220 /*!
221   Returns whether shapes can use an approximate value when counting
222   primitives. This is faster than doing an accurate count.  The
223   default is to not approximate.
224 
225   \sa setCanApproximate()
226 */
227 SbBool
canApproximateCount(void)228 SoGetPrimitiveCountAction::canApproximateCount(void)
229 {
230   return this->approx;
231 }
232 
233 /*!
234   Sets whether shapes can do an approximate count.
235   \sa canApproximateCount()
236 */
237 void
setCanApproximate(const SbBool flag)238 SoGetPrimitiveCountAction::setCanApproximate(const SbBool flag)
239 {
240   this->approx = flag;
241 }
242 
243 /*!
244   Set up the decimation parameters for the traversal.
245 
246   On-the-fly decimation is supported in Coin yet, so this call will
247   not have any effect until this feature has been implemented.
248 */
249 void
setDecimationValue(SoDecimationTypeElement::Type type,float percentage)250 SoGetPrimitiveCountAction::setDecimationValue(SoDecimationTypeElement::Type type,
251                                               float percentage)
252 {
253   this->decimationtype = type;
254   this->decimationpercentage = percentage;
255 }
256 
257 /*!
258   Returns decimation type used during the traversal count.
259  */
260 SoDecimationTypeElement::Type
getDecimationType(void)261 SoGetPrimitiveCountAction::getDecimationType(void)
262 {
263   return this->decimationtype;
264 }
265 
266 /*!
267   Returns decimation percentage used during the traversal count.
268  */
269 float
getDecimationPercentage(void)270 SoGetPrimitiveCountAction::getDecimationPercentage(void)
271 {
272   return this->decimationpercentage;
273 }
274 
275 /*!
276   Adds \a num triangles to total count. Used by node instances in the
277   scene graph during traversal.
278 */
279 void
addNumTriangles(const int num)280 SoGetPrimitiveCountAction::addNumTriangles(const int num)
281 {
282   this->numtris += num;
283 }
284 
285 /*!
286   Adds \a num lines to total count. Used by node instances in the
287   scene graph during traversal.
288 */
289 void
addNumLines(const int num)290 SoGetPrimitiveCountAction::addNumLines(const int num)
291 {
292   this->numlines += num;
293 }
294 
295 /*!
296   Adds \a num points to total count. Used by node instances in the
297   scene graph during traversal.
298 */
299 void
addNumPoints(const int num)300 SoGetPrimitiveCountAction::addNumPoints(const int num)
301 {
302   this->numpoints += num;
303 }
304 
305 /*!
306   Adds \a num texts to total count. Used by node instances in the
307   scene graph during traversal.
308 */
309 void
addNumText(const int num)310 SoGetPrimitiveCountAction::addNumText(const int num)
311 {
312   this->numtexts += num;
313 }
314 
315 /*!
316   Adds \a num texture image maps to total count. Used by node
317   instances in the scene graph during traversal.
318 */
319 void
addNumImage(const int num)320 SoGetPrimitiveCountAction::addNumImage(const int num)
321 {
322   this->numimages += num;
323 }
324 
325 /*!
326   Adds a single triangle to the total count. Used by node instances in
327   the scene graph during traversal.
328 */
329 void
incNumTriangles(void)330 SoGetPrimitiveCountAction::incNumTriangles(void)
331 {
332   this->numtris++;
333 }
334 
335 /*!
336   Adds a single line to the total count. Used by node instances in the
337   scene graph during traversal.
338 */
339 void
incNumLines(void)340 SoGetPrimitiveCountAction::incNumLines(void)
341 {
342   this->numlines++;
343 }
344 
345 /*!
346   Adds a single point to the total count. Used by node instances in
347   the scene graph during traversal.
348 */
349 void
incNumPoints(void)350 SoGetPrimitiveCountAction::incNumPoints(void)
351 {
352   this->numpoints++;
353 }
354 
355 /*!
356   Adds a single text to the total count. Used by node instances in the
357   scene graph during traversal.
358 */
359 void
incNumText(void)360 SoGetPrimitiveCountAction::incNumText(void)
361 {
362   this->numtexts++;
363 }
364 
365 /*!
366   Adds a single texture image map to the total count. Used by node
367   instances in the scene graph during traversal.
368 */
369 void
incNumImage(void)370 SoGetPrimitiveCountAction::incNumImage(void)
371 {
372   this->numimages++;
373 }
374 
375 
376 // Documented in superclass. Overridden to reset all counters to zero
377 // before traversal starts.
378 void
beginTraversal(SoNode * node)379 SoGetPrimitiveCountAction::beginTraversal(SoNode * node)
380 {
381   this->numtris = 0;
382   this->numlines = 0;
383   this->numpoints = 0;
384   this->numtexts = 0;
385   this->numimages = 0;
386 
387   SoViewportRegionElement::set(state, this->pimpl->viewport);
388 
389 //  SoDecimationTypeElement::set(this->getState(), this->decimationtype);
390 //  SoDecimationPercentageElement::set(this->getState(), this->decimationpercentage);
391 
392   this->traverse(node);
393 }
394