static int expand_variables_internal(parser_t &parser, wchar_t * const in, std::vector<completion_t> &out, long last_idx) { int is_ok= 1; int empty=0; wcstring var_tmp; std::vector<long> var_idx_list; // CHECK( out, 0 ); for (long i=last_idx; (i>=0) && is_ok && !empty; i--) { const wchar_t c = in[i]; if ((c == VARIABLE_EXPAND) || (c == VARIABLE_EXPAND_SINGLE)) { long start_pos = i+1; long stop_pos; long var_len; int is_single = (c==VARIABLE_EXPAND_SINGLE); stop_pos = start_pos; while (1) { if (!(in[stop_pos ])) break; if (!(iswalnum(in[stop_pos]) || (wcschr(L"_", in[stop_pos])!= 0))) break; stop_pos++; } /* printf( "Stop for '%c'\n", in[stop_pos]);*/ var_len = stop_pos - start_pos; if (var_len == 0) { expand_variable_error(parser, in, stop_pos-1, -1); is_ok = 0; break; } var_tmp.append(in + start_pos, var_len); env_var_t var_val = expand_var(var_tmp.c_str()); if (! var_val.missing()) { int all_vars=1; wcstring_list_t var_item_list; if (is_ok) { tokenize_variable_array(var_val.c_str(), var_item_list); if (in[stop_pos] == L'[') { wchar_t *slice_end; all_vars=0; if (parse_slice(in + stop_pos, &slice_end, var_idx_list, var_item_list.size())) { parser.error(SYNTAX_ERROR, -1, L"Invalid index value"); is_ok = 0; break; } stop_pos = (slice_end-in); } if (!all_vars) { wcstring_list_t string_values(var_idx_list.size()); for (size_t j=0; j<var_idx_list.size(); j++) { long tmp = var_idx_list.at(j); /* Check that we are within array bounds. If not, truncate the list to exit. */ if (tmp < 1 || (size_t)tmp > var_item_list.size()) { parser.error(SYNTAX_ERROR, -1, ARRAY_BOUNDS_ERR); is_ok=0; var_idx_list.resize(j); break; } else { /* Replace each index in var_idx_list inplace with the string value at the specified index */ //al_set( var_idx_list, j, wcsdup((const wchar_t *)al_get( &var_item_list, tmp-1 ) ) ); string_values.at(j) = var_item_list.at(tmp-1); } } // string_values is the new var_item_list var_item_list.swap(string_values); } } if (is_ok) { if (is_single) { in[i]=0; wcstring res = in; res.push_back(INTERNAL_SEPARATOR); for (size_t j=0; j<var_item_list.size(); j++) { const wcstring &next = var_item_list.at(j); if (is_ok) { if (j != 0) res.append(L" "); res.append(next); } } res.append(in + stop_pos); is_ok &= expand_variables2(parser, res, out, i); } else { for (size_t j=0; j<var_item_list.size(); j++) { const wcstring &next = var_item_list.at(j); if (is_ok && (i == 0) && (!in[stop_pos])) { append_completion(out, next); } else { if (is_ok) { wcstring new_in; if (start_pos > 0) new_in.append(in, start_pos - 1); // at this point new_in.size() is start_pos - 1 if (start_pos>1 && new_in[start_pos-2]!=VARIABLE_EXPAND) { new_in.push_back(INTERNAL_SEPARATOR); } new_in.append(next); new_in.append(in + stop_pos); is_ok &= expand_variables2(parser, new_in, out, i); } } } } } return is_ok; } else { /* Expand a non-existing variable */ if (c == VARIABLE_EXPAND) { /* Regular expansion, i.e. expand this argument to nothing */ empty = 1; } else { /* Expansion to single argument. */ wcstring res; in[i] = 0; res.append(in); res.append(in + stop_pos); is_ok &= expand_variables2(parser, res, out, i); return is_ok; } } } } if (!empty) { append_completion(out, in); } return is_ok; }
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; }