Notifications
Clear all

[Closed] Problems reading normals from an edit mesh

I’m having a problem retrieving the normals of some edit meshes, they are something like a flat geometry, it works ok with Edit Poly but the weird fact is that if I convert it to Edit Poly and back to Mesh it works ok.

MeshNormalSpec *getSpecifiedNormalsFromMesh(Mesh* mesh)
{
	MeshNormalSpec *normalSpec = mesh->GetSpecifiedNormals();

	if (normalSpec == NULL)
	{
		mesh->SpecifyNormals();
		normalSpec = mesh->GetSpecifiedNormals();
	}

	if (normalSpec->GetNumNormals() == 0)
	{
		normalSpec->SetParent(mesh);
		normalSpec->CheckNormals();
	}

	if (normalSpec == NULL)
		return NULL;

	bool isSetMESH_NORMAL_NORMALS_BUILT = normalSpec->GetFlag(MESH_NORMAL_NORMALS_BUILT);
	bool isSetMESH_NORMAL_NORMALS_COMPUTED = normalSpec->GetFlag(MESH_NORMAL_NORMALS_COMPUTED);
	bool isSetMESH_NORMAL_MODIFIER_SUPPORT = normalSpec->GetFlag(MESH_NORMAL_MODIFIER_SUPPORT);

	if (!isSetMESH_NORMAL_NORMALS_BUILT || !isSetMESH_NORMAL_NORMALS_COMPUTED)
	{
		normalSpec->SetParent(mesh);
		normalSpec->CheckNormals();
	}

	if (normalSpec->GetNumNormals() == 0)
	{
		normalSpec->SetParent(mesh);
		normalSpec->CheckNormals();
	}

	return normalSpec;
}

Called from:

if (objectState->obj->IsSubClassOf(triObjectClassID)) {
	TriObject *triOb = (TriObject*)objectState->obj;
	getSpecifiedNormalsFromMesh(triOb->GetMesh());
}

Any thought on this?

11 Replies

this is how I create them if they are not there…

