Modeling Class basics...



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

    On 17/02/2005 at 15:59, xxxxxxxx wrote:

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

    ---------
    Hi,

    I am now moving my plugins to R9 and I have just read the modeling class description and had a look at the modeling lib. I must say, the changes are a bit heavy to me, so I need a little lesson. The function themselves are actually clear but I am a bit lost in the overview.

    My first question would be: what´s the best or optimal way to browse through polygons including N-gons and getting point access? I assumed there would be a way to do sth similar to this:

    PGon *ngon;  
    Vector pointA;  
      
    for(i;i<pcnt;i++) {  
         CPolygon* p = &padr; _;  
         if(IsNGon(p)) {  
            GetNGon(i,*ngon);  
            pointA = ngon->a;  
         }  
         else  
            //usual access to p  
            pointA = p->a;  
    }
    

    Or is this possible with the Modeling class? I just cannot get thru the jungle yet. :-\

    Thanks in advance
    Katachi



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

    On 21/02/2005 at 11:03, xxxxxxxx wrote:

    Noone? I still couldn´t figure out which is the most sensible way to browse through a polygon object with NGons.
    I don´t want to see myself rewriting areas all over again.



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

    On 28/02/2005 at 09:33, xxxxxxxx wrote:

    First thing to understand is that a PolygonObject consists of polygons firstly (this was essential for backwards compatibility and internal compatibility) above this is a layer which holds n-gons (stored and managed by the NgonBase class). So when you have an object that has polygons and n-gons you actually have an array of all polygons (even those that make up n-gons) plus then additional data for each n-gon.
    If you want to loop through these then how (the most optimal) depends on what you are doing, here are some options:
    Lets start without the modeling library, so this way you are faced with the polygonobject itself which consists of the Polygons (all of them), plus any Ngons. If there are no n-gons (easily found by checking GetNgonCount from the PolygonObject) then its just a case of looping through all polygons as pre-R9. If there are n-gons then you have some options:
    1. the easiest and pretty optimal is to use the Neighbour class, then call its GetNgons() function, this will return to you the total number of Ngons (this will consist of everything, tris, quads and >4 point ngons), you can then loop around this returned count and use the array returned to read data about each index.
    2. you can loop through all polygons then use NgonBase::FindPolygon() to check if this polygon ID is contained within an N-gon (i.e. what you called IsNGon()). How you read the points from the n-gon depends on if you want to manually access the Ngon data or use the modeling library (see below for info on reading ngons).
    With the modeling library you don't need to worry about the split between n-gons and polygons, they are treated the same and all returned to you in the Ngon class. Indexing is the only thing you need to watch. The modeling library uses an index rule of polygons followed by n-gons, so for example, the index of the first real n-gons (>4 points) from the polygon object is at the index GetPolygonCount(). If you pass an index of any polygon the modeling library translates this into the index of the n-gon index for any real n-gon, if it was a polygon then it remains unchanged. You can use the Translate calls to find out what indexes the modeling library is dealing with (i.e if an index is changed), translate also does more than this since indexes can be cloned, virtual and melted.
    One way you could loop through the indexes would be to create two dummy BaseSelect, in the first (src) you could select all indexes of all polygons, then pass this to GetFaceSelection and it will fill the destination BaseSelect with the translated indexes, then you can easily loop through these. e.g.

        
        
          
         BaseObject *op=doc->GetActiveObject();
        
        
        
        
         AutoAlloc<Modeling> model;  
         AutoAlloc<BaseSelect> src,dst;
        
        
        
        
         if (!model->InitObject(op)) return FALSE;
        
        
        
        
         src->SelectAll(0,ToPoly(op)->GetPolygonCount());  
         model->GetFaceSelection(op,src,dst,NULL);  
           
         GePrint("Count: " +LongToString(dst->GetCount()));  
        
    

    You could also combine using the NgonBase::FindPolygon with the modeling library, this makes it easy and quick to loop through the polygons and n-gons and also to then read the points for them, e.g.

        
        
          
         BaseObject *op=doc->GetActiveObject();
        
        
        
        
         AutoAlloc<Modeling> model;
        
        
        
        
         NgonBase *ngons=ToPoly(op)->GetNgonBase();  
         Ngon ngon;
        
        
        
        
         LONG i,pcnt=0,ncnt=ToPoly(op)->GetNgonCount(),vcnt=ToPoly(op)->GetPolygonCount();
        
        
        
        
         if (!model->InitObject(op)) return FALSE;
        
        
        
        
         // loop through all polygons
        
        
        
        
         for (i=0;i<vcnt;i++)  
         {  
          if (!ngons || ngons->FindPolygon(i)==NOTOK) pcnt++;
        
        
        
        
          // read polygon as normal  
         }
        
        
        
        
         // loop through all ngons
        
        
        
        
         for (i=0;i<ncnt;i++)  
         {  
          if (!model->GetNgon(op,vcnt+i,&ngon)) return FALSE;
        
        
        
        
          // read points/segments from ngon  
         }
        
        
        
        
         pcnt+=ncnt;
        
        
        
        
         GePrint("Count:" +LongToString(pcnt));  
        
    

    A couple of points to note here...

    1. ALWAYS ALWAYS check NgonBase is NOT NULL! it is only created if an ngon was used, but, remains available even with no ngons, you can force it to create (sometimes useful) by calling GetNgon, if you have called GetNgon then the NgonBase will be always available afterwards (unless memory was too low, so a FAIL check is useful in that case).
    2. ALWAYS ALWAYS check that a modeling library function did NOT fail, if it DID fail exit and restore any data changes otherwise CINEMA could crash from corrupt or partly changed data.
      Manually reading ngons is sometimes useful for very fast access, the modeling library does have overhead since it must track and store data (so speed and memory hits there). Ngons are stored in whats called the Pgon class [Polygon group], this holds essentially an array of edges with extra bits to help mark segments and other useful info. All this can be found in the Ngon library, using the classes and functions will mean the best chance of future compatibility, raw data access could mean that in future plugin changes might be needed.
      HTH.


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

    On 28/02/2005 at 10:32, xxxxxxxx wrote:

    Thank you Dave! That helps very much.


Log in to reply