As part of my quest to improve the FBX export of Cinema 4D I've been asked to do some automatic cleanup of meshes before the export.
I'm using several calls of
SendModelingCommand() to perform these clean up operations. The requested commands are:
Optimize and Align Normals are run on every polygonal object as checked with
IsInstanceOf(c4d.Opolygon). Reverse Normals is run selectively only on meshes with no boundary edges (i.e. closed meshes) whose normals are pointing inward. I can get all of these to work properly in simple test documents, but when I test it with a full fledged production scene the
c4d.MCOMMAND_REVERSENORMALS calls fail and
False. Is there anyway to get more information about why
SendModelingCommand() is failing?
Here's the applicable part of my code:
if self.align: poly_objs = [o for o in self._GetAllObjects(self.doc.GetFirstObject()) if o.IsInstanceOf(c4d.Opolygon)] c4d.StopAllThreads() #Not sure if this is necessary res = c4d.utils.SendModelingCommand(c4d.MCOMMAND_ALIGNNORMALS, poly_objs, doc=self.doc) #Align normals for all polygon objects if res: print("Successfully aligned normals.") #Works in simple scenes else: print("Could not align normals.") #Doesn't work in production scenes if self.reverse: closed_objs = [o for o in poly_objs if self._IsClosedMesh(o)] reversed_objs = [o for o in closed_objs if self._IsReversed(o)] c4d.StopAllThreads() res = c4d.utils.SendModelingCommand(c4d.MCOMMAND_REVERSENORMALS, reversed_objs, doc=self.doc) #Reverse the normals of all closed polygon objects whose normals are currently reversed if res: print("Successfully fixed reversed normals.") #Works in simple scenes else: print("Could not fix reversed normals.") #Doesn't work in production scenes if self.optimize: poly_objs = [o for o in self._GetAllObjects(self.doc.GetFirstObject()) if o.IsInstanceOf(c4d.Opolygon)] tool_bc = c4d.BaseContainer() tool_bc[c4d.MDATA_OPTIMIZE_UNUSEDPOINTS] = True c4d.StopAllThreads() res = c4d.utils.SendModelingCommand(c4d.MCOMMAND_OPTIMIZE, poly_objs, bc=tool_bc, doc=self.doc) #Optimize unused points for all polygon objects if res: print("Successfully removed unused points.") #This one works in production scenes too! For some reason? else: print("Could not remove unused points.")
Edit: there are 1200 or so polygonal objects in the production scene, only 3 of them are closed meshes with reversed normals. I doubt it's an issue of list length. Many of the polygonal objects are children of generators (Symmetry, Cloner, Subdivision Surface) but I can't imagine that should make a difference.