selecting polygons facing away from cam

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

On 04/11/2009 at 04:37, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   R11 
Platform:   Windows  ;   Mac OSX  ; 
Language(s) :     C++  ;

---------
Hello,
how would I select all polygons of a given PolygonObject, that face away from the camera? Any ideas?

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

On 04/11/2009 at 08:32, xxxxxxxx wrote:

This is generally known as camera(or view)-dependent backface culling.

First thing you need is to calculate the normal vector for the polygon (there is a function to do this: CalcFaceNormal()). Then get the camera's location. In general, something like this:

// Polygon and Vertex array pointers   
CPolygon*     padr =     pobj->GetPolygonW();   
Vector*          vadr =     pobj->GetPointW();   
if (!(padr && vadr)) return FALSE;   
// Camera (global-space) location   
BaseDraw*     bd =     doc->GetActiveBaseDraw();   
BaseObject*     cam =     bd->GetSceneCamera(doc);   
if (!cam)               cam = bd->GetEditorCamera();   
Vector          E =      cam->GetMg().off;   
// incidentals   
Matrix          mg =     pobj->GetMg();   
LONG          pcnt =     pobj->GetPolygonCount();   
CPolygon*     p;   
Vector          N, V;   
Real          dir;   
for (LONG i = 0L; i != pcnt; ++i)   
{   
     // Some polygon   
     p =      padr[i];   
     // Normal vector of polygon   
     N =          CalcFaceNormal(vadr, p)*mg;   
     V =          vadr[p->a]*mg;   
     // Determination of polygon facing wrt camera   
     dir =     N*(E-V);   
     if (dir <= 0.0f)     // backfacing: cull polygon   
}

If you need to consider only what is in the direction of the camera view, you will need to build a direction vector and a bit more calculation.

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

On 06/11/2009 at 05:03, xxxxxxxx wrote:

Thx, that helped a lot 😄

I only had to change

  
    N = CalcFaceNormal(vadr, p) * mg;   

to

  
    N = CalcFaceNormal(vadr, p);   

to make it work for objects that are not in the origin.

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

On 06/11/2009 at 05:09, xxxxxxxx wrote:

CalcFaceNormal() might already be putting the normal into global space (haven't really had that exact circumstance arise yet). 🙂

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

On 06/11/2009 at 14:15, xxxxxxxx wrote:

Originally posted by xxxxxxxx

Thx, that helped a lot 😄

I only had to change

 
  N = CalcFaceNormal(vadr, p) * mg;   

to

 
  N = CalcFaceNormal(vadr, p);   

to make it work for objects that are not in the origin.

Hmm, that does only make sense if the calculations are done in local object space. However, that sounds like a dangerous operation to me (though I don´t know where and when you use it but generally it isn´t a bad idea making it work globally, especially during rendering etc.). It´s surely more safe to do it in global space (CalcFaceNormal does only return a local normal afaik), so definetly check the rest of your code to work with kuros suggested world aligned normal instead of using the local one.

Just my 2 cents.. 😉

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

On 06/11/2009 at 14:43, xxxxxxxx wrote:

I just found that BaseDraw has a BackfaceCulling() function (from BaseView) into which you pass the polygon normal and center vectors. Unfortunately, it doesn't specify if these two vectors should be in local, global, camera, or screen space.

This requires calculating the polygon's center (centroid). It should be determined as follows:

Vector ctr;
if (p->c == p->d) ctr = (vadr[p->a]+vadr[p->b]+vadr[p->c])*0.333333333f;
else ctr = (vadr[p->a]+vadr[p->b]+vadr[p->c]+vadr[p->d])*0.25f;