I have written a function that reads an obj. file and converts the strings into floats. The code worked fine untill the stof() function stops working properly. I'm not sure how this part suddenly stops working since it seems such a straight-forward thing to do and it has worked everytime untill now.
ftemp = std::stof(stemp);
ftemp and stemp (storage for float and string) are declared at the beginning of my function and are overwritten for each number. I use fstream and iterators to find the numbers. The rest of the code is easy to imagine and works as expected so I'll ommit everything but the failing part.
this is in the .obj file and should represent a textured plane.
# Blender v2.68 (sub 0) OBJ File: ''
# www.blender.org
v -1.000000 1.000000 -1.000000
v 1.000000 1.000000 -1.000000
v -1.000000 1.000000 1.000000
v 1.000000 1.000000 1.000000
vt 0.000100 0.000100
vt 0.999900 0.000100
vt 0.000100 0.999900
vt 0.999900 0.999900
s off
f 2/1 1/2 4/3
f 1/2 3/4 4/3
It fails at the point it reads the vt lines. So when stemp holds "0.000100" ftemp should hold 0.000100 yet it holds: 9.9999997e-005. The rest works the same way and does it correctly.
Any help would be greatly appreciated.
It's correct. IEEE754 for single precision which float implements, guarantees accuracy up to around 7 significant digits.
9.9999997e-005 is 0.00000999999997 so its close enough.
Related
I heard that, in Fortran77, all local variables in a function are created at the beginning of the main program execution and exist during the whole runtime, rather than being created on entry to the function and being destroyed on exit. I do not know whether this is still true in newer Fortran. Is there any way that can test this out?
One test that meight help is to check whether variables retain their values between invocations. Here is a simple test:
program main
call p()
call p()
call p()
end program main
subroutine p()
real :: a(3)
a=a+1
write(*,*) a(1), a(2), a(3)
end subroutine p
My test using gfortran indicates array a retains its values between invocations, the same behavior as save attribute being used.
I am wondering whether this is a standard in Fortran Language or depends on compiler implementations.
Such a test cannot prove anything. The fact that some garbage remains in the stack between two function invocations can be a pure coincidence.
Local function variables are only valid during the function invocation in which their value was defined. That is also true in Fortran 77. If the value should be retained, the variables hhave to be declared SAVE.
Just for fun, we can try a program where some other routine (e.g.foo()) may be called between successive calls of p():
program main
call p()
! call foo() ! (*)
call p()
! call foo() ! (*)
call p()
end
subroutine p()
real :: a(3)
a = a + 1
write(*,*) "a = ", a
end
subroutine foo()
real :: b(3)
b = b * 10
write(*,*) "b = ", b
end
With the lines (*) commented, we get
! gfortran-8.2
a = 1.00000000 4.74066630E+21 1.00000000
a = 2.00000000 4.74066630E+21 2.00000000
a = 3.00000000 4.74066630E+21 3.00000000
! PGI18.10
a = 1.000000 1.000000 1.000000
a = 2.000000 2.000000 2.000000
a = 3.000000 3.000000 3.000000
while with the lines (*) uncommented, we get
! gfortran-8.2
a = 1.00000000 4.74066630E+21 1.00000000
b = 10.0000000 4.74066641E+22 10.0000000
a = 11.0000000 4.74066641E+22 11.0000000
b = 110.000000 4.74066623E+23 110.000000
a = 111.000000 4.74066623E+23 111.000000
! PGI18.10
a = 1.000000 1.000000 1.000000
b = 0.000000 0.000000 0.000000
a = 2.000000 2.000000 2.000000
b = 0.000000 0.000000 0.000000
a = 3.000000 3.000000 3.000000
(This is just an experiment/illustration of the behavior of local variables (i.e. not necessarily "SAVE-ed" as it might appear in a simpler case), and please see the other answer and comments for detailed explanations.)
I have been using Assimp for a while and now I'm trying to load a .obj file. It loads perfectly, but I would like to manipulate the face data after loading it.
Basically I have this in the simple cube.obj file (Full file - http://pastebin.com/ha3VkZPM)
# 8 Vertices
v -1.0 -0.003248 1.0
v 1.0 -0.003248 1.0
v -1.0 1.996752 1.0
v 1.0 1.996752 1.0
v 1.0 -0.003248 -1.0
v -1.0 -0.003248 -1.0
v 1.0 1.996752 -1.0
v -1.0 1.996752 -1.0
# 36 Texture Coordinates
vt 1.0 0.0
vt 0.0 0.0
...
# 36 Vertex Normals
vn 0.0 0.0 1.0
vn 0.0 0.0 1.0
...
f 1/1/1 2/2/2 3/3/3
f 2/4/4 4/5/5 3/6/6
f 5/7/7 6/8/8 7/9/9
f 6/10/10 8/11/11 7/12/12
f 3/13/13 6/14/14 1/15/15
f 3/16/16 8/17/17 6/18/18
f 7/19/19 2/20/20 5/21/21
f 7/22/22 4/23/23 2/24/24
f 3/25/25 7/26/26 8/27/27
f 3/28/28 4/29/29 7/30/30
f 2/31/31 6/32/32 5/33/33
f 2/34/34 1/35/35 6/36/36
And as I understand face entry is V/T/N (Vertex indicies, tex coord indices and normal indices).
so
f 1/1/1 2/2/2 3/3/3 represents a triangle of vertices (1,2,3) - right?
From this face entry - I want to extract only the vertex indices.
Now enters Assimp - I have this now - Where Indices is a stl::vector
for (uint32 i = 0; i < pMesh->mNumFaces; i++) {
const aiFace& Face = pMesh->mFaces[i];
if(Face.mNumIndices == 3) {
Indices.push_back(Face.mIndices[0]);
Indices.push_back(Face.mIndices[1]);
Indices.push_back(Face.mIndices[2]);
}
Here are the values of pMesh->mNumFace = 12 - So thats correct.
(for 1st face)
Face.mindices[0] should probably point to 1/1/1
Face.mindices[1] should probably point to 2/2/2
Face.mindices[2] should probably point to 3/3/3
Now how do I extract only the vertex indices? And when I check the values of Face.mIndices[0] its index as 0,1,2...respectively. Why so? Assimp Faces all have indices (0,1,2)
I searched on Google and StackOverflow - here are some similar question but I cant seem to figure it out.
https://stackoverflow.com/questions/32788756/how-to-keep-vertex-order-from-obj-file-using-assimp-library
Assimp and D3D model loading: Mesh not being displayed in D3D
Assimp not properly loading indices
Please let me know if you need more info. Thanks.
OpenGL and DirectX use a slightly different way of indexing vertex data then the obj format does. In contrast to the file format where it is possible to use different indices for positions/texcoords etc, the graphic card requires one single index buffer for the whole vertex.
That beeing said: Assimp passes the obj format and transforms it into a single-index-buffer representation. Basically this means, that each unique vertex-texcoord-normal combination will give one vertex while the indexbuffer points to this new vertex list.
As far as I know, it is not possible to access the original indices using Assimp.
I need to import a 3D object mesh into my OpenGL code on Visual Studio 2010. I'm relateively new to OpenGL so I've been learning from the following tutorial (Number 7):
http://www.opengl-tutorial.org/beginners-tutorials/tutorial-7-model-loading/
Now, the tutorial uses a simple code rather than a library to import ".obj" files
Those who've used the tutorial will know that the "cube.obj" that has been provided by the creator of the tutorial works just fine.
However, the moment I try loading my own simple cube mesh, the program notifies me that "Our simple parser cannot handle the .obj file. Please try exporting with other options".
I figured this to be a problem with the code and moved on to his Assimp tutorial:
http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-9-vbo-indexing/
This time around, "Suzanne.obj" has been provided as a sample. Yet again, whenever I try exporting my own object into the code, the program now crashes saying "Visual Studio has stopped working". This only occurs with the objects I export.
In an attempt to narrow down the cause of the problem, I used the "cube.obj" provided in Tutorial 7 with Tutorial 9, and it worked just fine. So it seems for now as though the issue lies in the export of the object from Blender.
I've followed all the instructions in Tutorial 7 regarding to what options need be checked while exporting objects. It is worth noting however, the ".obj" code of the objects I export appear in a single line without any line breaks. This is the obj code of a simple cube mesh I exported:
# Blender v2.73 (sub 0) OBJ File: 'ROOM.blend'
# www.blender.org
mtllib room.mtl
o Cube_Cube.004
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
v 1.000000 1.000000 -1.000000
v 1.000000 1.000000 1.000000
vn -1.000000 0.000000 0.000000
vn 0.000000 0.000000 -1.000000
vn 1.000000 0.000000 0.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 1.000000 0.000000
usemtl None
s off
f 6//1 2//1 1//1
f 7//2 3//2 2//2
f 8//3 4//3 3//3
f 5//4 1//4 4//4
f 2//5 3//5 4//5
f 7//6 6//6 5//6
f 5//1 6//1 1//1
f 6//2 7//2 2//2
f 7//3 8//3 3//3
f 8//4 5//4 4//4
f 1//5 2//5 4//5
f 8//6 7//6 5//6
The .obj code of the cube provided in the tutorial in comparison is as follows:
# Blender3D v249 OBJ File: untitled.blend
# www.blender3d.org
mtllib cube.mtl
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -1.000000
v 0.999999 1.000000 1.000001
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
vt 0.748573 0.750412
vt 0.749279 0.501284
vt 0.999110 0.501077
vt 0.999455 0.750380
vt 0.250471 0.500702
vt 0.249682 0.749677
vt 0.001085 0.750380
vt 0.001517 0.499994
vt 0.499422 0.500239
vt 0.500149 0.750166
vt 0.748355 0.998230
vt 0.500193 0.998728
vt 0.498993 0.250415
vt 0.748953 0.250920
vn 0.000000 0.000000 -1.000000
vn -1.000000 -0.000000 -0.000000
vn -0.000000 -0.000000 1.000000
vn -0.000001 0.000000 1.000000
vn 1.000000 -0.000000 0.000000
vn 1.000000 0.000000 0.000001
vn 0.000000 1.000000 -0.000000
vn -0.000000 -1.000000 0.000000
usemtl Material_ray.png
s off
f 5/1/1 1/2/1 4/3/1
f 5/1/1 4/3/1 8/4/1
f 3/5/2 7/6/2 8/7/2
f 3/5/2 8/7/2 4/8/2
f 2/9/3 6/10/3 3/5/3
f 6/10/4 7/6/4 3/5/4
f 1/2/5 5/1/5 2/9/5
f 5/1/6 6/10/6 2/9/6
f 5/1/7 8/11/7 6/10/7
f 8/11/7 7/12/7 6/10/7
f 1/2/8 2/9/8 3/13/8
f 1/2/8 3/13/8 4/14/8
On debugging the crashed program, the following exception occurs:
Unhandled exception at 0x00007FF76255E2D5 in tutorial09_AssImp.exe:
0xC0000005: Access violation reading location 0x0000000000000000.
The call stack is as follows:
tutorial09_AssImp.exe!aiVector3t::aiVector3t(const aiVector3t & o) Line 67 C++
tutorial09_AssImp.exe!loadAssImp(const char * path,
std::vector > & indices,
std::vector,std::allocator
& vertices, std::vector,std::allocator
& uvs, std::vector,std::allocator
& normals) Line 149 C++ tutorial09_AssImp.exe!main() Line 92 C++
Moreover, the exception occurs in vector3.h which looks as so:
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2012, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/** #file aiVector3D.h
* #brief 3D vector structure, including operators when compiling in C++
*/
#ifndef AI_VECTOR3D_H_INC
#define AI_VECTOR3D_H_INC
#include <math.h>
#include "./Compiler/pushpack1.h"
#ifdef __cplusplus
template<typename TReal> class aiMatrix3x3t;
template<typename TReal> class aiMatrix4x4t;
// ---------------------------------------------------------------------------
/** Represents a three-dimensional vector. */
template <typename TReal>
class aiVector3t
{
public:
aiVector3t () : x(), y(), z() {}
aiVector3t (TReal _x, TReal _y, TReal _z) : x(_x), y(_y), z(_z) {}
explicit aiVector3t (TReal _xyz) : x(_xyz), y(_xyz), z(_xyz) {}
aiVector3t (const aiVector3t& o) : x(o.x), y(o.y), z(o.z) {} //exception generated here
public:
// combined operators
const aiVector3t& operator += (const aiVector3t& o);
const aiVector3t& operator -= (const aiVector3t& o);
const aiVector3t& operator *= (TReal f);
const aiVector3t& operator /= (TReal f);
// transform vector by matrix
aiVector3t& operator *= (const aiMatrix3x3t<TReal>& mat);
aiVector3t& operator *= (const aiMatrix4x4t<TReal>& mat);
// access a single element
TReal operator[](unsigned int i) const;
TReal& operator[](unsigned int i);
// comparison
bool operator== (const aiVector3t& other) const;
bool operator!= (const aiVector3t& other) const;
template <typename TOther>
operator aiVector3t<TOther> () const;
public:
/** #brief Set the components of a vector
* #param pX X component
* #param pY Y component
* #param pZ Z component */
void Set( TReal pX, TReal pY, TReal pZ);
/** #brief Get the squared length of the vector
* #return Square length */
TReal SquareLength() const;
/** #brief Get the length of the vector
* #return length */
TReal Length() const;
/** #brief Normalize the vector */
aiVector3t& Normalize();
/** #brief Componentwise multiplication of two vectors
*
* Note that vec*vec yields the dot product.
* #param o Second factor */
const aiVector3t SymMul(const aiVector3t& o);
TReal x, y, z;
} PACK_STRUCT;
typedef aiVector3t<float> aiVector3D;
#else
struct aiVector3D {
float x,y,z;
} PACK_STRUCT;
#endif // __cplusplus
#include "./Compiler/poppack1.h"
#ifdef __cplusplus
#endif // __cplusplus
#endif // AI_VECTOR3D_H_INC
Apparently I'm not doing something right while exporting my models. What could I possible be doing wrong? Is there a step I'm missing?
The program crashes at line 149 of objloader.cpp (says the callstack)
This line is about UV coordinates.
You model doesn't have any, which should ring a bell =)
You will have the same problem with normals, btw.
So, you have 2 options :
Make the object have UVs and normals
Make the loader support meshes without UVs or normals.
Since you'll need them anyway, I'd recommend the first one.
In Blender :
For the UVs, go to edit mode, select all vertices ('A' key), mesh->UVs->automatic unwrap ; If you struggle, Tutorial 15 contains a video which shows everything you need.
For normals, just tick the "export normals" option when exporting to OBJ.
In any case, the output OBJ must have v (position), vn (normals), vt (UVs) and f (connectivity between the 'v's )
EDIT : Explanation on why the top of the callstack talks about aiVector3Dt :
line 148 is
aiVector3D UVW = mesh->mTextureCoords[0][i];
UVW is a copy of mesh->mTextureCoords[0][i], which doesn't point to a valid place in memory, because the buffer wasn't allocated, because your OBJ doesn't have any. So the constructor (in the callstack : aiVector3Dt::aiVector3Dt() ) crashes when trying to copy this memory block to UVW. There's a small difference here, because the crash happens one line later, but it's just a compiler optimization. So, the code of aiVector3D is perfectly correct, but you're giving him a bad adress. You can see this in the debugger by setting the current frame to loadAssImp(), and spy on mesh->mTextureCoords[0].
I am using opencv library in c++ for matrix inversion. I use the function invert with DECOMP_SVD flag. For matrices which are not singular, it computes using SVD method.
However it gives me an incorrect answer for singular matrices (determinant = 0) when I compare it to the output in Matlab for the same inversion.
The answer is off by a margin of 1e+4!
The methods I have used in matlab is pinv() and svd().
pinv() uses moore-Penrose method.
Need help
Thanks in advance!
Example :
original =
0.2667 0.0667 -1.3333 2.2222
0.0667 0.0667 -0.0000 0.8889
-1.3333 -0.0000 8.8889 -8.8889
2.2222 0.8889 -8.8889 20.7408
Inverse from matlab =
1.0e+04 *
9.8888 -0.0000 0.7417 -0.7417
-0.0000 9.8888 -0.7417 -0.7417
0.7417 -0.7417 0.1113 0.0000
-0.7417 -0.7417 0.0000 0.1113
Your matrix is ill-conditioned (weak main diagonal).
Try to increase the main diagonal elements, and, I think, the error should decrease.
I am making an OBJ importer and I happen to be stuck on how to construct the mesh from a set of given vertices. Consider a cube with these vertices (OBJ format, faces are triangles:
v -2.767533 -0.000000 2.927381
v 3.017295 -0.000000 2.927381
v -2.767533 6.311718 2.927381
v 3.017295 6.311718 2.927381
v -2.767533 6.311718 -2.845727
v 3.017295 6.311718 -2.845727
v -2.767533 -0.000000 -2.845727
v 3.017295 -0.000000 -2.845727
I know how to construct meshes using GLUT (to make my calls to GlBegin(GL_TRIANGLES), glVertex3f(x, y, z), glEnd(), etc.) Its just that I don't know how to combine the vertices to recreate the object. I thought it was to go v1, v2, v3, then v2, v3, v4, etc. until I have made enough triangles (and something like v7, v8, v1 (because it goes back to the begining)) counts. So 8 vertices is 12 triangles for the cube, and for, say, a sphere with 108 triangles and 56 vertices is (56 vertices * 2) - 4. For a cube, I make the 12 triangles, its ok but for a sphere, I make the 108 triangles with 56 vertices, it does not work. So how do I combine the vertices in my glVertex calls to make it work for any mesh? Thank you!
There should be a bunch of "face" lines in the file (lines beginning with the letter "f") that tell you how to combine the vertices into an object. For example,
f 1 2 3
would mean a triangle composed of the first three vertices in the file. You might also see something like
f 1/1 2/2 3/3
which is a triangle that also includes texture coordinates,
f 1//1 2//2 3//3
which includes vertex normal vectors, or
f 1/1/1 2/2/2 3/3/3
which is one that includes both.
Wikipedia has an article that includes an overview of the format: https://en.wikipedia.org/wiki/Wavefront_.obj_file