void gdlme_eH(void *userData, const char *name) { if (gdlme) { unsigned char *gdlinput = (unsigned char *)charData_retrieve(); struct node *res = NULL; if (pi_file) { file = (char*)pi_file; lnum = pi_line; } if (gdlme_debug) fprintf(f_log, "%s:%d: gdlme processing `%s'\n", pi_file, pi_line, gdlinput); res = gdl(gdlinput, GDL_FRAG_OK); if (res && res->children.lastused) { int i; for (i = 0; i < res->children.lastused; ++i) serialize(res->children.nodes[i],0); } else fprintf(f_log,"%s:%d: conversion of '%s' failed\n", pi_file, pi_line, gdlinput); gdlme = 0; } else { const char *s = charData_retrieve(); fprintf(f_xml,"%s",(const char*)xmlify((unsigned char *)s)); } if (*name != 'r' || strcmp(name,"rp-wrap")) fprintf(f_xml,"</%s>",name); }
OP_ERROR SOP_PointsFromVoxels::cookMySop(OP_Context &context) { bool cull, store; fpreal now, value; int rx, ry, rz; unsigned primnum; GA_Offset ptOff; GA_ROAttributeRef input_attr_gah; GA_RWAttributeRef attr_gah; GA_ROHandleS input_attr_h; GA_RWHandleF attr_h; const GU_Detail *input_geo; const GEO_Primitive *prim; const GEO_PrimVolume *vol; UT_String attr_name; UT_Vector3 pos; UT_VoxelArrayIteratorF vit; now = context.getTime(); if (lockInputs(context) >= UT_ERROR_ABORT) { return error(); } // Get the primitive number. primnum = PRIM(now); // Check for culling. cull = CULL(now); store = STORE(now); // Clear out the detail since we only want our new points. gdp->clearAndDestroy(); // Get the input geometry as read only. GU_DetailHandleAutoReadLock gdl(inputGeoHandle(0)); input_geo = gdl.getGdp(); // Primitive number is valid. if (primnum < input_geo->getNumPrimitives()) { // Get the primitive we need. prim = input_geo->primitives()(primnum); // The primitive is a volume primitive. if (prim->getTypeId().get() == GEO_PRIMVOLUME) { // Get the actual PrimVolume. vol = (const GEO_PrimVolume *)prim; // Get a voxel read handle from the primitive. UT_VoxelArrayReadHandleF vox(vol->getVoxelHandle()); // Attach the voxel iterator to the handle. vit.setHandle(vox); if (store) { // Try to find a 'name' attribute. input_attr_gah = input_geo->findPrimitiveAttribute("name"); if (input_attr_gah.isValid()) { // Get this primitive's name. input_attr_h.bind(input_attr_gah.getAttribute()); attr_name = input_attr_h.get(primnum); } // No name, so just use 'value'. else { attr_name = "value"; } // Add a float point attribute to store the values. attr_gah = gdp->addFloatTuple(GA_ATTRIB_POINT, attr_name, 1); // Attach an attribute handle. attr_h.bind(attr_gah.getAttribute()); } // Culling empty voxels. if (cull) { // Iterate over all the voxels. for (vit.rewind(); !vit.atEnd(); vit.advance()) { // The voxel value. value = vit.getValue(); // Skip voxels with a value of 0. if (value == 0) { continue; } // Convert the voxel index to a position. vol->indexToPos(vit.x(), vit.y(), vit.z(), pos); // Create a point and set it to the position of the // voxel. ptOff = gdp->appendPointOffset(); gdp->setPos3(ptOff, pos); // Store the value if necessary. if (store) { attr_h.set(ptOff, value); } } } else { // Get the resolution of the volume. vol->getRes(rx, ry, rz); // Add points for each voxel. ptOff = gdp->appendPointBlock(rx * ry * rz); // Iterate over all the voxels. for (vit.rewind(); !vit.atEnd(); vit.advance()) { // Convert the voxel index to a position. vol->indexToPos(vit.x(), vit.y(), vit.z(), pos); // Set the position for the current offset. gdp->setPos3(ptOff, pos); // Get and store the value if necessary. if (store) { value = vit.getValue(); attr_h.set(ptOff, value); } // Increment the offset since the block of points we // created is guaranteed to be contiguous. ptOff++; } } } // Primitive isn't a volume primitive. else { addError(SOP_MESSAGE, "Not a volume primitive."); } } // Picked a primitive number that is out of range. else { addWarning(SOP_MESSAGE, "Invalid source index. Index out of range."); } unlockInputs(); return error(); }
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 SOP_PrimGroupCentroid::bindToCentroids(fpreal t, int mode, int method) { int behavior; exint int_value; const GA_PrimitiveGroup *group; GA_PrimitiveGroup *all_prims, *temp_group; GA_Range pr_range; GA_ROAttributeRef attr_gah, primattr_gah; GA_ROHandleI class_h; GA_ROHandleS str_h; const GU_Detail *input_geo; UT_Matrix4 mat; UT_String attr_name, pattern, str_value; UT_Vector3 pos; // Get the second input geometry as read only. GU_DetailHandleAutoReadLock gdl(inputGeoHandle(1)); input_geo = gdl.getGdp(); // Get the unmatched geometry behavior. behavior = BEHAVIOR(t); // Create a new attribute reference map. GA_AttributeRefMap hmap(*gdp, input_geo); // Get the attribute selection string. BIND(pattern, t); // If we have a pattern, try to build the ref map. if (pattern.length() > 0) buildRefMap(hmap, pattern, gdp, input_geo, mode, GA_ATTRIB_POINT); // The list of GA_Primitives in the input geometry. const GA_PrimitiveList &prim_list = gdp->getPrimitiveList(); // Create a temporary primitive group so we can keep track of all the // primitives we have modified. all_prims = createAdhocPrimGroup(*gdp, "allprims"); // Determine which attribute we need from the points, based on the mode. switch (mode) { case 0: attr_name = "group"; break; case 1: attr_name = "name"; break; case 2: attr_name = "class"; break; default: addError(SOP_MESSAGE, "Invalid mode setting"); return 1; } // Find the attribute. attr_gah = input_geo->findPointAttribute(attr_name); // If there is no attribute, add an error message and quit. if (attr_gah.isInvalid()) { addError(SOP_ATTRIBUTE_INVALID, attr_name); return 1; } // If not using groups, we need to check if the matching primitive // attribute exists on the geometry. if (mode != 0) { // Try to find the attribute. primattr_gah = gdp->findPrimitiveAttribute(attr_name); // If there is no attribute, add an error message and quit. if (primattr_gah.isInvalid()) { addError(SOP_ATTRIBUTE_INVALID, attr_name); return 1; } } // 'class' uses the int handle. if (mode == 2) class_h.bind(attr_gah.getAttribute()); // Groups and 'name' use the string handle. else str_h.bind(attr_gah.getAttribute()); for (GA_Iterator it(input_geo->getPointRange()); !it.atEnd(); ++it) { if (mode == 0) { // Get the unique string value. str_value = str_h.get(*it); // Find the group on the geometry to bind. group = gdp->findPrimitiveGroup(str_value); // Ignore non-existent groups. if (!group) continue; // Skip emptry groups. if (group->isEmpty()) continue; // The primtives in the group. pr_range = gdp->getPrimitiveRange(group); } else { if (mode == 1) { // Get the unique string value. str_value = str_h.get(*it); // Get the prims with that string value. pr_range = gdp->getRangeByValue(primattr_gah, str_value); } else { // Get the unique integer value. int_value = class_h.get(*it); // Get the prims with that integery value. pr_range = gdp->getRangeByValue(primattr_gah, int_value); } // Create an adhoc group. temp_group = createAdhocPrimGroup(*gdp); temp_group->addRange(pr_range); } // Add the primitives in the range to the groups. all_prims->addRange(pr_range); // Bounding Box if (method == 1) { // Calculate the bouding box center for this range. boundingBox(gdp, pr_range, prim_list, pos); } // Center of Mass else if (method == 2) { // Calculate the center of mass for this attribute value. centerOfMass(pr_range, prim_list, pos); } // Barycenter else { // Calculate the barycenter for this attribute value. baryCenter(gdp, pr_range, prim_list, pos); } // Build the transform from the point information. buildTransform(mat, input_geo, pos, *it); // Transform the geometry from the centroid. if (mode == 0) gdp->transform(mat, group); else gdp->transform(mat, temp_group); // Copy any necessary attributes from the incoming points to the // geometry. if (hmap.entries()) { for (GA_Iterator pr_it(pr_range); !pr_it.atEnd(); ++pr_it) { hmap.copyValue(GA_ATTRIB_PRIMITIVE, *pr_it, GA_ATTRIB_POINT, *it); } } } // We want to destroy prims that didn't have a matching name/group. if (behavior) { // Flip the membership of all the prims that we did see. all_prims->toggleEntries(); // Destroy the ones that we didn't. gdp->deletePrimitives(*all_prims, true); } return 0; }
int SOP_PrimGroupCentroid::buildCentroids(fpreal t, int mode, int method) { bool store; exint int_value; const GA_AIFStringTuple *ident_t; GA_Attribute *ident_attrib; GA_Offset ptOff; GA_RWAttributeRef ident_gah; GA_RWHandleI class_h; const GU_Detail *input_geo; UT_BoundingBox bbox; UT_String attr_name, pattern, str_value; UT_Vector3 pos; UT_Array<GA_Range> range_array; UT_Array<GA_Range>::const_iterator array_it; UT_StringArray string_values; UT_IntArray int_values; // Get the input geometry as read only. GU_DetailHandleAutoReadLock gdl(inputGeoHandle(0)); input_geo = gdl.getGdp(); // Check to see if we should store the source group/attribute name as an // attribute the generated points. store = STORE(t); // If we want to we need to create the attributes. if (store) { // A 'class' operation, so create a new integer attribute. if (mode == 2) { // Add the int tuple. ident_gah = gdp->addIntTuple(GA_ATTRIB_POINT, "class", 1); // Bind the handle. class_h.bind(ident_gah.getAttribute()); } // Using the 'name' attribute or groups, so create a new string // attribute. else { attr_name = (mode == 0) ? "group" : "name"; // Create a new string attribute. ident_gah = gdp->addStringTuple(GA_ATTRIB_POINT, attr_name, 1); ident_attrib = ident_gah.getAttribute(); // Get the string tuple so we can set values. ident_t = ident_gah.getAIFStringTuple(); } } // Create a new attribute reference map. GA_AttributeRefMap hmap(*gdp, input_geo); // Get the attribute selection string. ATTRIBUTES(pattern, t); // If we have a pattern, try to build the ref map. if (pattern.length() > 0) buildRefMap(hmap, pattern, gdp, input_geo, mode, GA_ATTRIB_PRIMITIVE); // The list of GA_Primitives in the input geometry. const GA_PrimitiveList &prim_list = input_geo->getPrimitiveList(); // Creating by groups. if (mode == 0) { // Get the group pattern. GROUP(pattern, t); // If the group string is empty, get out of here. if (pattern.length() == 0) return 1; buildGroupData(pattern, input_geo, range_array, string_values); } // 'name' or 'class'. else { // Build the data. If something failed, return that we had an issue. if (buildAttribData(mode, input_geo, range_array, string_values, int_values)) return 1; } // Iterate over each of the primitive ranges we found. for (array_it=range_array.begin(); !array_it.atEnd(); ++array_it) { // Create a new point. ptOff = gdp->appendPointOffset(); // Bounding Box if (method == 1) { // Calculate the bouding box center for this range. boundingBox(input_geo, *array_it, prim_list, pos); // Set the point's position to the center of the box. gdp->setPos3(ptOff, pos); } // Center of Mass else if (method == 2) { // Calculate the center of mass for this range. centerOfMass(*array_it, prim_list, pos); // Set the point's position to the center of mass. gdp->setPos3(ptOff, pos); } // Barycenter else { // Calculate the barycenter for this range. baryCenter(input_geo, *array_it, prim_list, pos); // Set the point's position to the barycenter. gdp->setPos3(ptOff, pos); } // Store the source value if required. if (store) { // 'class', so get the integer value at this iterator index. if (mode == 2) { int_value = int_values(array_it.index()); class_h.set(ptOff, int_value); } // 'name' or by group, so get the string value at this iterator // index. else { str_value = string_values(array_it.index()); ident_t->setString(ident_attrib, ptOff, str_value, 0); } } // If there are no entries in the map then we don't need to copy // anything. if (hmap.entries() > 0) { GA_WeightedSum sum; // Start a weighted sum for the range. hmap.startSum(sum, GA_ATTRIB_POINT, ptOff); // Add the values for each primitive to the sum. for (GA_Iterator it(*array_it); !it.atEnd(); ++it) { hmap.addSumValue(sum, GA_ATTRIB_POINT, ptOff, GA_ATTRIB_PRIMITIVE, *it, 1); } // Finish the sum, normalizing the values. hmap.finishSum(sum, GA_ATTRIB_POINT, ptOff, 1.0/(*array_it).getEntries()); } } return 0; }