float Value::getEstimateValue(float size, const Grammar& grammar, const boost::shared_ptr<Shape>& shape) const { if (type == Value::TYPE_ABSOLUTE) { return grammar.evalFloat(value, shape); } else if (type == Value::TYPE_RELATIVE) { return grammar.evalFloat(value, shape) * size; } else { return grammar.evalFloat(value, shape); } }
boost::shared_ptr<Shape> ShapeLOperator::apply(boost::shared_ptr<Shape>& shape, const Grammar& grammar, std::list<boost::shared_ptr<Shape> >& stack) { float actual_frontWidth; float actual_leftWidth; if (frontWidth.type == Value::TYPE_RELATIVE) { actual_frontWidth = shape->_scope.x * grammar.evalFloat(frontWidth.value, shape); } else { actual_frontWidth = shape->_scope.x * grammar.evalFloat(frontWidth.value, shape); } if (leftWidth.type == Value::TYPE_RELATIVE) { actual_leftWidth = shape->_scope.y * grammar.evalFloat(leftWidth.value, shape); } else { actual_leftWidth = shape->_scope.y * grammar.evalFloat(leftWidth.value, shape); } return shape->shapeL(shape->_name, actual_frontWidth, actual_leftWidth); }
boost::shared_ptr<Shape> TranslateOperator::apply(boost::shared_ptr<Shape>& shape, const Grammar& grammar, std::list<boost::shared_ptr<Shape> >& stack) { float actual_x; float actual_y; float actual_z; if (x.type == Value::TYPE_RELATIVE) { actual_x = shape->_scope.x * grammar.evalFloat(x.value, shape); } else { actual_x = grammar.evalFloat(x.value, shape); } if (y.type == Value::TYPE_RELATIVE) { actual_y = shape->_scope.y * grammar.evalFloat(y.value, shape); } else { actual_y = grammar.evalFloat(y.value, shape); } if (z.type == Value::TYPE_RELATIVE) { actual_z = shape->_scope.z * grammar.evalFloat(z.value, shape); } else { actual_z = grammar.evalFloat(z.value, shape); } shape->translate(mode, coordSystem, actual_x, actual_y, actual_z); return shape; }
boost::shared_ptr<Shape> CornerCutOperator::apply(boost::shared_ptr<Shape>& shape, const Grammar& grammar, std::list<boost::shared_ptr<Shape> >& stack) { float actual_length = grammar.evalFloat(length, shape); return shape->cornerCut(shape->_name, type, actual_length); }
boost::shared_ptr<Shape> RoofGableOperator::apply(boost::shared_ptr<Shape>& shape, const Grammar& grammar, std::list<boost::shared_ptr<Shape> >& stack) { float actual_angle = grammar.evalFloat(angle, shape); return shape->roofGable(shape->_name, actual_angle); }
boost::shared_ptr<Shape> TaperOperator::apply(boost::shared_ptr<Shape>& shape, const Grammar& grammar, std::list<boost::shared_ptr<Shape> >& stack) { float actual_height = grammar.evalFloat(height, shape); float actual_slope = grammar.evalFloat(slope, shape); return shape->taper(shape->_name, actual_height, actual_slope); }
boost::shared_ptr<Shape> ExtrudeOperator::apply(boost::shared_ptr<Shape>& shape, const Grammar& grammar, std::list<boost::shared_ptr<Shape> >& stack) { float actual_height = grammar.evalFloat(height, shape); return shape->extrude(shape->_name, actual_height); }
/** * 指定されたsizeをsplitした後の、各断片のサイズを計算する。 * * @param size もとのsize * @param sizes 指定された、各断片のサイズ * @param output_names 指定された、各断片の名前 * @param ruleSet ルール (sizeなどで変数が使用されている場合、解決するため) * @param decoded_sizes [OUT] 計算された、各断片のサイズ * @param decoded_output_names [OUT] 計算された、各断片の名前 */ void Rule::decodeSplitSizes(float size, const std::vector<Value>& sizes, const std::vector<std::string>& output_names, const Grammar& grammar, const boost::shared_ptr<Shape>& shape, std::vector<float>& decoded_sizes, std::vector<std::string>& decoded_output_names) { float regular_sum = 0.0f; float floating_sum = 0.0f; int repeat_count = 0; float repeat_unit = 0.0f; int repeat_num = 0; float repeat_scale = 1.0f; for (int i = 0; i < sizes.size(); ++i) { if (sizes[i].repeat) { repeat_count++; } else { if (sizes[i].type == Value::TYPE_ABSOLUTE) { regular_sum += grammar.evalFloat(sizes[i].value, shape); } else if (sizes[i].type == Value::TYPE_RELATIVE) { regular_sum += size * grammar.evalFloat(sizes[i].value, shape); } else if (sizes[i].type == Value::TYPE_FLOATING) { floating_sum += grammar.evalFloat(sizes[i].value, shape); } } } float floating_scale = 1.0f; if (floating_sum > 0 && repeat_count == 0) { floating_scale = std::max(0.0f, size - regular_sum) / floating_sum; } if (repeat_count > 0) { for (int i = 0; i < sizes.size(); ++i) { if (sizes[i].repeat) { repeat_unit += sizes[i].getEstimateValue(size - regular_sum - floating_sum * floating_scale, grammar, shape); } } repeat_num = std::max(0.0f, (size - regular_sum - floating_sum * floating_scale) / repeat_unit + 0.5f); if (repeat_num == 0) { if (size - regular_sum - floating_sum * floating_scale > 0) { repeat_num = 1; } } if (repeat_num > 0) { repeat_scale = std::max(0.0f, (size - regular_sum - floating_sum * floating_scale) / (float)repeat_num / repeat_unit); } if (floating_sum > 0) { floating_scale = std::max(0.0f, size - regular_sum - repeat_unit * repeat_scale * repeat_num) / floating_sum; } } for (int i = 0; i < sizes.size(); ++i) { if (sizes[i].repeat) { float s = sizes[i].getEstimateValue(size - regular_sum - floating_sum * floating_scale, grammar, shape); s *= repeat_scale; for (int k = 0; k < repeat_num; ++k) { decoded_sizes.push_back(s); decoded_output_names.push_back(output_names[i]); } } else { if (sizes[i].type == Value::TYPE_ABSOLUTE) { decoded_sizes.push_back(grammar.evalFloat(sizes[i].value, shape)); decoded_output_names.push_back(output_names[i]); } else if (sizes[i].type == Value::TYPE_RELATIVE) { decoded_sizes.push_back(grammar.evalFloat(sizes[i].value, shape) * size); decoded_output_names.push_back(output_names[i]); } else if (sizes[i].type == Value::TYPE_FLOATING) { decoded_sizes.push_back(grammar.evalFloat(sizes[i].value, shape) * floating_scale); decoded_output_names.push_back(output_names[i]); } } } }