point normals



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 16/03/2010 at 09:21, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   r11 
    Platform:      
    Language(s) :     C++  ;

    ---------
    hi there,

    how can i create a normal direction for a point? i suppose that i need to calculate the sum of the normals of all polygons which use that point and than divide it by the number of polygons used. but 1. how do i find out which polygons use a certain point and 2. would that be a performance issue (if i would cycle thru all polygons for every point and check if the point is used by that polygon)?

    thanks and cheers,
    ello



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 16/03/2010 at 16:42, xxxxxxxx wrote:

    Howdy,

    Have a look at the Neighbor class.

    Adios,
    Cactus Dan



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 16/03/2010 at 22:44, xxxxxxxx wrote:

    Thank you! Thats exactly what i need :)

    cheers,
    Ello



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 18/03/2010 at 11:48, xxxxxxxx wrote:

    Of course you could also just let C4D tell you what they are - look at: PolygonObject::CreatePhongNormals() - the advantage to that is that phong-break edges are also taken into account.

    Cheers,

    Keith



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 18/03/2010 at 13:24, xxxxxxxx wrote:

    thank you.. now i did this:

      
    Vector n;  
    Vector* phongNormal = myMesh->CreatePhongNormals();  
    for (int i=0;i<pointcount;i++)  
    {  
    n=phongNormal[i] _;  
    }  
    

    Is there anything wrong with my assumption that this should return the normal for point i ? somehow it looks a bit screwed up..

    thanks for your input,
    ello
    _



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 18/03/2010 at 13:48, xxxxxxxx wrote:

    CreatePhongNormals() creates normals for each of a polygon's points. For a cube for instance it will create 6*4 point normals. This is necessary to describe phong breaks. Depending on what you want to achieve this is maybe not really what you are looking for. I am guessing that you are looking for a way to obtain average point normals, right?

    cheers,
    Matthias



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 18/03/2010 at 13:52, xxxxxxxx wrote:

    yes, exactly.. so do you think i should go the way using the Neighbours ?



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 19/03/2010 at 01:04, xxxxxxxx wrote:

    Well you can still use CreatePhongNormals() and average these normals for each point.

    -build the point normals per polygon array with CreatePhongNormals()
    -iterate through all the points, GetPointR(), GetPointCount()
    -get the adjacent polygons for each point with GetPointPolys()
    -for each adjacent polygon get the point normal for the common point
    -average these normals

    alternatively
    -iterate through all the points, GetPointR(), GetPointCount()
    -get the adjacent polygons for each point with GetPointPolys()
    -calculate the polygon normal for each adjacent polygon (or create an polygon normal array in advance)
    -average these normals

    Since there is no "correct" way you have to try which works better for you.

    cheers,
    Matthias



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 19/03/2010 at 01:29, xxxxxxxx wrote:

    thank you.. after looking again at my code i found why i got that error message. i wrote Neighbour instead of Neighbor..

    kind regards,
    ello



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 19/03/2010 at 12:38, xxxxxxxx wrote:

    Hi, i am still having a problem here.

      
                      neighbor.GetPointPolys(i,&dadr,&dcnt);  
                      GePrint(LongToString(dcnt));
    

    dcnt is always 0, but how can this be? there are actually quite a lot of points and polygons in the base mesh..
    i dont understand this.

    thanks for any input.
    cheers,
    ello



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 19/03/2010 at 12:49, xxxxxxxx wrote:

    Sorry these two lines of code don't say much :) Please post a bigger portion of your code, for instance how you initialized the Neighbor class.

    cheers,
    Matthias



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 19/03/2010 at 12:58, xxxxxxxx wrote:

    oh, ok.. i placed the neighbor.Init(...) in a condition which wasnt true..
    it works now. thanks for all your help :)

    cheers,
    ello



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 11/06/2010 at 09:42, xxxxxxxx wrote:

    hi again,

    i am still struggling and i thought before further hijacking the other thread i bring this thead up again:

    here is my code for averaging.. polygonNormal returns the right polygon normals, as seen in this screen:

      
      
          padr = cloneOfBase->GetPointR();  
          pol = cloneOfBase->GetPolygonR();  
          numberofclones = cloneOfBase->GetPointCount();  
          maxcount = cloneOfBase->GetPolygonCount();  
    ...  
      
                  if (neighbor.Init(numberofclones, pol, maxcount, NULL))  
                  {  
                      neighbor.GetPointPolys(i, &dadr, &dcnt);  
                      if (dcnt)  
                      {  
                          for (int j=0;j<dcnt;j++)  
                          {  
                              if (dadr[j]<=maxcount)  
                              {  
                                  polyNormal += polygonNormal(nCalc1,nCalc2,padr,pol,dadr[j]);  
                              }  
                          }  
                          polyNormal /= dcnt;  
                      }  
                  }  
    

    any ideas??

    cheers,
    ello



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 11/06/2010 at 10:18, xxxxxxxx wrote:

    I see that you're still not normalizing the result of polygonNormal() or of polyNormal, after you've divided it... have you tried that?



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 11/06/2010 at 10:25, xxxxxxxx wrote:

    yes, that gave me even stranger results. what i dont understand is that it works for most of the points



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 11/06/2010 at 11:30, xxxxxxxx wrote:

    Ok, here is some verified working code that I've stripped out to be stand-alone callable routines...

      
    //---------------------------------------------------------------------------------------   
    //***************************************************************************************   
    // GetVertexNormals()   
    //***************************************************************************************   
    //---------------------------------------------------------------------------------------   
    Vector *GetVertexNormals(PolygonObject *pObj)   
    {   
         LONG numVerts = pObj->GetPointCount();   
         LONG numPolys = pObj->GetPolygonCount();   
         const Vector *pVerts = pObj->GetPointR();   
         const CPolygon *pPolys = pObj->GetPolygonR();   
      
         // initialize neighbor class... this is used to compute m_SrcvNorms   
         Neighbor neighbor;   
         if( !neighbor.Init(numVerts, pPolys, numPolys, NULL) )   
              return NULL;   
      
         // Allocate array of Normal Vectors to fill in and return   
         Vector *pNormals = (Vector * )GeAlloc(numVerts * sizeof(Vector));   
         if( !pNormals )     return NULL;   
      
         // Determine a Normal for each vertex of mesh   
         LONG i, j, faceCnt, *pFaces = NULL;   
         Vector vNorm;   
         for(i=0; i<numVerts; i++)   
         {   
              vNorm = Vector();          // (re)intitialize   
              neighbor.GetPointPolys(i, &pFaces;, &faceCnt;);   
              if( faceCnt )   
              {   
                   for(j=0; j<faceCnt; j++)   
                   {   
                        Vector n = CalcFaceNormal(pVerts, pPolys[pFaces[j]]);   
                        vNorm += !n;   
                   }   
                   vNorm /= faceCnt;          // average the normal(s)   
                   pNormals[i] = !vNorm;     // normalize and store   
              }   
              else   
                   pNormals[i] = Vector(0.0,1.0,0.0);     // default case = Up for any stray verts   
         }   
         return pNormals;   
    }   
      
    //---------------------------------------------------------------------------------------   
    //***************************************************************************************   
    // AddNormSplineObject()   
    //***************************************************************************************   
    //---------------------------------------------------------------------------------------   
    void AddNormSplineObject(PolygonObject *pObj, LONG splineLen)   
    {   
         Vector *pNormals = GetVertexNormals(pObj);   
         if( !pNormals )     return;   
      
         LONG numNorms = pObj->GetPointCount();   
      
         // allocate spline object large enough for all points   
         SplineObject *splineOp = SplineObject::Alloc(2*numNorms,Tlinear);   
         if( !splineOp || !splineOp->MakeVariableTag(Tsegment,numNorms) )   
         {   
              MessageDialog(String("Spline Object Allocation Failed"));   
              GeFree(pNormals);   
              return;   
         }   
         splineOp->SetName(String("NormSplines"));   
      
         Vector *padr = splineOp->GetPointW();   
         Segment *sadr = splineOp->GetSegmentW();   
      
         if( !padr || !sadr )   
         {   
              MessageDialog(String("Spline Object Data Setup Failed"));   
              GeFree(pNormals);   
              SplineObject::Free(splineOp);   
              return;   
         }   
      
         const Vector *pVerts = pObj->GetPointR();   
         Matrix mg = pObj->GetMgn();   
         LONG normCnt = 0;   
         LONG vertCnt = 0;   
         LONG i;   
         for(i=0; i<numNorms; i++)   
         {   
              sadr[normCnt].cnt = 2;   
              sadr[normCnt++].closed = false;   
      
              padr[vertCnt++] = pVerts[i] * mg;   
              padr[vertCnt++] = (pVerts[i] + (pNormals[i] * splineLen)) * mg;   
         }   
         splineOp->GetDataInstance()->SetBool(SPLINEOBJECT_CLOSED,false);   
      
         GeFree(pNormals); // done with this now   
      
         BaseDocument *pBaseDoc = pObj->GetDocument();   
         pBaseDoc->InsertObject(splineOp,NULL,NULL);   
         splineOp->Message(MSG_UPDATE);   
    }   
    

    ...just cut/paste that into your code and call the AddNormSplineObject() routine with your PolygonObject. Once you've verified that it's working, you can either use it as-is, or reference it to figure out why yours is not working.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 11/06/2010 at 11:31, xxxxxxxx wrote:

    If you have any compile errors or trouble with include files, let me know.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 11/06/2010 at 12:08, xxxxxxxx wrote:

    thank you very much.. after first crash, i passed my doc to the function like this,
    void AddNormSplineObject(PolygonObject *pObj, LONG splineLen,BaseDocument *doc)

    and it works.. now i need to understand why it does :)

    again, thank you very very much for your help!

    cheers,
    ello



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 11/06/2010 at 12:14, xxxxxxxx wrote:

    D'oh! I guess that your PolygonObject wasn't yet attached to the scene :). I usually test all results before using pointers like that, but I kinda threw that in there at the last minute when I was stripping out my old Class member code.

    Anyway... if you want, you can just use that GetVertexNormals() routine as-is (just be sure to GeFree() the array when you're done with it).

    Good luck!



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 11/06/2010 at 12:18, xxxxxxxx wrote:

    i now used the pNormals to rotate my clones and now it looks like when i told you how it looked after i used the normalised normals:

    any idea? how can this be?? i'll have to recheck my code after the rotation. i just dont understand why it works for polygons, but not for points. very strange


Log in to reply