<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Convert 3D space to 2D Space]]></title><description><![CDATA[<p dir="auto"><em>On 04/07/2018 at 03:36, <strong>xxxxxxxx</strong> wrote:</em></p>
<p dir="auto">Hey Everyone,</p>
<p dir="auto">Just wanted to know if anyone can point me in the right direction.</p>
<p dir="auto">Im looking to convert a 3D (world) space, point co-ordinate into a 2D camera space co-ordinate.</p>
<p dir="auto">Is this possible with the python SDK?</p>
<p dir="auto">Any info or a nudge in the right direction is much appreciated!</p>
<p dir="auto">Cheers,</p>
<p dir="auto">Cerac</p>
]]></description><link>http://developers.maxon.net/forum/topic/10857/14298_convert-3d-space-to-2d-space</link><generator>RSS for Node</generator><lastBuildDate>Sun, 19 Apr 2026 22:22:48 GMT</lastBuildDate><atom:link href="http://developers.maxon.net/forum/topic/10857.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 01 Sep 2018 10:45:30 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Convert 3D space to 2D Space on Sat, 01 Sep 2018 10:45:45 GMT]]></title><description><![CDATA[<p dir="auto"><em>On 11/07/2018 at 01:05, <strong>xxxxxxxx</strong> wrote:</em></p>
<p dir="auto">Thanks Maxime,</p>
<p dir="auto">i got there in the end, my solution was far less elegant than yours though, so thank you for spending the time to look through my code, i can certainly learn lots from your approach.</p>
<p dir="auto">Apologies also for my scrappy code - there was parts in there that made no sense whatsoever so kudos for managing to read through that.</p>
<p dir="auto">I'll post my solution below for reference but anyone who references this thread should definitely go with Maximes above suggestion.</p>
<pre><code>def screenCalc(guide, cZ, bd, sf, rd_w, rd_h) :  
        
        
  gPos = guide.GetMg().off  # get global position of guide  
  convertPos = bd.WS(gPos)  # convert world to screen space  
  
        
  # Perform safe zone maths  
  convertPos[0] = (convertPos[0] - sf["cl"])/(sf["cr"]-sf["cl"])  
  convertPos[1] = (convertPos[1] - sf["ct"])/(sf["cb"]-sf["ct"])  
  convertPos[2] = (cZ - convertPos[2])/cZ    
        
  gV1 = convertPos[0]  # get x from vector  
  gV2 = convertPos[1]  # get y from vector  
  
        
  # Remaps vector values to screenspace values, aswell as inverts  
  g_Xpos = c4d.utils.RangeMap(gV1, 0, 1, 0, rd_w, True)  
  INVg_Xpos = c4d.utils.RangeMap(gV1, 1, 0, 0, rd_w, True)  
    
  g_Ypos = c4d.utils.RangeMap(gV2, 0, 1, 0, rd_h, True)  
  INVg_Ypos = c4d.utils.RangeMap(gV2, 1, 0, 0, rd_h, True)  
    
  # Loads final values into a list and returns it  
  pos = [int(g_Xpos), int(INVg_Xpos), int(g_Ypos), int(INVg_Ypos)]  
        
  return pos  
  
  
def main() :  
    
  # +------- GET DOCUMENT DATA --------#  
    
  bd = doc.GetActiveBaseDraw()                 # Get current view  
  rd = doc.GetActiveRenderData()               # Get Render Setting  
  rd_w = rd[c4d.RDATA_XRES_VIRTUAL]            # Get X resolution  
  rd_h = rd[c4d.RDATA_YRES_VIRTUAL]            # Get Y resolution  
  sf = bd.GetSafeFrame()                       # Get SafeFrame dims  
    
  # +------- GET CUSTOM DATA --------#  
  obj = op.GetObject()                         # Get Null  
  cam = obj[c4d.ID_USERDATA,2]                 # Get Camera  
  top = obj[c4d.ID_USERDATA,3]                 # GetGuideObjects  
  bottom = obj[c4d.ID_USERDATA,7]              # --------------  
  left = obj[c4d.ID_USERDATA,8]                # --------------  
  right = obj[c4d.ID_USERDATA,9]               # --------------  
  switch = obj[c4d.ID_USERDATA,4]              # Get Switch  
  cZ = cam[c4d.CAMERAOBJECT_TARGETDISTANCE]    # Get z-distance  
  
  # If tag is activated  
    
  if switch:  
        
      # Use function to grab data  
      try:     
          topPos = screenCalc(top, cZ, bd, sf, rd_w, rd_h)  
          bottomPos = screenCalc(bottom, cZ, bd, sf, rd_w, rd_h)  
          leftPos = screenCalc(left, cZ, bd, sf, rd_w, rd_h)  
          rightPos = screenCalc(right, cZ, bd, sf, rd_w, rd_h)  
            
          # SET RENDER DATA  
          rd[c4d.RDATA_RENDERREGION_TOP] = topPos[2]  
          rd[c4d.RDATA_RENDERREGION_BOTTOM] = bottomPos[3]  
          rd[c4d.RDATA_RENDERREGION_LEFT] = leftPos[0]  
          rd[c4d.RDATA_RENDERREGION_RIGHT] = rightPos[1]  
  
          doc.SetActiveRenderData(rd)  
          c4d.EventAdd()  
        
      except ZeroDivisionError:  
          pass  
  else:  
      pass  

