PeriDyno 1.2.1
Loading...
Searching...
No Matches
tinyobj_helper.cpp
Go to the documentation of this file.
1#include "tinyobj_helper.h"
2
3#include "ImageLoader.h"
4
5#define TINYOBJLOADER_IMPLEMENTATION
6#include <tinyobjloader/tiny_obj_loader.h>
7
8namespace dyno
9{
10 bool loadTextureMeshFromObj(std::shared_ptr<TextureMesh> texMesh, const FilePath& fullname, bool useToCenter)
11 {
12 tinyobj::attrib_t attrib;
13 std::vector<tinyobj::shape_t> shapes;
14 std::vector<tinyobj::material_t> materials;
15 std::string err, warn;
16
17 auto name = fullname;
18 auto root = name.path().parent_path();
19
20 bool result = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
21 name.string().c_str(), root.string().c_str());
22
23 if (!err.empty()) {
24 std::cerr << err << std::endl;
25 return false;
26 }
27
28 if (!warn.empty()) {
29 std::cerr << warn << std::endl;
30 }
31
32 std::vector<dyno::Vec3f> vertices;
33 std::vector<dyno::Vec3f> normals;
34 std::vector<dyno::Vec2f> texCoords;
35 std::vector<dyno::uint> shapeIds;
36
37 std::vector<dyno::Vec3i> pIndex;
38 std::vector<dyno::Vec3i> nIndex;
39 std::vector<dyno::Vec3i> tIndex;
40
41 for (int i = 0; i < attrib.vertices.size(); i += 3) {
42 vertices.push_back({ attrib.vertices[i], attrib.vertices[i + 1], attrib.vertices[i + 2] });
43 }
44
45 for (int i = 0; i < attrib.normals.size(); i += 3) {
46 normals.push_back({ attrib.normals[i], attrib.normals[i + 1], attrib.normals[i + 2] });
47 }
48
49 for (int i = 0; i < attrib.texcoords.size(); i += 2) {
50 texCoords.push_back({ attrib.texcoords[i], attrib.texcoords[i + 1] });
51 }
52
53 shapeIds.resize(vertices.size());
54 texMesh->shapeIds().reset();
55 // load texture...
56 dyno::CArray2D<dyno::Vec4f> texture(1, 1);
57 texture[0, 0] = dyno::Vec4f(1);
58
59 auto& tMats = texMesh->materials();
60 tMats.resize(materials.size());
61
62 uint mId = 0;
63 for (const auto& mtl : materials) {
64 tMats[mId] = std::make_shared<Material>();
65 //tMats[mId]->ambient = { mtl.ambient[0], mtl.ambient[1], mtl.ambient[2] };
66 //tMats[mId]->diffuse = { mtl.diffuse[0], mtl.diffuse[1], mtl.diffuse[2] };
67 //tMats[mId]->specular = { mtl.specular[0], mtl.specular[1], mtl.specular[2] };
68 //tMats[mId]->roughness = 1.0f - mtl.shininess;
69 tMats[mId]->baseColor = { mtl.diffuse[0], mtl.diffuse[1], mtl.diffuse[2] };
70
71 std::shared_ptr<ImageLoader> loader = std::make_shared<ImageLoader>();
72
73 if (!mtl.diffuse_texname.empty())
74 {
75 auto tex_path = (root / mtl.diffuse_texname).string();
76
77 if (loader->loadImage(tex_path.c_str(), texture))
78 {
79 tMats[mId]->texColor.assign(texture);
80 }
81 }
82 if (!mtl.bump_texname.empty())
83 {
84 auto tex_path = (root / mtl.bump_texname).string();
85
86 if (loader->loadImage(tex_path.c_str(), texture))
87 {
88 tMats[mId]->texBump.assign(texture);
89 auto texOpt = mtl.bump_texopt;
90 tMats[mId]->bumpScale = texOpt.bump_multiplier;
91 }
92 }
93
94 mId++;
95 }
96
97
98 auto& tShapes = texMesh->shapes();
99 tShapes.resize(shapes.size());
100
101 uint sId = 0;
102
103 for (const tinyobj::shape_t& shape : shapes) {
104 // only load triangle mesh...
105 const auto& mesh = shape.mesh;
106 tShapes[sId] = std::make_shared<Shape>();
107 std::vector<TopologyModule::Triangle> vertexIndex;
108 std::vector<TopologyModule::Triangle> normalIndex;
109 std::vector<TopologyModule::Triangle> texCoordIndex;
110
111 if (mesh.material_ids.size() > 0 && mesh.material_ids[0] >= 0)
112 {
113 tShapes[sId]->material = tMats[mesh.material_ids[0]];
114 }
115
116 Vec3f lo = Vec3f(REAL_MAX);
117 Vec3f hi = Vec3f(-REAL_MAX);
118 for (int i = 0; i < mesh.indices.size(); i += 3) {
119 auto idx0 = mesh.indices[i];
120 auto idx1 = mesh.indices[i + 1];
121 auto idx2 = mesh.indices[i + 2];
122
123 vertexIndex.push_back({ idx0.vertex_index, idx1.vertex_index, idx2.vertex_index });
124 normalIndex.push_back({ idx0.normal_index, idx1.normal_index, idx2.normal_index });
125 texCoordIndex.push_back({ idx0.texcoord_index, idx1.texcoord_index, idx2.texcoord_index });
126
127 lo = lo.minimum(vertices[idx0.vertex_index]);
128 lo = lo.minimum(vertices[idx1.vertex_index]);
129 lo = lo.minimum(vertices[idx2.vertex_index]);
130
131 hi = hi.maximum(vertices[idx0.vertex_index]);
132 hi = hi.maximum(vertices[idx1.vertex_index]);
133 hi = hi.maximum(vertices[idx2.vertex_index]);
134
135 shapeIds[idx0.vertex_index] = sId;
136 shapeIds[idx1.vertex_index] = sId;
137 shapeIds[idx2.vertex_index] = sId;
138
139 }
140 tShapes[sId]->vertexIndex.assign(vertexIndex);
141 tShapes[sId]->normalIndex.assign(normalIndex);
142 tShapes[sId]->texCoordIndex.assign(texCoordIndex);
143
144 auto shapeCenter = (lo + hi) / 2;
145 tShapes[sId]->boundingBox = TAlignedBox3D<Real>(lo, hi);
146 tShapes[sId]->boundingTransform = Transform3f(shapeCenter, Quat1f().toMatrix3x3());
147
148
149 //Move to center
150 if (useToCenter)
151 {
152 std::vector<int> indicator(vertices.size(), 0);
153 for (int i = 0; i < mesh.indices.size(); i += 3)
154 {
155 auto idx0 = mesh.indices[i];
156 auto idx1 = mesh.indices[i + 1];
157 auto idx2 = mesh.indices[i + 2];
158
159 if (indicator[idx0.vertex_index] == 0)
160 {
161 vertices[idx0.vertex_index] -= shapeCenter;
162 indicator[idx0.vertex_index] = 1;
163 }
164 if (indicator[idx1.vertex_index] == 0)
165 {
166 vertices[idx1.vertex_index] -= shapeCenter;
167 indicator[idx1.vertex_index] = 1;
168 }
169 if (indicator[idx2.vertex_index] == 0)
170 {
171 vertices[idx2.vertex_index] -= shapeCenter;
172 indicator[idx2.vertex_index] = 1;
173 }
174 }
175 }
176
177
178 vertexIndex.clear();
179 normalIndex.clear();
180 texCoordIndex.clear();
181
182 sId++;
183 }
184
185 texMesh->vertices().assign(vertices);
186 texMesh->normals().assign(normals);
187 texMesh->texCoords().assign(texCoords);
188 texMesh->shapeIds().assign(shapeIds);
189
190 //A hack: for an obj file with one shape
191 if (shapes.size() == 1)
192 {
193 texMesh->shapeIds().resize(vertices.size());
194 texMesh->shapeIds().reset();
195 }
196
197 vertices.clear();
198 normals.clear();
199 texCoords.clear();
200
201 return true;
202 }
203
204
205 bool loadObj(std::vector<Vec3f>& points, std::vector<TopologyModule::Triangle>& triangles, std::string filename, bool append)
206 {
207 if (!append)
208 {
209 points.clear();
210 triangles.clear();
211 }
212 int offset = append ? points.size() : 0;
213
214 tinyobj::attrib_t myattrib;
215 std::vector <tinyobj::shape_t> myshape;
216 std::vector <tinyobj::material_t> mymat;
217 std::string mywarn;
218 std::string myerr;
219
220 char* fname = (char*)filename.c_str();
221 std::cout << fname << std::endl;
222 tinyobj::LoadObj(&myattrib, &myshape, &mymat, &mywarn, &myerr, fname, nullptr, true, true);
223 std::cout << mywarn << std::endl;
224 std::cout << myerr << std::endl;
225 std::cout << "************************ Loading : shapelod ************************ " << std::endl << std::endl;
226 std::cout << " " << " shape size =" << myshape.size() << std::endl << std::endl;
227 std::cout << "************************ Loading : v ************************ " << std::endl << std::endl;
228 std::cout << " " << " point sizelod = " << myattrib.GetVertices().size() / 3 << std::endl << std::endl;
229
230 if (myshape.size() == 0) { return false; }
231
232 for (int i = 0; i < myattrib.GetVertices().size() / 3; i++)
233 {
234 points.push_back(Vec3f(myattrib.GetVertices()[3 * i], myattrib.GetVertices()[3 * i + 1], myattrib.GetVertices()[3 * i + 2]));
235 }
236 std::cout << "************************ Loading : f ************************ " << std::endl << std::endl;
237 for (int i = 0; i < myshape.size(); i++)
238 {
239 std::cout << " " << " Triangle " << i << " size =" << myshape[i].mesh.indices.size() / 3 << std::endl << std::endl;
240
241 for (int s = 0; s < myshape[i].mesh.indices.size() / 3; s++)
242 {
243 //std::cout << myshape[i].mesh.indices[s].vertex_index <<" " << std::endl;
244
245 triangles.push_back(TopologyModule::Triangle(myshape[i].mesh.indices[3 * s].vertex_index + offset, myshape[i].mesh.indices[3 * s + 1].vertex_index + offset, myshape[i].mesh.indices[3 * s + 2].vertex_index + offset));
246 }
247 }
248 std::cout << "************************ Loading completed **********************" << std::endl << std::endl;
249 return true;
250
251 }
252
253}
fs::path & path()
Definition FilePath.h:17
Vector< PointType, 3 > Triangle
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
constexpr Real REAL_MAX
Definition Typedef.inl:45
bool loadTextureMeshFromObj(std::shared_ptr< TextureMesh > texMesh, const FilePath &fullname, bool useToCenter)
Array2D< T, DeviceType::CPU > CArray2D
Definition Array2D.h:131
bool loadObj(std::vector< Vec3f > &points, std::vector< TopologyModule::Triangle > &triangles, std::string filename, bool append)
Quat< float > Quat1f
Definition Quat.h:136
Vector< float, 4 > Vec4f
Definition Vector4D.h:86
Transform< float, 3 > Transform3f
Vector< float, 3 > Vec3f
Definition Vector3D.h:93
unsigned int uint
Definition VkProgram.h:14