Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    c4d threading runs only on one core and is slower than single threaded

    Cinema 4D SDK
    python
    2
    2
    750
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • P
      pyr
      last edited by

      put this code in a python generator and place any polygon object under it. run it single threaded , then increase the maxThreads.

      it is significant slower when maxThreads > 1.

      import c4d
      import math
      import time
      #Welcome to the world of Python
      
      
      
      RootNull = c4d.BaseObject(c4d.Onull)
      
      
      
      def currStateToObject(source):
      	
      	return c4d.utils.SendModelingCommand(
      		 command = c4d.MCOMMAND_CURRENTSTATETOOBJECT,
      		 list = [source],
      		 mode=c4d.MODELINGCOMMANDMODE_ALL,
      		 bc=c4d.BaseContainer(),
      		 doc = doc)[0]   
      
      def connectDelete(source):
       
      	return c4d.utils.SendModelingCommand(
      		 command = c4d.MCOMMAND_JOIN,
      		 list = [source],
      		 mode=c4d.MODELINGCOMMANDMODE_ALL,
      		 bc=c4d.BaseContainer())[0] 
      
      	
      class ThreadedCut(c4d.threading.C4DThread):
      
      	def TestBreak(self):
      		return None
      
      	def __init__(self, sList):    
      		print "thread init"
      		self.sList = sList
      	
      	def Main(self):
      		print "thread start"
      		for s in self.sList:
      			
      			self.CutObject(s)
      		print "thread finish"
      	
      	def CutObject(self,s):
      		
      		global objReference
      	   
      		# create a copy 
      	
      		obj = objReference.GetClone()
      		
      		
      		allPoints = obj.GetAllPoints()
      	
      	
      		bbox = obj.GetRad()  
      		
      		p1 = c4d.Vector(bbox.x*10,s,bbox.z*10)
      		v1 = c4d.Vector(bbox.x*10,0,bbox.z*-10)
      		p2 = c4d.Vector(bbox.x*-10,0,bbox.z*10)
      		v2 = c4d.Vector(bbox.x*-10,0,bbox.z*-10)
      		
      		data = c4d.BaseContainer()
      		data.SetVector(c4d.MDATA_KNIFE_P1, p1)
      		data.SetVector(c4d.MDATA_KNIFE_P2, p2)
      		data.SetVector(c4d.MDATA_KNIFE_V1, v1)
      		data.SetVector(c4d.MDATA_KNIFE_V2, v2)
      		
      		c4d.utils.SendModelingCommand(c4d.MCOMMAND_KNIFE, [obj], bc=data, doc=doc)
      		newPoints = obj.GetAllPoints()
      		
      		pointSelection = obj.GetPointS()
      		for i in range(len(allPoints),len(newPoints)):
      			pointSelection.Select(i)
      			
      		bc = c4d.BaseContainer()
      		bc.SetData(c4d.MDATA_CONVERTSELECTION_LEFT, 0)
      		bc.SetData(c4d.MDATA_CONVERTSELECTION_RIGHT, 1)
      		bc.SetData(c4d.MDATA_CONVERTSELECTION_TOLERANT, False)
      		c4d.utils.SendModelingCommand(c4d.MCOMMAND_CONVERTSELECTION, [obj], bc=bc, doc=doc)
      		c4d.utils.SendModelingCommand(c4d.MCOMMAND_EDGE_TO_SPLINE, [obj])
      		if obj.GetDown():
      			return obj.GetDown().InsertUnder(RootNull)
      		return None
      
      
      
      	
      def chunkIt(seq, num):
      	"""
      	https://stackoverflow.com/questions/2130016/splitting-a-list-into-n-parts-of-approximately-equal-length/37414115
      	"""
      	avg = len(seq) / float(num)
      	out = []
      	last = 0.0
      
      	while last < len(seq):
      		out.append(seq[int(last):int(last + avg)])
      		last += avg
      
      	return out   
      
      
      
      objReference = None
      
      
      def main():
      	
      	global objReference
      	runningThreads = 0    
      	starttime = time.time()
      	
      	obj = currStateToObject(op.GetDown())  
      	objReference = obj
      	
      	maxThreads = 1
      	
      	minHeight = -200
      	maxHeight = 200
      	offset = 0.5
      	maxSlices = 10000
      	sliceList= []
      	
      	
      	for i in range(0,maxSlices):
      		s =  minHeight + i*offset
      		if (s <= maxHeight and s < obj.GetRad().y*2):            
      			sliceList.append(s)
      		else:
      			break
      			
      	chunks = chunkIt(sliceList,maxThreads)    
      	
      	tList = []
      	
      	for c in chunks: 
      		print len(c),len(sliceList)
      		t = ThreadedCut(c)        
      		tList.append(t)
      		
      	print "threadlist rdy"
      	for t in tList:       
      		t.Start()
      
      	for t in tList:      
      		t.Wait(True)
      	  
      	
      	spline = connectDelete(RootNull)
      	spline[c4d.SPLINEOBJECT_TYPE] = 3
      	spline[c4d.SPLINEOBJECT_CLOSED] = True
      	
      	end = time.time()
      	print end-starttime
      	return spline
      
      1 Reply Last reply Reply Quote 0
      • M
        m_adam
        last edited by m_adam

        Hi @pyr,

        In Python, there is a GIL which do not allow Python by design to execute something in parallel.

        In Cinema 4D all our functions (so everything which is in the c4d python module) is "GIL safe" in order to avoid any issue with Python memory.
        So in Cinema 4D thread are designed for doing GUI, or background stuff.
        Moreover, keep in mind creating a Thread have a cost in term of time (to create, execute, delete them).

        Finally, I would like to point you to multiprocessing vs multi-threading.

        Note that since it's more an algorithm problem than an issue related to our API, we can only provide you hints.

        btw, I also turned your topic as a question. See Q&A New Functionality.
        Cheers,
        Maxime.

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

        1 Reply Last reply Reply Quote 3
        • First post
          Last post