1 /* OpenSceneGraph example, osgsimplifier.
2 *
3 *  Permission is hereby granted, free of charge, to any person obtaining a copy
4 *  of this software and associated documentation files (the "Software"), to deal
5 *  in the Software without restriction, including without limitation the rights
6 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 *  copies of the Software, and to permit persons to whom the Software is
8 *  furnished to do so, subject to the following conditions:
9 *
10 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16 *  THE SOFTWARE.
17 */
18 
19 #include <osgDB/ReadFile>
20 #include <osgDB/WriteFile>
21 
22 #include <osgUtil/Optimizer>
23 #include <osgUtil/Simplifier>
24 
25 #include <osgViewer/Viewer>
26 #include <osgViewer/ViewerEventHandlers>
27 
28 #include <osgGA/TrackballManipulator>
29 #include <osgGA/StateSetManipulator>
30 
31 #include <iostream>
32 
33 class KeyboardEventHandler : public osgGA::GUIEventHandler
34 {
35 public:
36 
KeyboardEventHandler(unsigned int & flag,const std::string & filename)37     KeyboardEventHandler(unsigned int& flag, const std::string& filename) :
38         _flag(flag),
39         _outputFilename(filename)
40     {}
41 
handle(const osgGA::GUIEventAdapter & ea,osgGA::GUIActionAdapter & aa)42     virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
43     {
44         switch(ea.getEventType())
45         {
46             case(osgGA::GUIEventAdapter::KEYDOWN):
47             {
48                 if (ea.getKey()=='n')
49                 {
50                     _flag = 1;
51                     return true;
52                 }
53                 if (ea.getKey()=='p')
54                 {
55                     _flag = 2;
56                     return true;
57                 }
58                 if (ea.getKey()=='o')
59                 {
60                     osgViewer::View* view = dynamic_cast<osgViewer::Viewer*>(aa.asView());
61                     osg::Node* sceneData = view ? view->getSceneData() : 0;
62                     if (sceneData)
63                     {
64                         OSG_NOTICE<<"Witten model to file: "<<_outputFilename<<std::endl;
65                         osgDB::writeNodeFile(*sceneData, _outputFilename);
66                     }
67                     return true;
68                 }
69                 break;
70             }
71             default:
72                 break;
73         }
74         return false;
75     }
76 
77 private:
78 
79     unsigned int& _flag;
80     std::string _outputFilename;
81 };
82 
83 
main(int argc,char ** argv)84 int main( int argc, char **argv )
85 {
86 
87     // use an ArgumentParser object to manage the program arguments.
88     osg::ArgumentParser arguments(&argc,argv);
89 
90     // set up the usage document, in case we need to print out how to use this program.
91     arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
92     arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" examples illustrates simplification of triangle meshes.");
93     arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
94     arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
95     arguments.getApplicationUsage()->addCommandLineOption("--ratio <ratio>","Specify the sample ratio","0.5]");
96     arguments.getApplicationUsage()->addCommandLineOption("--max-error <error>","Specify the maximum error","4.0");
97 
98 
99     std::string outputFilename="model.osgt";
100 
101     float sampleRatio = 0.5f;
102     float maxError = 4.0f;
103 
104     // construct the viewer.
105     osgViewer::Viewer viewer;
106 
107     // read the sample ratio if one is supplied
108     while (arguments.read("--ratio",sampleRatio)) {}
109     while (arguments.read("--max-error",maxError)) {}
110     while (arguments.read("-o",outputFilename)) {}
111 
112     // if user request help write it out to cout.
113     if (arguments.read("-h") || arguments.read("--help"))
114     {
115         arguments.getApplicationUsage()->write(std::cout);
116         return 1;
117     }
118 
119     if (arguments.argc()<=1)
120     {
121         arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
122         return 1;
123     }
124 
125     // read the scene from the list of file specified commandline args.
126     osg::ref_ptr<osg::Node> loadedModel = osgDB::readRefNodeFiles(arguments);
127 
128     // if not loaded assume no arguments passed in, try use default mode instead.
129     if (!loadedModel) loadedModel = osgDB::readRefNodeFile("dumptruck.osgt");
130 
131     // if no model has been successfully loaded report failure.
132     if (!loadedModel)
133     {
134         std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl;
135         return 1;
136     }
137 
138     //loadedModel->accept(simplifier);
139 
140     unsigned int keyFlag = 0;
141     viewer.addEventHandler(new KeyboardEventHandler(keyFlag, outputFilename));
142 
143     // add the state manipulator
144     viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
145 
146     // add the window size toggle handler
147     viewer.addEventHandler(new osgViewer::WindowSizeHandler);
148 
149     // add the stats handler
150     viewer.addEventHandler(new osgViewer::StatsHandler);
151 
152     viewer.setCameraManipulator(new osgGA::TrackballManipulator());
153 
154     // set the scene to render
155     viewer.setSceneData(loadedModel.get());
156 
157     // create the windows and run the threads.
158     viewer.realize();
159 
160     float multiplier = 0.8f;
161     float minRatio = 0.001f;
162     float ratio = sampleRatio;
163 
164 
165     while( !viewer.done() )
166     {
167         // fire off the cull and draw traversals of the scene.
168         viewer.frame();
169 
170         if (keyFlag == 1 || keyFlag == 2)
171         {
172             if (keyFlag == 1) ratio *= multiplier;
173             if (keyFlag == 2) ratio /= multiplier;
174             if (ratio<minRatio) ratio=minRatio;
175 
176             osgUtil::Simplifier simplifier(ratio, maxError);
177 
178             std::cout<<"Running osgUtil::Simplifier with SampleRatio="<<ratio<<" maxError="<<maxError<<" ...";
179             std::cout.flush();
180 
181             osg::ref_ptr<osg::Node> root = (osg::Node*)loadedModel->clone(osg::CopyOp::DEEP_COPY_ALL);
182 
183             root->accept(simplifier);
184 
185             std::cout<<"done"<<std::endl;
186 
187             viewer.setSceneData(root.get());
188             keyFlag = 0;
189         }
190     }
191 
192     return 0;
193 }
194 
195