How to set the color of a face using OpenMesh? - c++

I'm trying to just set the face color of a certain face and my code keeps throwing an error.
The line mesh.set_color(*f_it, clr); is throwing an error (something about a property error). I've tried changing it to mesh.set_color(f_it.handle(), clr); but that throws a dereferencing error.
Am I going about setting the color correctly?
typedef OpenMesh::TriMesh_ArrayKernelT<> myMesh;
myMesh * Mesh;
myMesh mesh;
void computeFaceNormals(myMesh mesh) {
OpenMesh::Vec3f pointA, pointB, pointC;
myMesh::VertexIter vlt, vBegin, vEnd;
myMesh::ConstFaceVertexIter cfvlt;
myMesh::Color clr;
for (myMesh::FaceIter f_it = mesh.faces_begin(); f_it != mesh.faces_end(); f_it++) {
cfvlt = mesh.cfv_iter(*f_it);
pointA = mesh.point(*cfvlt);
pointB = mesh.point((*cfvlt++));
pointC = mesh.point((*cfvlt++));
clr[0] = 0;
clr[1] = 1;
clr[2] = 0;
mesh.set_color(*f_it, clr);
}
}

The openmesh Mesh (OpenMesh::TriMesh_ArrayKernelT) can work with different properties: vertex-colors, face-colors, vertex-normals and so on. But you need to specify explicitly the properties that you want the Mesh to have.
In your case, what you are missing is a
mesh.request_face_colors();
If you receive the mesh as an argument, you can check whether it already has a color proterty with:
mesh.has_face_colors()
You can also remove properties using:
mesh.release_face_colors();
Read the tutorial for more details. An important note you should consider (from the tutorial) that clarifies the usage of request/has/release:
But, what happens if for example the vertex status property has been
requested twice? Then the first release does nothing, but the second
one will remove it. The standard properties have a reference counter,
which is incremented by one for each request and decremented by one
for each release. If the counter reaches 0 the property will be
removed from memory.

Related

Weird artefact while rotating mesh uvs

I created a Unity sphere and applied standard material with albedo texture. Now I'm trying to rotate mesh uvs (it looks like this is the simpliest way to rotate the texture)
Here is the code
using UnityEngine;
public class GameController : MonoBehaviour
{
public GameObject player;
public float rotationValue;
void Start ()
{
Mesh mesh = player.GetComponent<MeshFilter>().mesh;
Vector2[] uvs = mesh.uv;
mesh.uv = changeUvs(uvs);
}
private Vector2[] changeUvs (Vector2[] originalUvs)
{
for (int i = 0; i < originalUvs.Length; i++)
{
originalUvs[i].x = originalUvs[i].x + rotationValue;
if (originalUvs[i].x > 1)
{
originalUvs[i].x = originalUvs[i].x - 1f;
}
}
return originalUvs;
}
}
This gives me this strange artifact. What am I doing wrong?
It can't be done the way you're trying to do it. Even if you go outside the [0,1] range as pleluron suggests there will be a line on the sphere where the texture interpolates from high to low, and you get the entire texture in a single band as you see now.
The way the original sphere solves the problem is by having a seam that is duplicated. One version has x 0 and the other one has x 1. You don't see it because the vertices are at the same location. If you want to solve the problem with uv trickery then the only option is to move the seam, which involves creating a new mesh.
Actually the simplest way to rotate the planet is by leaving the texture alone and just rotate the object! If this for some reason is not an option then go into the material and find the tiling and offset. If you're using the standard shader then make sure you use the top one, just below the emission checkbox. If you modify that X you get the effect you're trying to create with the script you posted.

DirectX 9 not rendering after adding transforms

