Navigation

    • Register
    • Login
    • Search
    • Categories
    1. Home
    2. mogh
    M
    • Profile
    • Following
    • Followers
    • Topics
    • Posts
    • Best
    • Groups

    mogh

    @mogh

    Industrial Designer, Product Visualization, a slight itch for scripting.

    1
    Reputation
    44
    Posts
    78
    Profile views
    0
    Followers
    0
    Following
    Joined Last Online
    Location South Germany

    mogh Follow

    Posts made by mogh

    • RE: Find Plugin remains by Plugin ID and delete - how to tacle.

      I just had time to check this hence the holidays.

      This works with the correct ID (1036219 = Redshift) the nodes render my "cleaned" C4D file again.

      Thank you very much @m_magalhaes

      kind regards
      mogh

      posted in Cinema 4D Development
      M
      mogh
    • RE: Find Plugin remains by Plugin ID and delete - how to tacle.

      Thanks you for your reply,

      interesting never noticed that there is a post effekt called redshift in the standard renderer . will need to check that, I always swith from physical to redshift and back.

      the id is probably just the post effect not the redshift plugin ID I posted. - anyway

      if I could solve the problem by deleting the post effect i am happy also
      will check

      anyway thanks

      posted in Cinema 4D Development
      M
      mogh
    • Find Plugin remains by Plugin ID and delete - how to tacle.

      Dear developpers,

      I ran into a problem at work where remains of a plugin ( 'Redshift' (ID 1036219)) prevents me to render on my renderfarm. FYI the scene has no shader nor Objects which relate to Redshift anymore, I also copied everything to a new file the Renderfarm still throws a plugin error.

      My Idea is to write a script myself to delete remaining Plugin Data which is probabbly just a basecontainer with the ID.

      So how do I search for the basecontainer by ID and delete it (which could be wrong/dangerous but this is my idea at the moment)

      thank you for your time
      kind regards
      mogh

      posted in Cinema 4D Development
      M
      mogh
    • RE: Getting poly normal and CreatePhongNormals()

      Thanks for the reply, Wicked.

      interessting, but not what i hoped for ... ;-)

      kepp on chrunching

      posted in Cinema 4D Development
      M
      mogh
    • RE: Option to wait for c4d to catch up with script ? Memory wise and EventAdd?

      did sent email with raw data

      kind regards
      mogh

      posted in Cinema 4D Development
      M
      mogh
    • RE: Option to wait for c4d to catch up with script ? Memory wise and EventAdd?

      @zipit said in Option to wait for c4d to catch up with script ? Memory wise and EventAdd?:

      I would invite you to provide some test data

      You can reproduce a heavy data import by putting my object sent to you into a cloner (5x1x5 ... or even more) and convert it (C). No need to send hundreds of megabites through email.

      Use your script not my mess if you like.

      kind regards
      mogh

      posted in Cinema 4D Development
      M
      mogh
    • RE: Help with Matrix Manipulation after c4d.MCOMMAND_JOIN

      I am building of your script from here on. Thank You.

      FYI zipit:
      While your def get_nodes_by_name(doc, patterns) might be saver and more sound it takes 10x longer then my version to collect all axis ... (which is not the slow party of the script and could be neglegted - I was just buffled by the profiling i ran)

      kind regards
      mogh

      posted in Cinema 4D Development
      M
      mogh
    • RE: Option to wait for c4d to catch up with script ? Memory wise and EventAdd?

      slightly,

      the waiting is now in the beginning, with no or sporadic statusbar updates in between and some waiting at the end.

      While this seems fine in a generall sense hence the script now takes its time more reasonably, its a bummer that I cannot inform the user about the status of the script in a meaningfull manner.

      C4D "hangs and calculates" and is fnished at some point. If I did not know better I would suspect C4D to be crashed and kill it as a user.

      I suspect that the c4d.utils.SendModelingCommand does not allow a better solution at this point and only a selfmade C++ version would.


      Also my hopes for a faster script are shattered, hence the simplified script you posted takes more or less the same time (console reports 10sec but its actually 20seconds) as my 5 year old callcomand script (also 20 seconds) which is a bummer.

      I am still a bit lost on how to pursue my "optimzing scripts" endeavor at this point. (which is off topic here).

      nevertheless, thank you for your time

      kind regards
      mogh

      posted in Cinema 4D Development
      M
      mogh
    • RE: CAD Normal Tag flipped after Polyon merge (join) and axis repositioning - how realign?

      thank you zipit,

      as I am totally fine with a less heavy version (from the other thread) I would mark this as solved.

      I still want to Thank you for all the other people which might need the actuall NormalTag manipulation in the future.

      kind regards
      mogh

      posted in Cinema 4D Development
      M
      mogh
    • RE: Option to wait for c4d to catch up with script ? Memory wise and EventAdd?

      hi zipit, no worries,
      thank you for your time!

      Yes it is misterious, thats why I asked so vague. You can reproduce a heavy data import by putting my object sent to you into a cloner (5x1x5) and convert it (CSO) -
      Running the below script takes about 4 seconds to run and about 1Minute plus to display with the same weird finished but not fnished behavior.

      Use below script, set your C4D to only have one window otherwise I have status bar issues!
      The status bar displays when its fnished with main() the console lags behind but displays 4 secons !

      Latest Version, difference to the slim version is mainly with some quality of live code.

      by the way, scripts running for 1hour + are no strangers here - we often start them over night ... thats kinda normal the behavior is not
      kind regards mogh

      #!py3
      import c4d, sys, os, math
      from c4d import gui
      from c4d.documents import GetActiveDocument
      #Version 1.5
      
      import cProfile, pstats 
      #import time
      def profile(func):
          # A simple profiling decorator.
          profiler = cProfile.Profile()
      
          def wrapper(*args, **kwargs):
              result = None
              try:
                  result = profiler.runcall(func, *args, **kwargs)
              except Exception as error:
                  raise error
              finally:
                  stats = pstats.Stats(profiler)
                  # To get the full profile do this.
                  stats.strip_dirs().sort_stats("cumtime").print_stats()
                  t = round(stats.total_tt, 3)
                  #print (f"{func.__name__} took {t} sec.\n")
              return result
          return wrapper
      
      #@profile
      def gime_time (milliseconds):
          hours,milliseconds = divmod(milliseconds, 3600000)
          minutes, milliseconds = divmod(milliseconds, 60000)
          seconds = float(milliseconds) / 1000
          s = "%i:%02i:%06.3f" % (hours, minutes, seconds)
          return s
      
      #@profile
      def GetNextObject(op):
          if not op: return
          if op.GetDown(): return op.GetDown()
          while op.GetUp() and not op.GetNext():
              op = op.GetUp()
          return op.GetNext()
      
      #@profile
      def get_all_objects (op):
          allachsen_list = list()
          all_objects_list = list()
          while op:
              if op.GetName() == 'Achsen-Objekt' or op.GetName() == 'Axis' :
                  allachsen_list.append(op)
              all_objects_list.append(op)
              op = GetNextObject(op)
          #return {'all_objects_list' : all_objects}, allachsen
          return all_objects_list, allachsen_list
      
      #@profile
      def statusbar (counter, secondcounter):
          #print (secondcounter, int((100*secondcounter)/counter) )
          if int((100*secondcounter)/counter) in [10,20,30,40,50,60,70,80,90,100]:
              #print("Textupdate at: ", int((100*secondcounter)/counter))
              c4d.StatusSetText ('%s - %s Objects are processed.' %(secondcounter, counter))
          c4d.StatusSetBar(int(100*secondcounter/counter)) #statusbar
          #c4d.gui.GeUpdateUI()
      
      def savetorun(checkSelection = False):
          try:
              doc = GetActiveDocument()
          except Exception as e:
              print (e)
              raise TypeError("No Active Document!")
              exit()
              return False
      
          try:
              op = doc.GetFirstObject()
          except Exception as e:
              print (e)
              c4d.StatusSetText ('No Objects, nothing to do here.')
              raise TypeError("No Objects, nothing to do here.")
              exit()
              return False
      
          selected = None
          if checkSelection == True:
              selected = doc.GetActiveObject()
              if selected == None:
                  c4d.StatusSetText ('No Object/s selected, nothing to do here.')
                  print ("No Object/s selected, nothing to do here.")
                  exit()
                  return False
      
          return doc, op, selected
      
      def savedoc(doc):
          path = doc.GetDocumentPath()
          name = doc.GetDocumentName()
          name = name[ :-4 ] + "_conectedaxis.c4d"
          filename = os.path.join(path, name)
          saveflags = (c4d.SAVEDOCUMENTFLAGS_DONTADDTORECENTLIST | c4d.SAVEDOCUMENTFLAGS_DIALOGSALLOWED)
          c4d.documents.SaveDocument(doc, filename, saveflags, format=c4d.FORMAT_C4DEXPORT)
      
      #@profile
      def JoinCommand(doc, op):
          """ Apply a join command to the object passe as argument
          :param      op: the object to apply current state to object to.
          :type: BaseObject
          :return: the result of the command or raise an error if command failed
          :rtype: BaseObject
          """
          # null = c4d.BaseObject(c4d.Onull)
          # #for o in op.GetChildren:
          # op.InsertUnder(null)
          #settings = c4d.BaseContainer()
          #settings[c4d.MDATA_JOIN_MERGE_SELTAGS] = True
          # bc = settings,
          
          res = c4d.utils.SendModelingCommand(command = c4d.MCOMMAND_JOIN,
                                      list = [op],
                                      mode = c4d.MODELINGCOMMANDMODE_ALL,                                
                                      doc = doc)
      
          # Cheks if the command didn't failed
          if res is False:
              raise TypeError("return value of Join command is not valid")
          elif res is True:
              print ("Command successful. But no object.")
          elif isinstance(res, list):
              #if c4d.GetC4DVersion() < 21000: res[0].SetAbsPos(c4d.Vector())
              op.Remove()
              return res[0] # Returns the first item containing the object of the list.  ??? GetClone() ???
          
      #@profile
      def set_point_object_transform(node, transform):
          """Sets the global transform of a point object while keeping its points in place.
      
          Args:
              node (c4d.PointObject): The point object to move the axis for.
              transform (c4d.Matrix): The new global transform for the object.
      
          Raises:
              TypeError: When node or transform are not of specified type.
          """
          if (not isinstance(node, c4d.PointObject) or
              not isinstance(transform, c4d.Matrix)):
              msg = f"Illegal argument types: {type(node)}{type(transform)}"
              raise TypeError(msg)
      
          #mg = node.GetMg()
          # Move the points in the global frame and then into the new frame.
          points = [p * ~transform for p in node.GetAllPoints()]
          # Set the points and stuff ;)
          node.SetAllPoints(points)
          node.Message(c4d.MSG_UPDATE)
          node.SetMg(transform)
          
      #@profile
      def joinmanagment(n):
          # n "Axis" null will be not alive in a few steps get everything we need from it
          if n.GetUp() :
              parent = n.GetUp()
          else:
              print ("No Parent To Axis Null. Probably not save to run this sript anyway.")
              c4d.StatusClear()
              c4d.StatusSetText ('No Parent found! - Probalby mo CAD import Doc. Script Stopped.')
              exit()
              return False
      
          newobject = JoinCommand(doc, n) # combine the poly objects
      
          if not newobject.IsAlive():
              raise TypeError("Object is not alive.")
              return False
      
          newobject.SetName(str(parent.GetName()))
          newobject.InsertUnder(parent)
          set_point_object_transform(newobject, n.GetMg()) # set points with global matrix from parent n "Axis"
      
      #@profile
      def main():
          c4d.CallCommand(13957) # Konsole löschen
          now = c4d.GeGetTimer() # start stopwatch
          # Savetorun: Set True to check for slected objects and get them returned or throw an error, otherwise slected is None.
          doc, op , selected = savetorun()
      
          c4d.StatusSetSpin()
          all_objects, allachsen = get_all_objects(op) # get two lists
      
          null_counter = len(allachsen)
      
          if null_counter == 0: # check if found something to do.
              c4d.StatusClear()
              c4d.StatusSetText ('No Axis Objects found, nothing to do here.')
              print ("No Axis Objects found, nothing to do here.")
              exit()
      
          counter = len(all_objects)
          secondcounter = 0
      
          print (counter,' Objects' ,'\n' ,null_counter,' Nulls and their children to connect' ,'\n' ,'----------------------------------------------------' )
          c4d.StatusSetText ('%s Objects are processed.' %(null_counter))
      
          for n in allachsen:
              secondcounter += 1
              statusbar(null_counter, secondcounter)
              joinmanagment(n)
              #if joinmanagment(n) == False:            break
      
          print ('----------------------------------------------------')
          print ('END OF SCRIPT %s ms ' %(gime_time(c4d.GeGetTimer() - now))   )
          #savedoc(doc)
          c4d.StatusClear()
          c4d.StatusSetText ('Script finished - C4D needs a while to diplay the new viewport?!')
          c4d.EventAdd()        # update cinema 4d
          return True
          
      if __name__=='__main__':
          main()
      
      posted in Cinema 4D Development
      M
      mogh