1 /* -------------------------------------------------------------------------- *
2  *             Simbody(tm) Adhoc test: Look at polygonal mesh                 *
3  * -------------------------------------------------------------------------- *
4  * This is part of the SimTK biosimulation toolkit originating from           *
5  * Simbios, the NIH National Center for Physics-Based Simulation of           *
6  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
7  * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody.  *
8  *                                                                            *
9  * Portions copyright (c) 2014 Stanford University and the Authors.           *
10  * Authors: Michael Sherman                                                   *
11  * Contributors:                                                              *
12  *                                                                            *
13  * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
14  * not use this file except in compliance with the License. You may obtain a  *
15  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
16  *                                                                            *
17  * Unless required by applicable law or agreed to in writing, software        *
18  * distributed under the License is distributed on an "AS IS" BASIS,          *
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
20  * See the License for the specific language governing permissions and        *
21  * limitations under the License.                                             *
22  * -------------------------------------------------------------------------- */
23 
24 /*                      Simbody LookAtPolygonalMesh
25 Utility that exercises PolygonalMesh's load-from-file methods and then
26 displays the resulting mesh in the visualizer. It will also try to turn
27 the mesh into ContactGeometry and report any problems that occur. */
28 
29 #include "Simbody.h"
30 
31 #include <cassert>
32 #include <iostream>
33 using std::cout; using std::endl;
34 
35 using namespace SimTK;
36 
37 class ShowMesh : public DecorationGenerator {
38 public:
ShowMesh()39     ShowMesh() {}
40 
41     // This is a shallow reference to the supplied mesh.
setMesh(const PolygonalMesh & mesh)42     void setMesh(const PolygonalMesh& mesh) {m_mesh=mesh;}
43 
generateDecorations(const State & state,Array_<DecorativeGeometry> & geometry)44     void generateDecorations(const State&                state,
45                              Array_<DecorativeGeometry>& geometry) override
46     {
47         const Real TextScale = 0.1;
48         DecorativeText info; info.setIsScreenText(true);
49         info.setText("Faces/vertices: " + String(m_mesh.getNumFaces())
50                      + "/" + String(m_mesh.getNumVertices()));
51         geometry.push_back(info);
52         if (!m_mesh.getNumFaces())
53             return;
54 
55         DecorativeMesh dmesh(m_mesh);
56         geometry.push_back(DecorativeMesh(dmesh)
57                            .setOpacity(.8).setColor(Cyan));
58         geometry.push_back(DecorativeMesh(dmesh)
59                            .setRepresentation(DecorativeGeometry::DrawWireframe)
60                            .setLineThickness(3)
61                            .setColor(Black));
62     }
63 private:
64     PolygonalMesh m_mesh;
65 };
66 
main()67 int main() {
68   try {
69     // Create a system containing only Ground.
70     MultibodySystem system;
71     SimbodyMatterSubsystem matter(system);
72 
73     system.setUseUniformBackground(true); // no ground plane in display
74     system.realizeTopology();
75 
76     Visualizer viz(system);
77     viz.setCameraClippingPlanes(.01, 100);
78     ShowMesh* sp = new ShowMesh();
79     viz.addDecorationGenerator(sp);
80     viz.report(system.getDefaultState()); // show default shape
81 
82     // The Visualizer caches meshes by their addresses so won't update
83     // properly if memory gets reused in a modified mesh. Since there's a
84     // human in the loop here we can just keep all the meshes around until
85     // termination; that way there is no danger of reuse.
86     Array_<PolygonalMesh> meshes;
87     meshes.push_back(PolygonalMesh::createSphereMesh(1.,3));
88     sp->setMesh(meshes.back());
89     viz.report(system.getDefaultState());
90     viz.zoomCameraToShowAllGeometry();
91 
92 
93     std::string line, cwd = Pathname::getCurrentWorkingDirectory();
94     std::cout << "Current working directory: " << cwd << std::endl;
95     std::cout << "Change working directory (ENTER to keep): ";
96     std::getline(std::cin, line);
97     if (!line.empty()) cwd = line;
98 
99     while(true) {
100         viz.report(system.getDefaultState());
101         viz.zoomCameraToShowAllGeometry();
102 
103         meshes.push_back(); // make a new empty mesh
104         PolygonalMesh& mesh = meshes.back();
105 
106         printf("mesh file name (or 'end'): ");
107         std::getline(std::cin, line);
108         if (line=="end")
109             break;
110 
111         std::string dir,fn,ext;
112         bool isAbsolutePath;
113         Pathname::deconstructPathname(line,isAbsolutePath,dir,fn,ext);
114         if (!isAbsolutePath) line = cwd + "/" + line;
115 
116         if (!Pathname::fileExists(line)) {
117             if (!line.empty()) printf("'%s' doesn't exist\n", line.c_str());
118             sp->setMesh(mesh);
119             continue;
120         }
121 
122         try {
123             mesh.loadFile(line);
124         } catch(const std::exception& e) {
125             cout << "File loader error: " << e.what() << "\n";
126             mesh.clear();
127         }
128         sp->setMesh(mesh);
129 
130         try {
131             ContactGeometry::TriangleMesh tri(mesh);
132             printf("*** Works as contact mesh! ***\n");
133         } catch(const std::exception& e) {
134             cout << "XXX Can't make contact mesh: " << e.what() << "\n";
135         }
136     }
137 
138   } catch (const std::exception& e) {
139     cout << "EXCEPTION: " << e.what() << "\n";
140   }
141 }
142