Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python 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

    Is CalculateVisiblePoints() useable?

    Cinema 4D SDK
    c++ r20 sdk
    2
    3
    431
    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.
    • D
      d_schmidt
      last edited by

      Hello, I'm trying to find all of the visible points from the point of view of a given BaseDraw. It seems like CalculateVisiblePoints() should be exactly what I need, but I'm not getting results that make any sense to me.

      It seems like the function would do exactly what I'm looking for and a search only turned up a thread about it not being available in Python from years ago. I've seen other threads about getting visible object points, but I wanted to see if CalculateVisiblePoints() would work before moving onto one of those.

      My tests have just involved a polygon cube and rotating around it, but the visible points aren't consistent with the view.

      My current code:

          BaseObject* child =op->GetDown();
          if(child== nullptr ||child->GetType() != Opolygon)
          {
              return;
          }
         
          PolygonObject* polyobj = static_cast<PolygonObject*>(child);
          BaseDraw* bd = doc->GetActiveBaseDraw();
          if(bd==nullptr)
          {
              return;
          }
          Vector* vectors = polyobj->GetPointW();
          UChar* results;
          if (CalculateVisiblePoints(bd, polyobj, vectors, results, TRUE) == FALSE)
          {
              return;
          }
         
          Int32 pointcount =polyobj->GetPointCount();
          for (Int32 x=0; x<pointcount; x++)
          {
              
              if (results[x] ==1)
              {
                  ApplicationOutput(String::IntToString(x) + " Visible");
              }
              else if (results[x] ==0)
              {
                  ApplicationOutput(String::IntToString(x) + " Not Visible");
              }
              else
              {
                  ApplicationOutput("-Empty-");
              }
              
          }
      

      Thanks for any help,
      Dan

      1 Reply Last reply Reply Quote 0
      • r_giganteR
        r_gigante
        last edited by r_gigante

        Hi Daniel, thanks for reaching out us.

        With regard to your issue, the question is what values we are passing to the CalculateVisiblePoints. The function is actually designed to receive an array specifying the world position of points in camera space. On top of this the function is supposed to receive a result array initialized to 1.

        For your convenience the solution should look like:

        	// check passed parameter
        	if (!doc)
        		return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION);
        	
        	// check for an active object
        	BaseObject* op = doc->GetActiveObject();
        	if (!op)
        		return maxon::OK;
        	
        	// check for current BaseDraw
        	BaseDraw* activeBD = doc->GetActiveBaseDraw();
        	if (!activeBD)
        		return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
        	
        	// check it's an instance of a Opolygon
        	if (!op->IsInstanceOf(Opolygon))
        		return maxon::OK;
        	
        	// cast active BaseObject in PolygonObject
        	PolygonObject* polyobj = static_cast<PolygonObject*>(op);
        	
        	// get the point count
        	const Int32 pointCount = polyobj->GetPointCount();
        	if (pointCount == 0)
        		return maxon::OK;
        	
        	// get the active object points
        	const Vector* points = (Vector*)polyobj->GetPointR();
        	if (!points)
        		return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
        	
        	// allocate a temporary array of points (same count of active object points)
        	Vector* pointFromCam = nullptr;
        	pointFromCam = NewMem(Vector, pointCount) iferr_return;
        	
        	// calculate the a transformation of the active object as seen from the camera
        	Matrix mgObjFromCamera = activeBD->GetMi() * polyobj->GetMg();
        	
        	// fill the temporary array of points with active object points as seen from the camera space
        	for (Int32 p = 0; p < pointCount; p++)
        		pointFromCam[p] = mgObjFromCamera * points[p];
        	
        	// allocate an array to store the result of the visiblity check
        	UChar *pointVisRes = nullptr;
        	pointVisRes = NewMem(UChar, pointCount) iferr_return;
        	
        	// fill the visibility result array with 1
        	FillMemType(UChar, pointVisRes, pointCount, 1);
        	
        	// execute the visibility check
        	Bool res = CalculateVisiblePoints(activeBD, polyobj, pointFromCam, pointVisRes, true);
        	if (!res)
        	{
        		DeleteMem(pointFromCam);
        		DeleteMem(pointVisRes);
        		return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
        	}
        	
        	// return the results in a more convenient format
        	maxon::String resString;
        	for (Int i = 0; i < polyobj->GetPointCount(); i++)
        		resString += FormatString(" @"_s, maxon::Int(pointVisRes[i]));
        	
        	// print the output
        	ApplicationOutput("visibility array:"_s + resString);
        	
        	// free the allocated resources
        	DeleteMem(pointFromCam);
        	DeleteMem(pointVisRes);
        	
        	return maxon::OK;
        

        Finally this stuff in Python is:

            if doc is None:
                return
        
            if op is None:
                return
        
            activeBD = doc.GetActiveBaseDraw()
            if activeBD is None:
                return
        
            visres = c4d.utils.CalculateVisiblePoints(activeBD, op, True)
            
            print visres
        

        Best, Riccardo

        1 Reply Last reply Reply Quote 1
        • D
          d_schmidt
          last edited by

          Thank you, Riccardo. That was exactly what I was doing wrong.

          Dan

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