Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode.
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
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.
CalculateVisiblePoints
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