</code></pre>
<p dir="auto">Thanks again,</p>
<p dir="auto">Cerac</p>
]]></description><link>http://developers.maxon.net/forum/post/55202</link><guid isPermaLink="true">http://developers.maxon.net/forum/post/55202</guid><dc:creator><![CDATA[Helper]]></dc:creator><pubDate>Sat, 01 Sep 2018 10:45:45 GMT</pubDate></item><item><title><![CDATA[Reply to Convert 3D space to 2D Space on Sat, 01 Sep 2018 10:45:42 GMT]]></title><description><![CDATA[<p dir="auto"><em>On 09/07/2018 at 07:09, <strong>xxxxxxxx</strong> wrote:</em></p>
<p dir="auto">Hi Ceracticus,</p>
<p dir="auto">Actually, WS already take care of the film offset, so you just have to do something like that.</p>
<pre><code>    rd = doc.GetActiveRenderData()
    rd_w = rd[c4d.RDATA_XRES_VIRTUAL]
    rd_h = rd[c4d.RDATA_YRES_VIRTUAL]
    
    bd = doc.GetActiveBaseDraw()
    viewX = bd.GetFrame()["cr"]
    viewY = bd.GetFrame()["cb"]
    sf = bd.GetSafeFrame() #SafeFrame
    cam = bd.GetSceneCamera(doc)
  
    top = doc.GetFirstObject().GetMg().off
    bot = doc.GetFirstObject().GetNext().GetMg().off
    left = doc.GetFirstObject().GetNext().GetNext().GetMg().off
    right = doc.GetFirstObject().GetNext().GetNext().GetNext().GetMg().off
  
	# Get pixels counts between top obj and the frame, then scale this pixel count according to the ratio between viewport size and render size.
    top_p = max(0, bd.WS(top).y - sf["ct"]) * rd_h / viewY 
    bot_p = max(0, sf["cb"] - bd.WS(bot).y) * rd_h / viewY
    left_p = max(0, bd.WS(left).x - sf["cl"]) * rd_w / viewX
    right_p = max(0, sf["cr"] - bd.WS(right).x) * rd_w / viewX
    
    rd[c4d.RDATA_RENDERREGION_TOP] = int(top_p)
    rd[c4d.RDATA_RENDERREGION_BOTTOM] = int(bot_p)
    rd[c4d.RDATA_RENDERREGION_LEFT] = int(left_p)
    rd[c4d.RDATA_RENDERREGION_RIGHT] = int(right_p)
    
    c4d.EventAdd()