mesh->SpecifyNormals();
MeshNormalSpec* nspec = mesh->GetSpecifiedNormals(); // creates an "empty" soec normals
if(nspec)
{
      nspec->ClearFlag(MESH_NORMAL_NORMALS_BUILT);
      nspec->CheckNormals(); // force them to be built
......

it’s also worth noting that MeshNormalSpec::GetSpecifiedNormals() IIRC always returns a valid pointer so can’t be used to test “existance” on its own…

so you should use…

MeshNormalSpec* nspec = mesh->GetSpecifiedNormals();
if(nspec && nspec->GetFlag(MESH_NORMAL_NORMALS_BUILT))  // nspec will always be valid but old habits
{
.....

what I think is going on is
the MeshNormalSpec exists on the mesh but the mesh is not assined to it or GetSpecifiedNormals returns new MeshNormalSpec() and not NULL if it can’t be found.
so

mesh->SpecifyNormals();

is much the same as using

nspec->SetParent(mesh);

I think that my implementation makes the same thing

bool isSetMESH_NORMAL_NORMALS_BUILT = normalSpec->GetFlag(MESH_NORMAL_NORMALS_BUILT);
bool isSetMESH_NORMAL_NORMALS_COMPUTED = normalSpec->GetFlag(MESH_NORMAL_NORMALS_COMPUTED);
bool isSetMESH_NORMAL_MODIFIER_SUPPORT = normalSpec->GetFlag(MESH_NORMAL_MODIFIER_SUPPORT);

if (!isSetMESH_NORMAL_NORMALS_BUILT || !isSetMESH_NORMAL_NORMALS_COMPUTED)
{
normalSpec->SetParent(mesh);
normalSpec->CheckNormals();
}

But I’m still having this problem (it doesn’t happen with Edit Poly)

Original normals (edit mesh)

Recreated normals (readed and reapplied)

I did be looking at how you “read” and “write” them. looks like you “exploded” them ie 1 for every face corner and none shared.

Yes I think so, but that’s my code nothing special, about reading the normals

MeshNormalSpec *nrm = getSpecifiedNormalsFromMesh(mesh);
for (int i = 0; i < numFaces; i++)
{
	for (int j = 0; j < 3; j++)
	{
		p3 = nrm->GetNormal(i, j).Normalize();
	}
}

Is the current method , there is nothing strange neither here.

could you post the max scene with this object?

Sure, here we go:

EditMeshNormals.max (484 KB)

this the one of the functions I use for my normal editing routines (there are others that work on selected faces etc) might shed some light on it for you

void modutils::AdjNormals(Mesh& mesh, MeshNormalSpec* nspec, INormalModParams& p)
{
	int numnormals = nspec->GetNumNormals();
	Point3* normals = nspec->GetNormalArray();
	MeshNormalFace* normalfaces = nspec->GetFaceArray();
	DbgAssert(normals);
	DbgAssert(normalfaces);

	BitArray normalset(numnormals); // create a bit array to make sure we only visit once

// geometry verts and faces

	int nfaces = mesh.numFaces;
	Face* faces = mesh.faces;
	Point3* verts = mesh.verts;

// for all faces and all face verts

	for(int f=0; f < nfaces; ++f ,++faces, ++normalfaces)
	{
		int* fnormals = normalfaces->GetNormalIDArray();
		for(int j = 0; j < 3; ++j)
		{
			int normal = fnormals[j];
			if(!normalset[normal])
			{
				p.evaluate(verts[faces->v[j]],normals[normal]);
				normalset.Set(normal);
			}
		}
	}
	nspec->MakeNormalsExplicit(false), 
	nspec->SetFlag(MESH_NORMAL_NORMALS_BUILT);
}

I can just different editing object via INormalModParams object

It seems that the problem is creating the normals not reading them, it also fails in a really simple code snippet:

void BuildMesh(Mesh &mesh, float objSize)
{
mesh.setNumVerts(4);
mesh.setNumFaces(3);
mesh.setVert(0, objSizePoint3(0.0, 0.0, 0.0));
mesh.setVert(1, objSize
Point3(10.0, 0.0, 0.0));
mesh.setVert(2, objSizePoint3(0.0, 10.0, 0.0));
mesh.setVert(3, objSize
Point3(0.0, 0.0, 10.0));

mesh.faces[0].setVerts(0, 1, 2);
mesh.faces[0].setEdgeVisFlags(1, 1, 1);
mesh.faces[1].setVerts(3, 1, 0);
mesh.faces[1].setEdgeVisFlags(1, 1, 1);
mesh.faces[2].setVerts(0, 2, 3);
mesh.faces[2].setEdgeVisFlags(1, 1, 1);

mesh.SpecifyNormals();
MeshNormalSpec* normalsSpecifier = mesh.GetSpecifiedNormals();

normalsSpecifier->ClearNormals();
size_t numFaces = mesh.getNumFaces();
normalsSpecifier->SetNumFaces((int)numFaces);

// fill in the normals
int normalCount = (int)mesh.getNumFaces() * 3;

normalsSpecifier->SetNumNormals(normalCount);
for (int i = 0; i < normalCount; ++i)
{
Point3 normal = Point3(0, 1, 0);
normalsSpecifier->Normal(i) = normal;
normalsSpecifier->SetNormalExplicit(i, true);
}

for (size_t j = 0; j < numFaces; ++j)
{
MeshNormalFace& normalFace = normalsSpecifier->Face((int)j);
normalFace.SpecifyAll();
normalFace.SetNormalID(0, 3 * j);
normalFace.SetNormalID(1, 3 * j + 1);
normalFace.SetNormalID(2, 3 * j + 2);
}

mesh.InvalidateGeomCache();
}

TriObject* triObj = CreateNewTriObject();
BuildMesh(triObj->mesh,1);
INode* newnode = GetCOREInterface()->CreateObjectNode(triObj);

It seems to be ok … until you apply a Edit Poly modifier:

Any tip on this?

ignore me my mind is else where and I’m talking rubbish

Page 1 / 2