PolygonObject.GetPolygonTranslationMap()

On 04/06/2013 at 21:59, xxxxxxxx wrote:

Hi,

has someone experience with PolygonObject.GetPolygonTranslationMap() ? The methods
output does not make any sense to me. I have used the search function which does come 
up with a cpp code example, but that uses also PolygonObject->GetNGonTranslationMap()
which is not wrapped for python. For a linear polygon strip of 8 polygons with no ngons the 
method returns :

[0, 1, 2, 3, 4, 5, 6, 7]

If I do perform two melting operations to group the polygons in two ngons and one
polygon (0, 1, 2 - 3 - 4, 5, 6, 7) the method returns :

[0, 0, 0]

I just need a method that allows me to retrieve the the polygons attached to a ngon.
I could write more, about what I suspect and what I have tried, but I guess that won't
help. So, thanks for your time and happy rendering,

Ferdinand

On 06/06/2013 at 05:03, xxxxxxxx wrote:

is something unclear about my question ?

On 08/06/2013 at 04:56, xxxxxxxx wrote:

Hi littledevil,

I don't understand the return value of the method either. The explanation in the C++ documentation
is accurate, but it doesn't seem to be consistent with what the method returns. We either both do
not understand it correctly, or the implementation is buggy. 🙂

The returned list should have a length equal to the number of polygons in the polygon object, but
it isn't. If I create a Cube and check the output (without any N-Gons yet), the returned list is fine.
But after I add a point to an edge of the cube an create two ngons (resulting in 8 actual polygons),
the returned list does still contain only 6 elements.

-Niklas

On 08/06/2013 at 05:25, xxxxxxxx wrote:

Originally posted by xxxxxxxx

Hi littledevil,

I don't understand the return value of the method either. The explanation in the C++ documentation
is accurate, but it doesn't seem to be consistent with what the method returns. We either both do
not understand it correctly, or the implementation is buggy. 🙂

The returned list should have a length equal to the number of polygons in the polygon object, but
it isn't. If I create a Cube and check the output (without any N-Gons yet), the returned list is fine.
But after I add a point to an edge of the cube an create two ngons (resulting in 8 actual polygons),
the returned list does still contain only 6 elements.

-Niklas

Hey nikklas thanks for your answer,

The list size is actually shrinking with each ngon added the list size is always ngon count + count
of polygons not bound in a ngon. It would be great to get a official Maxon answer on that topic.

Also wrapping _lib_ngon.h  _and  lib_modeling.h for python would be a great addition for future
python SDK versions, rather than something useless (at least useless from my point of 
view) like the new snapping 'module' which is  basically just pushing BaseContainer around, 
which could also be done without that module.

Happy rendering,
Ferdinand

On 14/06/2013 at 11:40, xxxxxxxx wrote:

The problem remains unresolved for me , I would really appreciate an official statement
on the topic.

On 26/04/2017 at 14:59, xxxxxxxx wrote:

I'm running into the same issue! When I count the number of NGons returned by GetPolygonTranslationMap() it's always fewer than the total number of polygons in my scene.

  
import c4d   
  
def main() :   
    obj = op.GetObject()   
    poly_to_ngons = obj.GetPolygonTranslationMap()   
    ngons_to_polys = {}   
  
    for poly_id, ngon_id in enumerate(poly_to_ngons) :   
        ngon = ngons_to_polys.get(ngon_id, list())   
        ngons_to_polys[ngon_id] = ngon + [poly_id]   
       
    # I expect this to be the same as the list of Ngons in the structure manager.   
    # it isn't.   
    print list(set(poly_to_ngons))   

On 27/04/2017 at 01:28, xxxxxxxx wrote:

Hi,

unfortunately you are both right. GetPolygonTranslationMap() is broken in Python currently. The bug is filed and we are working on it. Sorry.

On 27/04/2017 at 10:37, xxxxxxxx wrote:

Thanks for the heads up. I've put together a probably horribly inefficient algorithm that I think retrieves all n-gons and non-n-gons.

  
def GetAllNgons(obj) :   
    """Returns a list of ngons & polygons. Its all n-gons as they first appear based on poly_id then edge order.   
    Followed by all non-ngon polys in their poly order.   
       
    Output will looks something like:   
    [[0, 2, 3], [4, 6], [1], [5]]   
    """   
  
    neighbor = c4d.utils.Neighbor()   
    neighbor.Init(obj)   
       
    polys = obj.GetAllPolygons()   
    poly_count = len(polys)   
    ngon_count = obj.GetNgonCount()   
       
    ngon_edges_compact = obj.GetNgonEdgesCompact() # N-gon info for each polygon   
    non_ngons = []   
    ngon_polys = []   
    ngons = None   
       
    edges = []   
       
    # Get NGon Polygons   
    for poly_id in xrange(poly_count) :   
        edge_value = ngon_edges_compact[poly_id] # Bitmask w/ slots for each edge in a quad   
          
        # No need to calculate n-gons if there aren't any   
        if not edge_value:   
            non_ngons.append([poly_id]) # Store it as a one item list to match format of ngons   
            continue   
          
        poly = polys[poly_id]   
        poly_info = neighbor.GetPolyInfo(poly_id)   
          
        for side in xrange(4) :          
            # Skip the fourth "edge" of triangles.   
            if side==2 and (poly.c == poly.d) :   
               continue   
               
            edge = None   
               
            if side == 0:   
               edge = (poly.a, poly.b)   
            elif side == 1:   
               edge = (poly.b, poly.c)   
            elif side == 2:   
               edge = (poly.c, poly.d)   
            elif side == 3:   
               edge = (poly.d, poly.a)   
                       
            # N-Gon Edge   
            if not (edge_value & (1 << side) == 0) :   
               if poly_id not in ngon_polys:   
                    ngon_polys.append(poly_id)   
                        
               # Get the neighborning hidden ngon poly, should be safe to assume there will always be one.   
               adjacent_poly = neighbor.GetNeighbor(edge[0], edge[1], poly_id)   
                 
               if ngons is None:   
                    ngon = [poly_id, adjacent_poly]   
                    ngons = [ngon]   
               else:   
                    # Add this polygon to an existing set if one exists   
                    present = False   
                    print "ngons: ", ngons   
                    for i, poly_set in enumerate(ngons) :   
                        print "poly_set: ", poly_set   
                           
                        if adjacent_poly in poly_set:   
                            ngons[i] = ngons[i][:] + [poly_id]   
                            present = True   
                               
                    if not present:   
                        ngons.append([poly_id, adjacent_poly])   
                 
        for i, poly_set in enumerate(ngons) :   
            ngons[i] = list(set(ngons[i]))   
               
       
    ngons = ngons + non_ngons   
       
    return ngons   

On 28/04/2017 at 03:42, xxxxxxxx wrote:

Interesting method Donovan.
But it appear to be slower than my method get_ngonv3
http://www.plugincafe.com/\forum/forum_posts.asp?TID=13225&PID=52347#52347

Here you have an ugly benchmarking with both version https://pastebin.com/3s8UbwDv
But your version don't need to have op in a doc.
Anyway thanks for sharing.
I guess the ngon class is really something missing in the python SDK.