</code></pre>
<p dir="auto">On a side topic, please use [ code] [ /code] to insert code in your post, it increases the readability of them.</p>
<p dir="auto">If you have any question, please let me know.<br />
Cheers,<br />
Maxime</p>
]]></description><link>http://developers.maxon.net/forum/post/55201</link><guid isPermaLink="true">http://developers.maxon.net/forum/post/55201</guid><dc:creator><![CDATA[Helper]]></dc:creator><pubDate>Sat, 01 Sep 2018 10:45:42 GMT</pubDate></item><item><title><![CDATA[Reply to Convert 3D space to 2D Space on Sat, 01 Sep 2018 10:45:39 GMT]]></title><description><![CDATA[<p dir="auto"><em>On 05/07/2018 at 09:53, <strong>xxxxxxxx</strong> wrote:</em></p>
<p dir="auto">Hey Both,</p>
<p dir="auto">thanks so much for your suggestions, massively helpful.</p>
<p dir="auto">Managed to get 90% of the way with looking up other examples on this site, plus your feedback which is really great.</p>
<p dir="auto">What im essentially doing is rebuilding the interactive render region crop function out of guides (converted from world to screen space) then plugging these values into the active render setting.</p>
<p dir="auto">Ive got everything working as expected - apart from when a camera has film offset. I know i can access this data which is great.</p>
<p dir="auto"><code>[c4d.CAMERAOBJECT_FILM_OFFSET_Y]``` </code>[c4d.CAMERAOBJECT_FILM_OFFSET_X]`</p>
<p dir="auto">Does anyone know what the best way of taking this into account whilst running my code?</p>
<pre><code>  
def main() :  
    
  
  rd = doc.GetActiveRenderData()  
  rd_w = rd[c4d.RDATA_XRES_VIRTUAL]  
  rd_h = rd[c4d.RDATA_YRES_VIRTUAL]  
  bd = doc.GetActiveBaseDraw()       # Get current view  
  sf = bd.GetSafeFrame() #SafeFrame  
  
  obj = op.GetObject()               # Get Null  
  cam = obj[c4d.ID_USERDATA,2]       # Get Camera  
  top = obj[c4d.ID_USERDATA,3]       # GetGuideObjects  
  bottom = obj[c4d.ID_USERDATA,7]  
  left = obj[c4d.ID_USERDATA,8]  
  right = obj[c4d.ID_USERDATA,9]  
  switch = obj[c4d.ID_USERDATA,4]           # Get Switch  
  cZ = cam[c4d.CAMERAOBJECT_TARGETDISTANCE] #z-distance  
  
  if switch:  
  
      # +-------------------------- TOP IRR  
    
      topPos = top.GetMg().off #top global position  
      top_v = bd.WS(topPos) #World2Screen  
    
    
      top_v[0] = (top_v[0] - sf["cl"])/(sf["cr"]-sf["cl"])  
      top_v[1] = (top_v[1] - sf["ct"])/(sf["cb"]-sf["ct"])  
      top_v[2] = (cZ-top_v[2])/cZ  
  
      top_pos = top_v[1] #Gets Y pos from vector  
  
      # Rangemap the result to IRR space  
      irrTop_min = c4d.utils.RangeMap(top_pos, 0, 1, 0, rd_h, True)  
      irrTop_max = 0  
    
      # If its over halfway - reverse it  
      if irrTop_min &gt;= (rd_h/2) :  
          irrTop_max = c4d.utils.RangeMap(irrTop_min, rd_h, rd_h/2, 0, rd_h/2,True)   
          rd[c4d.RDATA_RENDERREGION_TOP] = int(irrTop_max)  
        
      else:  
          pass
</code></pre>
<p dir="auto">Thanks again!</p>
<p dir="auto">Cerac</p>
]]></description><link>http://developers.maxon.net/forum/post/55200</link><guid isPermaLink="true">http://developers.maxon.net/forum/post/55200</guid><dc:creator><![CDATA[Helper]]></dc:creator><pubDate>Sat, 01 Sep 2018 10:45:39 GMT</pubDate></item><item><title><![CDATA[Reply to Convert 3D space to 2D Space on Sat, 01 Sep 2018 10:45:36 GMT]]></title><description><![CDATA[<p dir="auto"><em>On 05/07/2018 at 02:12, <strong>xxxxxxxx</strong> wrote:</em></p>
<p dir="auto">Hi Ceracticus,</p>
<p dir="auto">As Daniel already pointed you <a href="https://developers.maxon.net/docs/py/2023_2/modules/c4d/C4DAtom/GeListNode/BaseList2D/BaseView/index.html?highlight=wc#BaseView.WC" target="_blank" rel="noopener noreferrer nofollow ugc">BaseView.WC</a> and <a href="https://developers.maxon.net/docs/py/2023_2/modules/c4d/C4DAtom/GeListNode/BaseList2D/BaseView/index.html?highlight=wc#BaseView.WC_V" target="_blank" rel="noopener noreferrer nofollow ugc">BaseView.WC_V</a> is the way to go.</p>
<p dir="auto">Additionally, I would like to point you to the <a href="https://developers.maxon.net/docs/cpp/2023_2/page_manual_basedraw.html" target="_blank" rel="noopener noreferrer nofollow ugc">C++ manual</a> which can give you some valuable information even for python.</p>
<p dir="auto">Cheers,<br />
Maxime</p>
]]></description><link>http://developers.maxon.net/forum/post/55199</link><guid isPermaLink="true">http://developers.maxon.net/forum/post/55199</guid><dc:creator><![CDATA[Helper]]></dc:creator><pubDate>Sat, 01 Sep 2018 10:45:36 GMT</pubDate></item><item><title><![CDATA[Reply to Convert 3D space to 2D Space on Sat, 01 Sep 2018 10:45:33 GMT]]></title><description><![CDATA[<p dir="auto"><em>On 04/07/2018 at 12:22, <strong>xxxxxxxx</strong> wrote:</em></p>
<p dir="auto">Check out the BaseView class<br />
BaseView::WC() or BaseView::WC_V() is what you most likely are looking for.</p>
]]></description><link>http://developers.maxon.net/forum/post/55198</link><guid isPermaLink="true">http://developers.maxon.net/forum/post/55198</guid><dc:creator><![CDATA[Helper]]></dc:creator><pubDate>Sat, 01 Sep 2018 10:45:33 GMT</pubDate></item></channel></rss>