void SOP_PrimGroupCentroid::boundingBox(const GU_Detail *input_geo, GA_Range &pr_range, const GA_PrimitiveList &prim_list, UT_Vector3 &pos) { GA_Range pt_range; UT_BoundingBox bbox; // Initialize the bounding box to contain nothing and have // no position. bbox.initBounds(); // Iterate over each primitive in the range. for (GA_Iterator pr_it(pr_range); !pr_it.atEnd(); ++pr_it) { // Get the range of points for the primitive using the // offset from the primitive list. pt_range = prim_list.get(*pr_it)->getPointRange(); // For each point in the primitive, enlarge the bounding // box to contain it. for (GA_Iterator pt_it(pt_range); !pt_it.atEnd(); ++pt_it) bbox.enlargeBounds(input_geo->getPos3(*pt_it)); } // Extract the center. pos = bbox.center(); }
void OctreeBox::Split() { C = new OctreeBox[8]; for(int i=0;i<8;i++) { C[i].level=level-1; }; UT_Vector3 c = bbox.center(); UT_Vector3 m = bbox.minvec(); UT_Vector3 M = bbox.maxvec(); C[0].bbox = UT_BoundingBox(m.vec[0],m.vec[1],m.vec[2],c.vec[0],c.vec[1],c.vec[2]); C[1].bbox = UT_BoundingBox(c.vec[0],m.vec[1],m.vec[2],M.vec[0],c.vec[1],c.vec[2]); C[2].bbox = UT_BoundingBox(m.vec[0],c.vec[1],m.vec[2],c.vec[0],M.vec[1],c.vec[2]); C[3].bbox = UT_BoundingBox(m.vec[0],m.vec[1],c.vec[2],c.vec[0],c.vec[1],M.vec[2]); C[4].bbox = UT_BoundingBox(m.vec[0],c.vec[1],c.vec[2],c.vec[0],M.vec[1],M.vec[2]); C[5].bbox = UT_BoundingBox(c.vec[0],m.vec[1],c.vec[2],M.vec[0],c.vec[1],M.vec[2]); C[6].bbox = UT_BoundingBox(c.vec[0],c.vec[1],m.vec[2],M.vec[0],M.vec[1],c.vec[2]); C[7].bbox = UT_BoundingBox(c.vec[0],c.vec[1],c.vec[2],M.vec[0],M.vec[1],M.vec[2]); };
OP_ERROR SOP_PrimCentroid::cookMySop(OP_Context &context) { fpreal now; int method; const GA_Attribute *source_attr; const GA_AttributeDict *dict; GA_AttributeDict::iterator a_it; GA_Offset ptOff; GA_RWAttributeRef n_gah; GA_RWHandleV3 n_h; const GEO_Primitive *prim; const GU_Detail *input_geo; UT_BoundingBox bbox; UT_String pattern, attr_name; UT_WorkArgs tokens; now = context.getTime(); if (lockInputs(context) >= UT_ERROR_ABORT) return error(); // Clear out any previous data. gdp->clearAndDestroy(); // Get the input geometry as read only. GU_DetailHandleAutoReadLock gdl(inputGeoHandle(0)); input_geo = gdl.getGdp(); // Find out which calculation method we are attempting. method = METHOD(now); // Create the standard point normal (N) attribute. n_gah = gdp->addNormalAttribute(GA_ATTRIB_POINT); // Bind a read/write attribute handle to the normal attribute. n_h.bind(n_gah.getAttribute()); // Construct an attribute reference map to map attributes. GA_AttributeRefMap hmap(*gdp, input_geo); // Get the attribute selection string. ATTRIBUTES(pattern, now); // Make sure we entered something. if (pattern.length() > 0) { // Tokenize the pattern. pattern.tokenize(tokens, " "); // The primitive attributes on the incoming geometry. dict = &input_geo->primitiveAttribs(); // Iterate over all the primitive attributes. for (a_it=dict->begin(GA_SCOPE_PUBLIC); !a_it.atEnd(); ++a_it) { // The current attribute. source_attr = a_it.attrib(); // Get the attribute name. attr_name = source_attr->getName(); // If the name doesn't match our pattern, skip it. if (!attr_name.matchPattern(tokens)) continue; // Create a new point attribute on the current geometry // that is the same as the source attribute. Append it and // the source to the map. hmap.append(gdp->addPointAttrib(source_attr).getAttribute(), source_attr); } // Copy local variables. if (COPY(now)) { // Traverse the variable names on the input geometry and attempt to // copy any that match to our new geometry. input_geo->traverseVariableNames( SOP_PrimCentroid::copyLocalVariables, gdp ); } } // Get the list of input primitives. const GA_PrimitiveList &prim_list = input_geo->getPrimitiveList(); // Add points for each primitive. ptOff = gdp->appendPointBlock(input_geo->getNumPrimitives()); // Iterate over primitives using pages. for (GA_Iterator it(input_geo->getPrimitiveRange()); !it.atEnd(); ++it) { // Get the primitive from the list. prim = (const GEO_Primitive *) prim_list.get(*it); if (method) { // Get the bounding box for the primitive and set the point's // position to be the center of the box. prim->getBBox(&bbox); gdp->setPos3(ptOff, bbox.center()); } else // Set the point's position to be the bary center of the primitive gdp->setPos3(ptOff, prim->baryCenter()); // Set the point's normal to be the normal of the primitive. n_h.set(ptOff, prim->computeNormal()); // If we are copying attributes, copy the primitive attributes from // the current primitive to the new point. if (hmap.entries() > 0) hmap.copyValue(GA_ATTRIB_POINT, ptOff, GA_ATTRIB_PRIMITIVE, *it); // Increment the point offset. ptOff++; } unlockInputs(); return error(); }
int main(int argc, char *argv[]) { // Init: CMD_Args args; args.initialize(argc, argv); args.stripOptions("r:v"); if (args.argc() < 3) { usage(argv[0]); return 1; } // Options: int res = 256; int verbose = 0; if(args.found('r')) res = atoi(args.argp('r')); if(args.found('v')) verbose = 1; UT_String dcm_file, gdp_file; gdp_file.harden(argv[argc-2]); dcm_file.harden(argv[argc-1]); #if 1 // Open GDP with samples: GU_Detail gdp; UT_BoundingBox bbox; if (!gdp.load(gdp_file, 0).success()) { cerr << "Cant open " << gdp_file << endl; return 1; } // Points arrays and bbox details: gdp.getBBox(&bbox); int range = gdp.getNumPoints(); UT_Vector3Array positions(range); UT_ValArray<int> indices(range); const GEO_Point *ppt; const GEO_PointList plist = gdp.points(); for (int i = 0; i < gdp.getNumPoints(); i++) { ppt = plist(i); UT_Vector3 pos = ppt->getPos3(); positions.append(pos); indices.append(i); } if (verbose) cout << "Points in gdp : " << positions.entries() << endl; // Point Grid structures/objects: UT_Vector3Point accessor(positions, indices); UT_PointGrid<UT_Vector3Point> pointgrid(accessor); // Can we build it? if (!pointgrid.canBuild(res, res, res)) { cout << "Can't build the grid!" << endl; return 1; } // Build it: pointgrid.build(bbox.minvec(), bbox.size(), res, res, res); if (verbose) { cout << "Point grid res : " << res << "x" << res << "x" << res << endl; cout << "Bounding box size : " << bbox.size().x() << ", " << bbox.size().y() << ", " << bbox.size().z() << endl; cout << "Bounding box center: " << bbox.center().x() << ", " << bbox.center().y() << ", " << bbox.center().z() << endl; cout << "Pointgrid mem size : " << pointgrid.getMemoryUsage() << endl; cout << "Voxel size is : " << pointgrid.getVoxelSize() << endl; cout << "Total grid points : " << pointgrid.entries() << endl; } #endif // Open rat (our random access, variable array length storage): IMG_DeepShadow dsm; dsm.setOption("compression", "0"); dsm.setOption("zbias", "0.05"); dsm.setOption("depth_mode", "nearest"); dsm.setOption("depth_interp", "discrete"); dsm.open(dcm_file, res*res, res); dsm.getTBFOptions()->setOptionV3("bbox:min" , bbox.minvec()); dsm.getTBFOptions()->setOptionV3("bbox:max" , bbox.maxvec()); if (verbose) cout << "DCM created res : " << res*res << "x" << res << endl; #if 1 // db_* debug variables... int db_index = 0; int db_uindex = 0; int db_av_iter = 0; // Put point into deep pixels: Locker locker; Timer timer; timer.start(); parallel_fillDCM(res, &dsm, &pointgrid, &positions, &locker); cout << "Creation time : " << timer.current() << endl; if (verbose) { cout << "Total voxels : " << db_index << endl; cout << "Written voxel : " << db_uindex << endl; cout << "Points per voxel : " << (float)db_av_iter / db_uindex << endl; } timer.start(); dsm.close(); cout << "Saving time : " << timer.current() << endl; if (verbose) cout << "Deep map closed." << endl; return 0; #endif }