Point normals (again)
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 25/01/2009 at 05:25, xxxxxxxx wrote:
Quote: Originally posted by c4dJack on 25 January 2009
>
> * * *
>
> ...I would get 4 tri polygons = 6 vertices = 12 elements in normal array. Right? Because there are three vertices per polygon? Or would I still get 4 vertices per polygon (= 16 elements), just the 4th one is not used?
>
>
> * * *Underlined.
Basically, you always get 4 x number_of_polygons ... one for each (a,b,c,d) corner of the quad - whether the 4th is used, or not.
As an aside, this is also how the UVW Tag works... except that it has routines to let you get each uv-polygon: UVWStruct uvw = pUVs->Get(polyNdx); I modeled the NormalStruct on the UVWStruct -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 25/01/2009 at 05:37, xxxxxxxx wrote:
It's best to think of it this way:
CPolygon = vertex-polygon
UVWStruct = uv-polygon
NormalStruct = normal-polygon
...all of the above always have 4 elements (a,b,c,d). The only practical difference is that the CPolygon contains indices into the vertex array as it's elements and the other two contain the actual UV/Normal Vector itself instead of an index, as the 4 elements. -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 05/08/2009 at 10:40, xxxxxxxx wrote:
Sorry, to push this up again, but:
What , if I don't work with polygons, but just with points? I can't use NormalStruct results here, since I just have a point index. How can I find out the Vertex Normal for a specific point?
Thanks in advance!
Cheers,
Jack -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 05/08/2009 at 11:33, xxxxxxxx wrote:
I'm trying to understand this, so I wrote a function to get the Vertex Normal of just one point (I know this will be slow if I want them for several points, but it's just a test).
Strangely, I get the weirdest results. The normals point in all kinds of directions, but not into the correct one.
>
\> Vector GetVertexNormal(LONG PointIndex, PolygonObject \*op) \> { \> // Variables \> CPolygon \*pNeighborPoly; \> Neighbor neighbor; \> LONG j, faceCnt, \*pFaces = NULL; \> Vector v1, v2, vNorm = Vector(0,0,0); \> CPolygon \*m_pPolys = op->GetPolygonW(); \> Vector \*m_pPoints = op->GetPointW(); \> \> // Init Neighbor class \> if (!neighbor.Init(op->GetPointCount(), m_pPolys, op->GetPolygonCount(), NULL)) \> return vNorm; \> \> // Get polygons attached to point \> neighbor.GetPointPolys(PointIndex, &pFaces;, &faceCnt;); \> \> for(j=0; j<faceCnt; j++) \> { \> pNeighborPoly = &m;\_pPolys[pFaces[j]]; \> \> // Compute face normal \> v1 = m_pPoints[pNeighborPoly->b] - m_pPoints[pNeighborPoly->a]; \> v2 = m_pPoints[pNeighborPoly->c] - m_pPoints[pNeighborPoly->a]; \> vNorm += v1 % v2; // get cross-product \> } \> vNorm /= faceCnt; \> \> // Return resuling normal vector \> return !vNorm; \> } \>
Thanks for any help!
Greetings,
Jack -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 05/08/2009 at 12:07, xxxxxxxx wrote:
I'm just waking up, but your code "looks" ok (should be working), so I'm wondering if maybe the code that's asking for 'some' point's normal is maybe asking about the wrong point? (or something).
Anyway, for debugging purposes, I sometimes call a utility routine like this...
>\> \> \> \> > //------------------------------------------------------------- \> > // AddSplineObject() \> > //------------------------------------------------------------- \> > void AddSplineObject(BaseDocument *pDoc, const String& name, const Vector& pos, const Vector& axis, const Real& length) \> > { \> > SplineObject *pSpline = SplineObject::Alloc(2,Tlinear); // allocate spline object \> > if( pSpline ) \> > { \> > if( pSpline->MakeVariableTag(Tsegment,1) ) \> > { \> > Vector *padr = pSpline->GetPointW(); \> > Segment *sadr = pSpline->GetSegmentW(); \> \> \> \> \> sadr[0].cnt = 2; \> > sadr[0].closed = false; \> \> \> \> \> padr[0] = pos; \> > padr[1] = pos + (axis * length); \> \> \> \> \> pSpline->SetName(name); \> > pDoc->InsertObject(pSpline, NULL, NULL); \> > pDoc->AddUndo(UNDO_NEW, pSpline); \> > pSpline->Message(MSG_UPDATE); \> > } \> > } \> > } \> > \> \>
...you can pass the point your asking about as the 'pos' arg, and the generated normal as the 'axis' arg and use 1 or 10 or whatever for the length. It adds a spline object, showing a visual representation of the normal (be sure to either StartUndo() or comment out that AddUndo() line).
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 05/08/2009 at 12:16, xxxxxxxx wrote:
....in your code, I'd also change:
vNorm = Vector(0,0,0); to vNorm = Vector(0,1,0); //default to pointing straight up
...and also, after:
// Get polygons attached to point neighbor.GetPointPolys(PointIndex, &pFaces, &faceCnt); ...you should add: if( !faceCnt ) return vNorm;
...to avoid any potential divide-by-zero below there.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 05/08/2009 at 12:24, xxxxxxxx wrote:
Also keep in mind that if edge-breaks are involved, each vertex can have more than one Normal. In other words, (vertex) Normals are really polygon-relative - none of the above code takes edge-breaks into account, so you end up with smoothed (averaged) normals at each vertex.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 05/08/2009 at 14:40, xxxxxxxx wrote:
In this particular case I won't care about edge breaks. Each Vertex Normal should just be the average of it's surrounding polygons.
But I HAVE to get the normal vectors by addressing them with the point index.
My code is now like this.
I pass an initialized Neighbor class object to the function, that speeds it up a lot. Anyway, the normals still point into totally stupid directions.Also I noticed, that faceCnt is always 3 for each point. But the geometry is (for testing) just a cube subdivided object, so there *should* be 4 faces for each point.
>
Vector GetVertexNormal(LONG PointIndex, PolygonObject \*op, Neighbor \*neighbor) \> { \> // Variables \> CPolygon \*pNeighborPoly; \> LONG j, faceCnt, \*pFaces = NULL; \> Vector v1, v2, vNorm = Vector(C_FLOATZERO, C_FLOATONE, C_FLOATZERO); \> CPolygon \*m_pPolys = op->GetPolygonW(); \> Vector \*m_pPoints = op->GetPointW(); \> \> // Get polygons attached to point \> neighbor->GetPointPolys(PointIndex, &pFaces;, &faceCnt;); \> if(!faceCnt) return vNorm; \> \> for(j=0; j<faceCnt; j++) \> { \> pNeighborPoly = &m;\_pPolys[pFaces[j]]; \> \> // Compute face normal \> v1 = m_pPoints[pNeighborPoly->b] - m_pPoints[pNeighborPoly->a]; \> v2 = m_pPoints[pNeighborPoly->c] - m_pPoints[pNeighborPoly->a]; \> vNorm += v1 % v2; // get cross-product \> } \> vNorm /= faceCnt; \> \> // Return resuling normal vector \> return !vNorm; \> }
Greetings,
Jack -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 05/08/2009 at 15:10, xxxxxxxx wrote:
Oh wait. My mistake. Code works fine. If I modify the geometry while calculating an array of Vertex normals, it's no wonder they point into seemingly stupid directions.
Thanks a thousand times!
Cheers,
Jack -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 06/08/2009 at 00:32, xxxxxxxx wrote:
That looks ok to me. Just some stuff you can improve (taking triangles or quadrangles into account) :
>
\> for (j=0; j<faceCnt; j++) \> { \> pNeighborPoly = &m;\_pPolys[pFaces[j]]; \> \> // Compute face normal \> if (pNeighborPoly->c == pNeighborPoly->d) //triangle \> { \> v1 = m_pPoints[pNeighborPoly->b] - m_pPoints[pNeighborPoly->a]; \> v2 = m_pPoints[pNeighborPoly->c] - m_pPoints[pNeighborPoly->a]; \> } \> else //quadrangle \> { \> v1 = m_pPoints[pNeighborPoly->c] - m_pPoints[pNeighborPoly->a]; \> v2 = m_pPoints[pNeighborPoly->d] - m_pPoints[pNeighborPoly->b]; \> } \> \> vNorm += v1 % v2; // get cross-product \> } \> \> //vNorm /= faceCnt; not necessary, normalizing is enough \> \> // Return resuling normal vector \> return !vNorm; \>
cheers,
Matthias -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 06/08/2009 at 03:07, xxxxxxxx wrote:
Quote: Originally posted by Giblet on 05 August 2009
>
> * * *
>
> ....in your code, I'd also change:
>
>\> \> \> \> > vNorm = Vector(0,0,0); \> \> \> \> \> to \> \> \> \> \> vNorm = Vector(0,1,0); //default to pointing straight up \> \> \> \> .... \> > \> \>
>
> * * *
D'oh! Ignore the above suggestion... or at least reset it to all zeros before you enter that loop below there - I was just trying to account for points not connected to ANY polygons, but you should probably handle that error condition differently anyway.
@Matthias - thanks for the corrections/additions... I'd forgotten about th normalization, so that extra divide at the end of the loop is not needed.