so far I got a cube rendered without any transforms (thus it was rendered in an orthographic perspective), and I am working on the previous code to get it into a perspective view, with all the matrices involved. I changed the Flexible Vertex Format so as not to have RHW (thus only having XYZ coordinates and color, tried ARGB and XRGB but I don't think it matters), and I added a function that sets all the matrices.
Debugging
showed that matrices are being created correctly, functions return correctly (as far as I could see), no crashes (DirectX will never complain if something goes wrong, it just doesn't render) and in general, step-by-step debugging shows no paranormal activity.
Existing project (which I modify and eventually prevent from working):
As I advance I also write tutorials of sorts so I can go back and see what I did last time to get it to work, and this time I've kept versions so you can get the code here along with the VS2010 solution, all the DirectX work is done in 3Dheader.h and D3DLoader.h
Changes:
- the custom vertex format FVF_CUSTOMVERTEX has been changed so as not to include RHW, as I understand it has to be removed so as to be computed through the transformations
- In Render() I add a call to the function setMatrices() which does all the matrix and transform work, and is as follows:
void setMatrices()
{
//--------------transformation code----------------//
D3DXMATRIX objectM, translationM, rotationM, projectionM, lookAtM, finalM;
HRESULT hr;
D3DXMatrixIdentity(&objectM);
D3DXMatrixRotationY(&rotationM, D3DX_PI/4);
//D3DXMatrixMultiply(&finalM, &objectM, &rotationM);
D3DXMatrixPerspectiveFovLH(&projectionM,D3DX_PI/4,(float)yRes/xRes, 1, 100);
D3DXVECTOR3 camera;
camera.x = -10;
camera.y = 0;
camera.z = 0;
D3DXVECTOR3 cameraTarget;
cameraTarget.x = 0;
cameraTarget.y = 0;
cameraTarget.z = 0;
D3DXVECTOR3 cameraUp;
cameraUp.x = 0;
cameraUp.y = 1;
cameraUp.z = 0;
D3DXMatrixLookAtLH(&lookAtM,&camera,&cameraTarget, &cameraUp);
hr = pd3dDevice->SetTransform(D3DTS_WORLD, &objectM);
hr = pd3dDevice->SetTransform(D3DTS_PROJECTION, &projectionM);
hr = pd3dDevice->SetTransform(D3DTS_VIEW, &lookAtM);
D3DVIEWPORT9 view_port;
view_port.X=0;
view_port.Y=0;
view_port.Width=xRes;
view_port.Height=yRes;
view_port.MinZ=0.0f;
view_port.MaxZ=1.0f;
pd3dDevice->SetViewport(&view_port);
}
Note of course that some elements may not be needed, placed there just in case during my attempts, this is the code I have currently so we have a common reference.
Thanks in advance for any answers and/or attempts to answer.
In your code (downloaded), xRes and yRes are ints. Due to integer division, yRes/xRes will be zero, because xRes > yRes. You are passing this into the D3DXMatrixPerspextiveFovLH function as the aspect ratio, which will produce an invalid matrix. Instead, cast them to floats first, before doing the division, and pass the result in.

Raytracer won't render more than one instance of an object

I'm writing a raytracer in C++ and I'm having quite a bit of trouble understanding why my output images don't contain all of the objects that should be there. Namely, I'm working with spheres and planes, and I can't draw more than one instance of each.
The object values are read in from an ASCII file (such as radius, location, normals, etc). Here's my intersect test code.
//check primary ray against each object
for(int size = 0; size < objList.size(); size++){
//if intersect
if(objList[size]->intersect(ray,origin,&t)){
if(t < minDist){ //check depth
minDist = t; //update depth
bestObj = size; //update closest object
}
}
}
vec3 intersection = origin + minDist*ray;
//figure out what to draw, if anything
color_t shadeColor;
if(bestObj != -1){ //valid object
//get base color
//using rgb color
if(objList[bestObj]->rgbColor != vec3(-1)){
shadeColor.r = objList[bestObj]->rgbColor.x;
shadeColor.g = objList[bestObj]->rgbColor.y;
shadeColor.b = objList[bestObj]->rgbColor.z;
}
//else using rgbf color
else if(objList[bestObj]->rgbfColor != vec4(-1)){
shadeColor.r = objList[bestObj]->rgbfColor.x;
shadeColor.g = objList[bestObj]->rgbfColor.y;
shadeColor.b = objList[bestObj]->rgbfColor.z;
//need to do something with alpha value
}
//else invalid color
else{
cout << "Invalid color." << endl;
}
//...the rest is just shadow and reflection tests. There are bugs here as well, but those are for another post
The above code is within a loop that checks for every pixel. 'ray' is the direction of the ray, and 'origin' is the origin of that ray. 'objList' is an stl vector that holds each object in the scene. I've tested to make sure that each object is actually getting put into the vector.
I know that my intersection tests are working...at least for the one object of each type that renders. I've had the program print to a file all the values that 'bestObj' ever gets, but it never seems to register that any of the objects other than the last one is a 'bestObj'. I realize that this is the problem, that no other object gets set as the 'bestObj', but I can't figure out why!
Any help would be appreciated :)
I figured out the problem, thanks to didierc. I'm not sure what he was really talking about, but it made me think about how I was handling my pointers. Indeed, though my vector was pushing back every object, I wasn't creating new objects for each time I pushed one back. This led to each sphere in the stl vector pointing to the same one (aka the last one read in from file)!

Java3d - Bad Normals using GeometryInfo

I'm working with Java3d under eclipse Indigo in windows. After finally modifying the StlLoader example and ObjLoad classes to get my STL files to load up, I get a result that looks like the below (I think from other questions these are definitely bad vector normals). Does anybody know why I might be having this problem? I am using SolidWorks to save the STL as an ASCII file and using a modification of the code for loading STL files given on java3d.org. Although I have only changed some appearance properties and fixed broken imports etc. I have confirmed that the facet normals put into "normList" below definitely match those from the file.
Example of Result:
Snippet of StlFile.java from http://www.java3d.org :
private SceneBase makeScene()
{
// Create Scene to pass back
SceneBase scene = new SceneBase();
BranchGroup group = new BranchGroup();
scene.setSceneGroup(group);
// Store the scene info on a GeometryInfo
GeometryInfo gi = new GeometryInfo(GeometryInfo.TRIANGLE_STRIP_ARRAY);
// Convert ArrayLists to arrays: only needed if file was not binary
if(this.Ascii)
{
coordArray = objectToPoint3Array(coordList);
normArray = objectToVectorArray(normList);
}
gi.setCoordinates(coordArray);
gi.setNormals(normArray);
gi.setStripCounts(stripCounts);
// Setting the Material Appearance
Appearance app = new Appearance();
// Coloring Attributes
ColoringAttributes catt = new ColoringAttributes();
catt.setShadeModel( ColoringAttributes.NICEST );
app.setColoringAttributes(catt);
Material mat = new Material(new Color3f(0.6f, 0.6f, 0.6f), // ambient
new Color3f(0, 0, 0), // emissive
new Color3f(0.6f, 0.6f, 0.6f), // diffuse
new Color3f(0.6f, 0.6f, 0.6f), // specular
10); // shininess
app.setMaterial(mat);
// Put geometry into Shape3d
Shape3D shape = new Shape3D(gi.getGeometryArray(), app);
group.addChild(shape);
scene.addNamedObject(objectName, shape);
return scene;
} // end of makeScene
If some areas on the surface are really black (0x000000), I would guess some of the normals are actually pointing inwards the model rather than to the outside.
You may check if vertices v1,v2,v3 for all the triangles are defined in right-hand order (just test if det(v1,v2,v3) > 0 ) and reorder points accordingly. Alternatively, detect the "opposite" normals and multiply them by -1

'An invalid object handle was used' in FMOD 3D sound listener

I'm trying to set up 3D sounds with FMOD in a game which uses Ogre. The sound listener is attached to the camera which runs on a spline. I have footstep sounds attached to the player, and the volume should be determined by how far the player is from the camera.
The foot step sounds are acting as though the sound listener is not moving from its start position. At the start of the level, the footsteps are loud, and as you move away from the start they get quieter until you can't hear them anymore. If you run back to the start, they get louder. However, the position of the sound listener's scene node is updating and staying in sync with the camera.
In code there is an FMOD error being generated every frame on the following line:
result = m_system->set3DListenerAttributes(0, &pos, &vel, &forward, &up);
result is always returning FMOD_ERR_INVALID_HANDLE, with the following error string - 'An invalid object handle was used'. I can't figure out why this error is being generated. All the FMOD_VECTORs being passed in as parameters are initialised and I appear to be setting up the system correctly. The code is all over the place in different classes but here are the important bits:
// Initialise FMOD system
result = m_system->init(4093, FMOD_INIT_3D_RIGHTHANDED, 0);
result = m_system->set3DSettings(1.0f, 1.0f, 1.0f);
// Create sound
FMOD_MODE mode = FMOD_SOFTWARE;
if(a_positional)
{
mode |= FMOD_3D;
}
FMOD_CREATESOUNDEXINFO info;
memset(&info, 0, sizeof(FMOD_CREATESOUNDEXINFO));
info.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
r = sys->_getFMODSystem()->createSound(a_file.c_str(), mode, &info, &retVal);
// Update sound listener
FMOD_VECTOR pos, vel, forward, up;
pos.x = m_sceneNode->getParentSceneNode()->_getDerivedPosition().x;
pos.y = m_sceneNode->getParentSceneNode()->_getDerivedPosition().y;
pos.z = m_sceneNode->getParentSceneNode()->_getDerivedPosition().z;
vel.x = 0;
vel.y = 0;
vel.z = 0;
forward.x = 0;
forward.y = 0;
forward.z = 1;
up.x = 0;
up.y = 1;
up.z = 0;
result = m_system->set3DListenerAttributes(0, &pos, &vel, &forward, &up);
// FMOD error: (36) An invalid object handle was used.
Any ideas as to why 'result' is returning this error? I'm assuming it's the reason why the 3D sounds aren't playing correctly.
An invalid handle error (FMOD_ERR_INVALID_HANDLE) is referring to the object you are calling functions on, in this case it means the m_system handle is invalid.
Firstly I noticed you have omited the code to create the FMOD::System object, can you confirm you are doing the following:
result = FMOD::System_Create(&m_system);
Secondly, provided you have that code somewhere can you verify that the value of m_system remains unchanged between when it is created and when it is used (perhaps something is corrupting the handle).
Finally (as a long shot) if your headers and lib are out of sync you might be getting a different error message, ensure the headers and libs you are using are all from the same version of FMOD.
Extra note, try linking with the logging version of FMOD, you should get some useful debug output on the TTY that might help your situation.