Is CalculateVisiblePoints() useable?
-
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 -
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
-
Thank you, Riccardo. That was exactly what I was doing wrong.
Dan