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