diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..281d5f979 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,43 @@ +# Contributing to Helios + +Thanks for contributing to [Helios](https://github.com/PlantSimulationLab/Helios)! + +The following set of guidelines should be taken as suggestion, rather than rules. These are currently a work-in-progress, and will evolve along with the project. + +If you have comments or suggestions, please feel free to [open an issue](https://github.com/PlantSimulationLab/Helios/issues/new) or [submit a pull-request](https://github.com/PlantSimulationLab/Helios/compare) to this file. + +## Editing Documentation + +Documentation source files for the Helios core can be found in `doc/UserGuide.dox`, and for each plugin in the corresponding plug-in directory sub-folder `doc/*.dox`. These files are written in [Doxygen](https://www.doxygen.nl/index.html) format. Additionally, documentation for data structures, functions, methods, etc. is written directly in the corresponding header file, and also uses Doxygen syntax. + +If you edit the documentation and want to view the changes, you can build the documentation HTML files. To do this, you need to have Doxygen installed on your system. Then, navigate to the Helios root directory and run: + +```bash +doxygen doc/Doxyfile +``` + +To view the built documentation, open the file `doc/html/index.html` in a web browser. + +## Submitting Changes + +To submit a change, please submit a pull request. There are two methods for doing this if you do not have a 'contributor' role in the Helios repo: + +1. Fork the Helios repo, push changes to a branch, and [create a pull-request on github](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork). +2. You can use the GitHub web interface to [submit a pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). + +Please make edits to the latest version of the master to the extent possible in order to allow for straight-forward merging of the changes into the master. Pull requests should include a clear list of changes summarizing the overall contents of the change. + +Each individual commits should be prefaced with a one-line summary of the intended change. Large and complex commits may also include a longer description, separated by at least one line: + +``` +$ git commit -m "A brief summary of the commit. +> +> A paragraph describing the change in greater detail." +``` + +## Style Guide + +Below are a few general guidelines to follow when contributing to Helios: +1. **Case**: Helios generally uses UpperCamelCase for class names, lowerCamelCase for method names, and snake_case for variable names. +2. **Const Ref**: Use const references (const &) for function/method arguments when passing non-scalar values. + diff --git a/core/include/Context.h b/core/include/Context.h index 2cb1a70b8..91d543004 100755 --- a/core/include/Context.h +++ b/core/include/Context.h @@ -4347,6 +4347,12 @@ class Context{ * \return Size/length of global data array */ size_t getGlobalDataSize( const char* label ) const; + + //! List the labels for all global data in the Context + /** + * \return Vector of labels for all global data + */ + std::vector listGlobalData() const; //! Check if global data 'label' exists /** diff --git a/core/include/helios_vector_types.h b/core/include/helios_vector_types.h index 47d537335..7ec14ca87 100755 --- a/core/include/helios_vector_types.h +++ b/core/include/helios_vector_types.h @@ -352,10 +352,11 @@ struct vec2{ float y; //! Normalize vector components such that the magnitude is unity. - void normalize(){ + vec2 normalize(){ float mag = sqrt( x*x + y*y ); x/=mag; y/=mag; + return {x,y}; } //! Compute the vector magnitude @@ -510,11 +511,12 @@ struct vec3{ float z; //! Normalize vector components such that the magnitude is unity. - void normalize(){ + vec3 normalize(){ float mag = sqrt( x*x + y*y + z*z ); x/=mag; y/=mag; z/=mag; + return {x,y,z}; } //! Compute the vector magnitude @@ -681,12 +683,13 @@ struct vec4{ float w; //! Normalize vector components such that the magnitude is unity. - void normalize(){ + vec4 normalize(){ float mag = sqrt( x*x + y*y + z*z + w*w ); x/=mag; y/=mag; z/=mag; w/=mag; + return {x,y,z,w}; } //! Compute the vector magnitude diff --git a/core/src/Context.cpp b/core/src/Context.cpp index cf6733976..08ec9de50 100755 --- a/core/src/Context.cpp +++ b/core/src/Context.cpp @@ -66,12 +66,7 @@ void Context::addTexture( const char* texture_file ){ } bool Context::doesTextureFileExist(const char* texture_file ) const{ - if (FILE *file = fopen(texture_file, "r")) { - fclose(file); - return true; - } else { - return false; - } + return std::filesystem::exists(texture_file); } bool Context::validateTextureFileExtenstion( const char* texture_file ) const{ @@ -99,7 +94,7 @@ Texture::Texture( const char* texture_file ){ //-------- load transparency channel (if exists) ------------// - if( hastransparencychannel ){ + if( ext==".png" ){ transparencydata = readPNGAlpha( filename ); image_resolution = make_int2(int(transparencydata.front().size()),int(transparencydata.size())); }else{ @@ -3559,9 +3554,12 @@ float Tube::getSegmentVolume( uint segment_index ) const{ void Tube::appendTubeSegment( const helios::vec3 &node_position, float node_radius, const helios::RGBcolor &node_color ){ + //\todo This is a computationally inefficient method for appending the tube, but it ensures that there is no twisting of the tube relative to the previous tube segments. + if( node_radius<0 ){ helios_runtime_error("ERROR (Tube::appendTubeSegment): Node radius must be positive."); } + node_radius = std::max((float)1e-5, node_radius); uint radial_subdivisions = subdiv; @@ -3569,8 +3567,6 @@ void Tube::appendTubeSegment( const helios::vec3 &node_position, float node_radi std::vector cfact(radial_subdivisions + 1); std::vector sfact(radial_subdivisions + 1); - vec3 nvec(0.1817f,0.6198f,0.7634f);//random vector to get things going - for(int j=0; j < radial_subdivisions + 1; j++ ){ cfact[j]=cosf(2.f*float(M_PI)*float(j)/float(radial_subdivisions)); sfact[j]=sinf(2.f*float(M_PI)*float(j)/float(radial_subdivisions)); @@ -3585,24 +3581,53 @@ void Tube::appendTubeSegment( const helios::vec3 &node_position, float node_radi int node_count = nodes.size(); - for( int i=node_count-3; i 0.99f) { + initial_radial = vec3(0.0f, 1.0f, 0.0f); // Avoid parallel vectors + } + previous_radial_dir = cross(axial_vector, initial_radial).normalize(); + } else { + if (i == node_count - 1) { + axial_vector = nodes[i] - nodes[i - 1]; + } else { + axial_vector = 0.5f * ((nodes[i] - nodes[i - 1]) + (nodes[i + 1] - nodes[i])); + } + axial_vector.normalize(); - vec3 orthogonal_dir = cross(radial_dir, axial_vector); - orthogonal_dir.normalize(); + // Calculate radial direction using parallel transport + vec3 rotation_axis = cross(previous_axial_vector, axial_vector); + if (rotation_axis.magnitude() > 1e-6) { + float angle = acos(previous_axial_vector * axial_vector); + previous_radial_dir = rotatePointAboutLine(previous_radial_dir, vec3(0.0f, 0.0f, 0.0f), rotation_axis, angle); + } + previous_radial_dir.normalize(); + } - for(int j=0; j < radial_subdivisions + 1; j++ ){ + previous_axial_vector = axial_vector; - vec3 normal = cfact.at(j)*radius.at(i)*radial_dir + sfact.at(j)*radius.at(i)*orthogonal_dir; - triangle_vertices.at(i).at(j)=nodes.at(i)+normal; + vec3 radial_dir = previous_radial_dir; + vec3 orthogonal_dir = cross(radial_dir, axial_vector); + orthogonal_dir.normalize(); + if( i1 || textureuv_ufrac.y>1 ){ + } else if (textureuv_ufrac.x < 0 || textureuv_ufrac.y < 0 || textureuv_ufrac.x > 1 || textureuv_ufrac.y > 1) { helios_runtime_error("ERROR (Tube::appendTubeSegment): Texture U fraction must be between 0 and 1."); } + node_radius = std::max((float)1e-5, node_radius); uint radial_subdivisions = subdiv; @@ -3649,48 +3677,76 @@ void Tube::appendTubeSegment( const helios::vec3 &node_position, float node_radi std::vector cfact(radial_subdivisions + 1); std::vector sfact(radial_subdivisions + 1); - vec3 nvec(0.1817f,0.6198f,0.7634f);//random vector to get things going - - for(int j=0; j < radial_subdivisions + 1; j++ ){ - cfact[j]=cosf(2.f*float(M_PI)*float(j)/float(radial_subdivisions)); - sfact[j]=sinf(2.f*float(M_PI)*float(j)/float(radial_subdivisions)); + for (int j = 0; j < radial_subdivisions + 1; j++) { + cfact[j] = cosf(2.f * float(M_PI) * float(j) / float(radial_subdivisions)); + sfact[j] = sinf(2.f * float(M_PI) * float(j) / float(radial_subdivisions)); } - triangle_vertices.resize( triangle_vertices.size() + 1 ); - triangle_vertices.back().resize(radial_subdivisions+1); - std::vector > uv; - resize_vector( uv, radial_subdivisions + 1, 2 ); + triangle_vertices.resize(triangle_vertices.size() + 1); + triangle_vertices.back().resize(radial_subdivisions + 1); + std::vector> uv; + resize_vector(uv, radial_subdivisions + 1, 2); - nodes.push_back( node_position ); - radius.push_back( node_radius ); - colors.push_back( RGB::black ); + nodes.push_back(node_position); + radius.push_back(node_radius); + colors.push_back(RGB::black); int node_count = nodes.size(); - for( int i=node_count-3; i 0.99f) { + initial_radial = vec3(0.0f, 1.0f, 0.0f); // Avoid parallel vectors + } + previous_radial_dir = cross(axial_vector, initial_radial).normalize(); + } else { + if (i == node_count - 1) { + axial_vector = nodes[i] - nodes[i - 1]; + } else { + axial_vector = 0.5f * ((nodes[i] - nodes[i - 1]) + (nodes[i + 1] - nodes[i])); + } + axial_vector.normalize(); - vec3 radial_dir = nvec - axial_vector * (nvec * axial_vector); - radial_dir.normalize(); + // Calculate radial direction using parallel transport + vec3 rotation_axis = cross(previous_axial_vector, axial_vector); + if (rotation_axis.magnitude() > 1e-6) { + float angle = acos(previous_axial_vector * axial_vector); + previous_radial_dir = rotatePointAboutLine(previous_radial_dir, vec3(0.0f, 0.0f, 0.0f), rotation_axis, angle); + } + previous_radial_dir.normalize(); + } + previous_axial_vector = axial_vector; + + vec3 radial_dir = previous_radial_dir; vec3 orthogonal_dir = cross(radial_dir, axial_vector); orthogonal_dir.normalize(); - for(int j=0; j < radial_subdivisions + 1; j++ ){ - - vec3 normal = cfact.at(j)*radius.at(i)*radial_dir + sfact.at(j)*radius.at(i)*orthogonal_dir; - triangle_vertices.at(i).at(j)=nodes.at(i)+normal; + if( i ufrac{textureuv_ufrac.x, textureuv_ufrac.y}; - for( int i=0; i<2; i++ ){ - for(int j=0; j < radial_subdivisions + 1; j++ ){ - uv.at(i).at(j).x = ufrac.at(i); - uv.at(i).at(j).y = float(j)/float(radial_subdivisions); + for (int i = 0; i < 2; i++) { + for (int j = 0; j < radial_subdivisions + 1; j++) { + uv[i][j].x = ufrac[i]; + uv[i][j].y = float(j) / float(radial_subdivisions); } } @@ -3699,38 +3755,34 @@ void Tube::appendTubeSegment( const helios::vec3 &node_position, float node_radi vec3 v0, v1, v2; vec2 uv0, uv1, uv2; - //add triangles for new segment - - for(int j=0; j < radial_subdivisions; j++ ) { - - v0 = triangle_vertices.at(1).at(j); - v1 = triangle_vertices.at(1+1).at(j + 1); - v2 = triangle_vertices.at(1).at(j + 1); + // Add triangles for new segment + for (int j = 0; j < radial_subdivisions; j++) { + v0 = triangle_vertices[node_count - 2][j]; + v1 = triangle_vertices[node_count - 1][j + 1]; + v2 = triangle_vertices[node_count - 2][j + 1]; - uv0 = uv.at(0).at(j); - uv1 = uv.at(0+1).at(j+1); - uv2 = uv.at(0).at(j+1); + uv0 = uv[0][j]; + uv1 = uv[1][j + 1]; + uv2 = uv[0][j + 1]; UUIDs.push_back(context->addTriangle(v0, v1, v2, texturefile, uv0, uv1, uv2)); - v0 = triangle_vertices.at(1).at(j); - v1 = triangle_vertices.at(1+1).at(j); - v2 = triangle_vertices.at(1+1).at(j + 1); + v0 = triangle_vertices[node_count - 2][j]; + v1 = triangle_vertices[node_count - 1][j]; + v2 = triangle_vertices[node_count - 1][j + 1]; - uv0 = uv.at(0).at(j); - uv1 = uv.at(0+1).at(j); - uv2 = uv.at(0+1).at(j+1); + uv0 = uv[0][j]; + uv1 = uv[1][j]; + uv2 = uv[1][j + 1]; UUIDs.push_back(context->addTriangle(v0, v1, v2, texturefile, uv0, uv1, uv2)); - } - for( uint p : UUIDs){ + for (uint p : UUIDs) { context->setPrimitiveParentObjectID(p, this->OID); } updateTriangleVertices(); - } void Tube::scaleTubeGirth( float S ){ @@ -4370,12 +4422,12 @@ uint Context::addSphereObject(uint Ndivs, const vec3 ¢er, const vec3 &radius //top cap for( int j=0; j &n helios_runtime_error("ERROR (Context::addTubeObject): Size of `nodes' and `color' arguments must agree."); } - vec3 axial_vector, convec; + vec3 axial_vector; std::vector cfact(radial_subdivisions + 1); std::vector sfact(radial_subdivisions + 1); - std::vector > triangle_vertices; - resize_vector( triangle_vertices, radial_subdivisions + 1, node_count ); + std::vector> triangle_vertices; + resize_vector(triangle_vertices, radial_subdivisions + 1, node_count); - for(int j=0; j < radial_subdivisions + 1; j++ ){ - cfact[j]=cosf(2.f*float(M_PI)*float(j)/float(radial_subdivisions)); - sfact[j]=sinf(2.f*float(M_PI)*float(j)/float(radial_subdivisions)); + // Initialize trigonometric factors for circle points + for (int j = 0; j < radial_subdivisions + 1; j++) { + cfact[j] = cosf(2.f * float(M_PI) * float(j) / float(radial_subdivisions)); + sfact[j] = sinf(2.f * float(M_PI) * float(j) / float(radial_subdivisions)); } - for( int i=0; i 0.99f) { + initial_radial = vec3(0.0f, 1.0f, 0.0f); // Avoid parallel vectors + } + previous_radial_dir = cross(axial_vector, initial_radial).normalize(); + } else { + if (i == node_count - 1) { + axial_vector = nodes[i] - nodes[i - 1]; + } else { + axial_vector = 0.5f * ((nodes[i] - nodes[i - 1]) + (nodes[i + 1] - nodes[i])); + } + axial_vector.normalize(); - convec = cross(nvec, axial_vector); - convec.normalize(); - nvec = cross(axial_vector, convec); - nvec.normalize(); + // Calculate radial direction using parallel transport + vec3 rotation_axis = cross(previous_axial_vector, axial_vector); + if (rotation_axis.magnitude() > 1e-6) { + float angle = acos(previous_axial_vector * axial_vector); + previous_radial_dir = rotatePointAboutLine(previous_radial_dir, vec3(0.0f, 0.0f, 0.0f), rotation_axis, angle); + } + previous_radial_dir.normalize(); + } - for(int j=0; j < radial_subdivisions + 1; j++ ){ + previous_axial_vector = axial_vector; - vec3 normal = cfact[j]*radius[i]*nvec+sfact[j]*radius[i]*convec; - triangle_vertices[i][j]=nodes[i]+normal; + vec3 radial_dir = previous_radial_dir; + vec3 orthogonal_dir = cross(radial_dir, axial_vector); + orthogonal_dir.normalize(); + for (int j = 0; j < radial_subdivisions + 1; j++) { + vec3 normal = cfact[j] * radius[i] * radial_dir + sfact[j] * radius[i] * orthogonal_dir; + triangle_vertices[i][j] = nodes[i] + normal; } - } @@ -4755,93 +4817,99 @@ uint Context::addTubeObject(uint radial_subdivisions, const std::vector &n return addTubeObject( radial_subdivisions, nodes, radius, texturefile, textureuv_ufrac ); } -uint Context::addTubeObject(uint radial_subdivisions, const std::vector &nodes, const std::vector &radius, const char* texturefile, const std::vector &textureuv_ufrac ){ - - - if( !validateTextureFileExtenstion(texturefile) ){ +uint Context::addTubeObject(uint radial_subdivisions, const std::vector &nodes, const std::vector &radius, const char* texturefile, const std::vector &textureuv_ufrac) { + if (!validateTextureFileExtenstion(texturefile)) { helios_runtime_error("ERROR (Context::addTubeObject): Texture file " + std::string(texturefile) + " is not PNG or JPEG format."); - }else if( !doesTextureFileExist(texturefile) ){ + } else if (!doesTextureFileExist(texturefile)) { helios_runtime_error("ERROR (Context::addTubeObject): Texture file " + std::string(texturefile) + " does not exist."); } const uint node_count = nodes.size(); - if( node_count==0 ){ + if (node_count == 0) { helios_runtime_error("ERROR (Context::addTubeObject): Node and radius arrays are empty."); - }else if( node_count!=radius.size() ){ + } else if (node_count != radius.size()) { helios_runtime_error("ERROR (Context::addTubeObject): Size of `nodes' and `radius' arguments must agree."); - }else if( node_count!=textureuv_ufrac.size() ){ + } else if (node_count != textureuv_ufrac.size()) { helios_runtime_error("ERROR (Context::addTubeObject): Size of `nodes' and `textureuv_ufrac' arguments must agree."); } - vec3 axial_vector, convec; + vec3 axial_vector; std::vector cfact(radial_subdivisions + 1); std::vector sfact(radial_subdivisions + 1); - std::vector > triangle_vertices; - resize_vector( triangle_vertices, radial_subdivisions + 1, node_count ); - std::vector > uv; - resize_vector( uv, radial_subdivisions + 1, node_count ); + std::vector> triangle_vertices; + resize_vector(triangle_vertices, radial_subdivisions + 1, node_count); + std::vector> uv; + resize_vector(uv, radial_subdivisions + 1, node_count); - for(int j=0; j < radial_subdivisions + 1; j++ ){ - cfact[j]=cosf(2.f*float(M_PI)*float(j)/float(radial_subdivisions)); - sfact[j]=sinf(2.f*float(M_PI)*float(j)/float(radial_subdivisions)); + // Initialize trigonometric factors for circle points + for (int j = 0; j < radial_subdivisions + 1; j++) { + cfact[j] = cosf(2.f * float(M_PI) * float(j) / float(radial_subdivisions)); + sfact[j] = sinf(2.f * float(M_PI) * float(j) / float(radial_subdivisions)); } - for( int i=0; i 0.99f) { + initial_radial = vec3(0.0f, 1.0f, 0.0f); // Avoid parallel vectors + } + previous_radial_dir = cross(axial_vector, initial_radial).normalize(); + } else { + if (i == node_count - 1) { + axial_vector = nodes[i] - nodes[i - 1]; + } else { + axial_vector = 0.5f * ((nodes[i] - nodes[i - 1]) + (nodes[i + 1] - nodes[i])); + } + axial_vector.normalize(); + + // Calculate radial direction using parallel transport + vec3 rotation_axis = cross(previous_axial_vector, axial_vector); + if (rotation_axis.magnitude() > 1e-6) { + float angle = acos(previous_axial_vector * axial_vector); + previous_radial_dir = rotatePointAboutLine(previous_radial_dir, vec3(0.0f, 0.0f, 0.0f), rotation_axis, angle); + } + previous_radial_dir.normalize(); } - float norm; - convec = cross(nvec, axial_vector); - convec.normalize(); - nvec = cross(axial_vector, convec); - nvec.normalize(); + previous_axial_vector = axial_vector; - for(int j=0; j < radial_subdivisions + 1; j++ ){ + vec3 radial_dir = previous_radial_dir; + vec3 orthogonal_dir = cross(radial_dir, axial_vector); + orthogonal_dir.normalize(); - vec3 normal = cfact[j]*radius[i]*nvec+sfact[j]*radius[i]*convec; - triangle_vertices[i][j]=nodes[i]+normal; + for (int j = 0; j < radial_subdivisions + 1; j++) { + vec3 normal = cfact[j] * radius[i] * radial_dir + sfact[j] * radius[i] * orthogonal_dir; + triangle_vertices[i][j] = nodes[i] + normal; uv[i][j].x = textureuv_ufrac[i]; - uv[i][j].y = float(j)/float(radial_subdivisions); - + uv[i][j].y = float(j) / float(radial_subdivisions); } - } - std::vector UUIDs(2 * (node_count-1) * radial_subdivisions ); + std::vector UUIDs(2 * (node_count - 1) * radial_subdivisions); vec3 v0, v1, v2; vec2 uv0, uv1, uv2; - int ii=0; - for(int j=0; j < radial_subdivisions; j++ ) { + int ii = 0; + for (int j = 0; j < radial_subdivisions; j++) { for (int i = 0; i < node_count - 1; i++) { - v0 = triangle_vertices[i][j]; v1 = triangle_vertices[i + 1][j + 1]; v2 = triangle_vertices[i][j + 1]; uv0 = uv[i][j]; - uv1 = uv[i+1][j+1]; - uv2 = uv[i][j+1]; + uv1 = uv[i + 1][j + 1]; + uv2 = uv[i][j + 1]; UUIDs.at(ii) = addTriangle(v0, v1, v2, texturefile, uv0, uv1, uv2); @@ -4850,8 +4918,8 @@ uint Context::addTubeObject(uint radial_subdivisions, const std::vector &n v2 = triangle_vertices[i + 1][j + 1]; uv0 = uv[i][j]; - uv1 = uv[i+1][j]; - uv2 = uv[i+1][j+1]; + uv1 = uv[i + 1][j]; + uv2 = uv[i + 1][j + 1]; UUIDs.at(ii + 1) = addTriangle(v0, v1, v2, texturefile, uv0, uv1, uv2); @@ -4863,15 +4931,14 @@ uint Context::addTubeObject(uint radial_subdivisions, const std::vector &n auto* tube_new = (new Tube(currentObjectID, UUIDs, nodes, radius, colors, triangle_vertices, radial_subdivisions, texturefile, this)); - for( uint p : UUIDs){ + for (uint p : UUIDs) { getPrimitivePointer_private(p)->setParentObjectID(currentObjectID); } objects[currentObjectID] = tube_new; currentObjectID++; - return currentObjectID-1; - + return currentObjectID - 1; } uint Context::addBoxObject(const vec3 ¢er, const vec3 &size, const int3 &subdiv ){ diff --git a/core/src/Context_data.cpp b/core/src/Context_data.cpp index 2b2ee71a8..923e2808e 100644 --- a/core/src/Context_data.cpp +++ b/core/src/Context_data.cpp @@ -4444,6 +4444,17 @@ size_t Context::getGlobalDataSize(const char *label) const { } +std::vector Context::listGlobalData() const{ + + std::vector labels; + labels.reserve(globaldata.size()); + for( auto it=globaldata.begin(); it!=globaldata.end(); it++ ){ + labels.push_back(it->first); + } + + return labels; +} + bool Context::doesGlobalDataExist( const char* label ) const{ if( globaldata.find(label) == globaldata.end() ){ diff --git a/core/src/global.cpp b/core/src/global.cpp index 8a35599d5..383407e3d 100755 --- a/core/src/global.cpp +++ b/core/src/global.cpp @@ -1675,7 +1675,7 @@ void helios::readJPEG( const std::string &filename, uint &width, uint &height, s auto file_extension = getFileExtension(filename); if ( file_extension != ".jpg" && file_extension != ".JPG" && file_extension != ".jpeg" && file_extension != ".JPEG" ) { - throw (std::runtime_error("ERROR (Context::readJPEG): File " + filename + " is not JPEG format.")); + helios_runtime_error("ERROR (Context::readJPEG): File " + filename + " is not JPEG format."); } struct jpeg_decompress_struct cinfo; @@ -1686,7 +1686,7 @@ void helios::readJPEG( const std::string &filename, uint &width, uint &height, s int row_stride; if ((infile = fopen(filename.c_str(), "rb")) == nullptr ) { - throw (std::runtime_error("ERROR (Context::readJPEG): File " + filename + " could not be opened. Check that the file exists and that you have permission to read it.")); + helios_runtime_error("ERROR (Context::readJPEG): File " + filename + " could not be opened. Check that the file exists and that you have permission to read it."); } cinfo.err = jpeg_std_error(&jerr.pub); @@ -1712,7 +1712,9 @@ void helios::readJPEG( const std::string &filename, uint &width, uint &height, s height=cinfo.output_height; if(cinfo.output_components!=3){ - throw (std::runtime_error("ERROR (Context::readJPEG): Image file does not have RGB components.")); + helios_runtime_error("ERROR (Context::readJPEG): Image file does not have RGB components."); + }else if( width==0 || height == 0 ){ + helios_runtime_error("ERROR (Context::readJPEG): Image file is empty."); } pixel_data.resize(width*height); @@ -1743,7 +1745,7 @@ helios::int2 helios::getImageResolutionJPEG( const std::string &filename ){ auto file_extension = getFileExtension(filename); if ( file_extension != ".jpg" && file_extension != ".JPG" && file_extension != ".jpeg" && file_extension != ".JPEG" ) { - throw (std::runtime_error("ERROR (Context::getImageResolutionJPEG): File " + filename + " is not JPEG format.")); + helios_runtime_error("ERROR (Context::getImageResolutionJPEG): File " + filename + " is not JPEG format."); } struct jpeg_decompress_struct cinfo; @@ -1754,7 +1756,7 @@ helios::int2 helios::getImageResolutionJPEG( const std::string &filename ){ int row_stride; if ((infile = fopen(filename.c_str(), "rb")) == nullptr ) { - throw (std::runtime_error("ERROR (Context::getImageResolutionJPEG): File " + filename + " could not be opened. Check that the file exists and that you have permission to read it.")); + helios_runtime_error("ERROR (Context::getImageResolutionJPEG): File " + filename + " could not be opened. Check that the file exists and that you have permission to read it."); } cinfo.err = jpeg_std_error(&jerr.pub); diff --git a/doc/CHANGELOG b/doc/CHANGELOG index d04b722ef..b22af9cf6 100644 --- a/doc/CHANGELOG +++ b/doc/CHANGELOG @@ -1847,4 +1847,47 @@ The radiation model has been re-designed, with the following primary additions: *Stomatal Conductance* *Credit to Kyle Rizzo for these updates -- Added a stomatal conductance model (BMF) parameter library for a range of species. \ No newline at end of file +- Added a stomatal conductance model (BMF) parameter library for a range of species. + +[1.3.20] 2024-10-21 + +*Context* +- Texture mapping for sphere objects was not correct. The top cap was not being properly mapped, resulting in a dark spot. +- Added Context::listGlobalData() to list out all global data in the Context. +- There were still issues with tube twisting when using Context::appendTubeSegment() based on the implementation from v1.3.19. This should now be fixed. +- Modified helios vector types vec2, vec3, and vec4 normalize methods to also return the normalized vector. This allows for chaining of operations. + +*Energy Balance* +- Added overloaded version of EnergyBalanceModel::addRadiationBand() to add multiple bands at the same time by passing a vector. + +*Stomatal Conductance* +- Error in StomatalConductanceModel::setBMFCoefficientsFromLibrary(const std::string &species_name) function fixed. + +*Plant Architecture* +- Added capability of having evergreen plants. This is controlled through PlantArchitecture::setPlantPhenologicalThresholds(); +- Added olive, pistachio, and apple trees and grapevine (VSP) to the library. +- 'flower_arrangement_pattern' parameter of the internode has been removed. It currently now follows the phyllotaxy of the parent shoot. +- An error was corrected in which the first peduncle segment was being set to the internode color. +- An error was corrected that would cause inconsistent behavior of the shoot internode when there were multiple child shoots originating from the same node. +- Changed how girth scaling is handled. The shoot girth is now calculated based on the downstream leaf area. The new parameter is called "girth_area_factor", which is cm^2 branch area / m^2 downstream leaf area. +- The parameter 'flowers_per_rachis' was changed to be 'flowers_per_peduncle'. + +*Radiation Model* +- When writing output images, the radiation model now checks to make sure the output directory exists and creates it if it does not. + +*Synthetic Annotation* +- Error (Windows OS) fixed to use the filesystem library for file management instead of mkdir. Credit to Sean Banks for this edit. + +*Weber-Penn Tree* +* Credit to Corentin LEROY for these edits +- Addition of variable range parameters for WeberPenn tree generation +- Addition of a sample project to demonstrate how one could build tree orchards based on a WeberPenn XML configuration + +*Canopy Generator* +* Credit to Corentin LEROY for these edits +- Handling of parameters that were not parsed from a CanopyGenerator XML configuration for grapevine canopies +- A refactoring of the way canopy types are handled. Now all canopy classes inherit from BaseCanopyParameters, and all grapevine canopy classes inherit from BaseGrapeVineParameters. On top of that, parameters read from an XML file are stored so that canopies or individual plants can be built later on. This allows client code to have no knowledge at all about the types of canopies or plants that can be built; this information is exclusively written in the configuration file. +- Addition of variable range parameters for grapevine canopies +- Addition of parameters to create dead plants or to have missing plants (holes) in grapevine canopies +- Addition of parameters to set the cordon length independently from the plant spacing for grapevine canopies. Until now, the plant spacing was used so that there was no discontinuity between neighbor vine stocks. These new parameters allow to potentially have gaps between vine stocks, or even have them overlap with each other (if the cordon length is greater than the plant spacing). +- Addition of a sample project to demonstrate how one could build realistic vineyards based on CanopyGenerator XML configuration. \ No newline at end of file diff --git a/doc/UserGuide.dox b/doc/UserGuide.dox index 7fcc3b7b7..326d035f7 100755 --- a/doc/UserGuide.dox +++ b/doc/UserGuide.dox @@ -1,4 +1,4 @@ -/*! \mainpage Helios Documentation v1.3.19 +/*! \mainpage Helios Documentation v1.3.20


diff --git a/doc/header.html b/doc/header.html index 08d2d1b36..0a9323908 100644 --- a/doc/header.html +++ b/doc/header.html @@ -40,7 +40,7 @@ Logo -
 v1.3.19 +
 v1.3.20
diff --git a/doc/html/Helios_logo_small.png b/doc/html/Helios_logo_small.png index 15d057d70..65732fadf 100644 Binary files a/doc/html/Helios_logo_small.png and b/doc/html/Helios_logo_small.png differ diff --git a/doc/html/PlantArchitecture_cover_image.png b/doc/html/PlantArchitecture_cover_image.png new file mode 100644 index 000000000..37e806a36 Binary files /dev/null and b/doc/html/PlantArchitecture_cover_image.png differ diff --git a/doc/html/_a_p_i.html b/doc/html/_a_p_i.html index de52fcee0..84312fcd5 100644 --- a/doc/html/_a_p_i.html +++ b/doc/html/_a_p_i.html @@ -38,7 +38,7 @@ Logo -
 v1.3.19 +
 v1.3.20
@@ -369,9 +369,9 @@

TypeDescriptionData FieldsMember FunctionsMath OperatorsCreation Function -vec22D vector of floatsx, ynormalize(), magnitude()* (dot product), * (mult. by scalar), /, +, -, +=, ==, !=, << make_vec2() +vec22D vector of floatsx, ynormalize(), magnitude()* (dot product), * (mult. by scalar), /, +, -, +=, ==, !=, << make_vec2() -vec33D vector of floatsx, y, znormalize(), magnitude()* (dot product), * (mult. by scalar), /, +, -, +=, ==, !=, << make_vec3() +vec33D vector of floatsx, y, znormalize(), magnitude()* (dot product), * (mult. by scalar), /, +, -, +=, ==, !=, << make_vec3() vec44D vector of floatsx, y, z, wnone* (dot product), * (mult. by scalar), /, +, -, +=, ==, !=, << make_vec4() @@ -441,7 +441,7 @@

Note that the above colors can be directly passed to make_RGBAcolor to specify an alpha (transparency) value:

RGBAcolor red_trans = make_RGBAcolor( RGB::red, 0.5 );
-
R-G-B-A color vector.
+
R-G-B-A color vector.

Coordinate System

Helios uses a right-handed Cartesian coordinate system. (x,y,z) coordinates are typically specified using the 'vec3' data structure (see Vector Types).
@@ -531,9 +531,9 @@

UUID = context.addPatch( center, size );
}
-
uint addPatch()
Add new default Patch geometric primitive, which is centered at the origin (0,0,0),...
Definition Context.cpp:1207
+
uint addPatch()
Add new default Patch geometric primitive, which is centered at the origin (0,0,0),...
Definition Context.cpp:1202
Vector of two elements of type 'float'.
-
Vector of three elements of type 'float'.
+
Vector of three elements of type 'float'.

This will add the Patch shown below, with the default orientation of horizontal. (Note that the addition of the checkerboard ground and the 'Visualizer' plugin is needed to replicate this image, which is not shown in the example code.)

@@ -544,7 +544,7 @@

vec2 size = make_vec2(1,1);
SphericalCoord rotation = make_SphericalCoord(0.25*M_PI,0.5*M_PI);
context.addPatch( center, size, rotation );
-
Vector of spherical coordinates (elevation,azimuth)
+
Vector of spherical coordinates (elevation,azimuth)

This will first rotate the patch by 0.25 $\pi$ rad about the x-axis such that its normal is pointing toward the +y direction, THEN it will apply a clockwise azimuthal rotation of 0.5 $\pi$ rad such that its normal is pointing in the +x direction (which will be its final orientation). Note that in order to have more control over rotations, it is recommended to use the Primitive::rotate() function (see "Primitive Transformations" section below).

Adding Triangles

@@ -564,7 +564,7 @@

UUID = context.addTriangle( v0, v1, v2, RGB::red );
}
-
uint addTriangle(const helios::vec3 &vertex0, const helios::vec3 &vertex1, const helios::vec3 &vertex2)
Add new Triangle geometric primitive.
Definition Context.cpp:1323
+
uint addTriangle(const helios::vec3 &vertex0, const helios::vec3 &vertex1, const helios::vec3 &vertex2)
Add new Triangle geometric primitive.
Definition Context.cpp:1318

This will add the Triangle shown below. (Note that the addition of the checkerboard ground and the 'Visualizer' plugin is needed to replicate this image, which is not shown in the example code.)

@@ -592,7 +592,7 @@

UUID = context.addVoxel( center, size, 0, RGB::red );
}
-
uint addVoxel(const helios::vec3 &center, const helios::vec3 &size)
Add new Voxel geometric primitive.
Definition Context.cpp:1367
+
uint addVoxel(const helios::vec3 &center, const helios::vec3 &size)
Add new Voxel geometric primitive.
Definition Context.cpp:1362

This will add the Voxel shown below, with the default orientation of horizontal. (Note that the addition of the checkerboard ground and the 'visualizer' plugin is needed to replicate this image, which is not shown in the example code.)

@@ -665,7 +665,7 @@

context.translatePrimitive( UUID, translation );
}
-
void translatePrimitive(uint UUID, const vec3 &shift)
Translate a primitive using its UUID.
Definition Context.cpp:1401
+
void translatePrimitive(uint UUID, const vec3 &shift)
Translate a primitive using its UUID.
Definition Context.cpp:1396

Primitive Properties

All primitives have a common set of data that can be accessed by the same set of functions, such as the primitive surface area, the primitive vertices, etc.

@@ -820,8 +820,8 @@

context.deletePrimitive(UUID);
}
-
void deletePrimitive(uint UUID)
Delete a single primitive from the context.
Definition Context.cpp:1531
-
uint copyPrimitive(uint UUID)
Make a copy of a primitive from the context.
Definition Context.cpp:1573
+
void deletePrimitive(uint UUID)
Delete a single primitive from the context.
Definition Context.cpp:1526
+
uint copyPrimitive(uint UUID)
Make a copy of a primitive from the context.
Definition Context.cpp:1568
@@ -1011,9 +1011,9 @@

float area = object->getArea();
-
float getArea() const
Calculate the total one-sided surface area of the Compound Object.
Definition Context.cpp:2270
-
CompoundObject * getObjectPointer(uint ObjID) const
Get a pointer to a Compound Object.
Definition Context.cpp:2559
-
uint addTileObject(const vec3 &center, const vec2 &size, const SphericalCoord &rotation, const int2 &subdiv)
Add a patch that is subdivided into a regular grid of sub-patches (tiled)
Definition Context.cpp:4460
+
float getArea() const
Calculate the total one-sided surface area of the Compound Object.
Definition Context.cpp:2265
+
CompoundObject * getObjectPointer(uint ObjID) const
Get a pointer to a Compound Object.
Definition Context.cpp:2554
+
uint addTileObject(const vec3 &center, const vec2 &size, const SphericalCoord &rotation, const int2 &subdiv)
Add a patch that is subdivided into a regular grid of sub-patches (tiled)
Definition Context.cpp:4512

or a shorthand would be

uint objID; //object identifier
float area = context.getObjectPointer(objID)->getArea();
@@ -1341,14 +1341,14 @@

}
}
-
uint getTimeseriesLength(const char *label) const
Get the length of timeseries data.
Definition Context.cpp:2009
-
float queryTimeseriesData(const char *label, const Date &date, const Time &time) const
Get a timeseries data point by specifying a date and time vector.
Definition Context.cpp:1889
-
void addTimeseriesData(const char *label, float value, const Date &date, const Time &time)
Add a data point to timeseries of data.
Definition Context.cpp:1818
- - -
int second
Second of minute.
-
int hour
Hour of day.
-
int minute
Minute of hour.
+
uint getTimeseriesLength(const char *label) const
Get the length of timeseries data.
Definition Context.cpp:2004
+
float queryTimeseriesData(const char *label, const Date &date, const Time &time) const
Get a timeseries data point by specifying a date and time vector.
Definition Context.cpp:1884
+
void addTimeseriesData(const char *label, float value, const Date &date, const Time &time)
Add a data point to timeseries of data.
Definition Context.cpp:1813
+ + +
int second
Second of minute.
+
int hour
Hour of day.
+
int minute
Minute of hour.

Typically, data is not entered manually, but rather through an XML or text file (see Reading XML Files for information).

It is often necessary to get the number of data points in a given timeseries, which can be accomplished with the command:

uint N = context.getTimeseriesLength( "temperature" );
diff --git a/doc/html/_aerial_li_d_a_r_8cpp.html b/doc/html/_aerial_li_d_a_r_8cpp.html index fcf885826..dac6ecbad 100644 --- a/doc/html/_aerial_li_d_a_r_8cpp.html +++ b/doc/html/_aerial_li_d_a_r_8cpp.html @@ -38,7 +38,7 @@

diff --git a/doc/html/_aerial_li_d_a_r_8cpp_source.html b/doc/html/_aerial_li_d_a_r_8cpp_source.html index 36862663f..63e5c8f22 100644 --- a/doc/html/_aerial_li_d_a_r_8cpp_source.html +++ b/doc/html/_aerial_li_d_a_r_8cpp_source.html @@ -38,7 +38,7 @@ @@ -1925,20 +1925,20 @@
void addVoxelByCenter(const helios::vec3 &center, const helios::vec3 &size, const helios::SphericalCoord &rotation, const helios::RGBcolor &color, CoordinateSystem coordFlag)
Add a voxel by giving the coordinates of its center.
Colormap getCurrentColormap() const
Get the current colormap used in Colorbar/visualization.
Stores the state associated with simulation.
Definition Context.h:1882
-
float randu()
Draw a random number from a uniform distribution between 0 and 1.
Definition Context.cpp:1173
+
float randu()
Draw a random number from a uniform distribution between 0 and 1.
Definition Context.cpp:1168
void helios_runtime_error(const std::string &error_message)
Function to throw a runtime error.
Definition global.cpp:29
float randu()
Random number from a uniform distribution between 0 and 1.
Definition global.cpp:223
SphericalCoord cart2sphere(const vec3 &Cartesian)
Convert Cartesian coordinates to spherical coordinates.
Definition global.cpp:610
float mean(const std::vector< float > &vect)
Mean value of a vector of floats.
Definition global.cpp:1002
-
uint addPatch()
Add new default Patch geometric primitive, which is centered at the origin (0,0,0),...
Definition Context.cpp:1207
+
uint addPatch()
Add new default Patch geometric primitive, which is centered at the origin (0,0,0),...
Definition Context.cpp:1202
int2 make_int2(int x, int y)
Make an int2 vector from two ints.
-
vec2 make_vec2(float x, float y)
Make a vec2 from two floats.
-
RGBAcolor make_RGBAcolor(float r, float g, float b, float a)
Make an RGBAcolor vector.
-
RGBcolor make_RGBcolor(float r, float g, float b)
Make an RGBcolor vector.
+
vec2 make_vec2(float x, float y)
Make a vec2 from two floats.
+
RGBAcolor make_RGBAcolor(float r, float g, float b, float a)
Make an RGBAcolor vector.
+
RGBcolor make_RGBcolor(float r, float g, float b)
Make an RGBcolor vector.
int3 make_int3(int X, int Y, int Z)
Make an int3 vector from three ints.
-
vec3 make_vec3(float x, float y, float z)
Make a vec3 from three floats.
-
vec3 cross(const vec3 &a, const vec3 &b)
Cross product of two vec3 vectors.
-
SphericalCoord make_SphericalCoord(float elevation_radians, float azimuth_radians)
Make a SphericalCoord by specifying elevation and azimuth.
+
vec3 make_vec3(float x, float y, float z)
Make a vec3 from three floats.
+
vec3 cross(const vec3 &a, const vec3 &b)
Cross product of two vec3 vectors.
+
SphericalCoord make_SphericalCoord(float elevation_radians, float azimuth_radians)
Make a SphericalCoord by specifying elevation and azimuth.
Structure containing metadata for an aerial hit point.
Definition AerialLiDAR.h:64
Structure containing metadata for an aerial scan.
Definition AerialLiDAR.h:26
helios::vec2 extent
(x,y) size/extent of scan surface
Definition AerialLiDAR.h:43
@@ -1949,9 +1949,9 @@
float exitDiameter
Diameter of laser pulse at exit from the scanner.
Definition AerialLiDAR.h:53
float scandensity
Scan density in points/m^2.
Definition AerialLiDAR.h:49
RGB color map.
Definition Visualizer.h:159
-
R-G-B-A color vector.
-
R-G-B color vector.
-
Vector of spherical coordinates (elevation,azimuth)
+
R-G-B-A color vector.
+
R-G-B color vector.
+
Vector of spherical coordinates (elevation,azimuth)
Vector of two elements of type 'int'.
int y
Second element in vector.
int x
First element in vector.
@@ -1962,15 +1962,15 @@
Vector of two elements of type 'float'.
float x
First element in vector.
float y
Second element in vector.
-
Vector of three elements of type 'float'.
-
float x
First element in vector.
-
float z
Third element in vector.
-
float y
Second element in vector.
-
Vector of four elements of type 'float'.
-
float y
Second element in vector.
-
float w
Fourth element in vector.
-
float z
Third element in vector.
-
float x
First element in vector.
+
Vector of three elements of type 'float'.
+
float x
First element in vector.
+
float z
Third element in vector.
+
float y
Second element in vector.
+
Vector of four elements of type 'float'.
+
float y
Second element in vector.
+
float w
Fourth element in vector.
+
float z
Third element in vector.
+
float x
First element in vector.
diff --git a/doc/html/_aerial_li_d_a_r_8cu_source.html b/doc/html/_aerial_li_d_a_r_8cu_source.html index 3ddf71252..0bbf912c1 100644 --- a/doc/html/_aerial_li_d_a_r_8cu_source.html +++ b/doc/html/_aerial_li_d_a_r_8cu_source.html @@ -38,7 +38,7 @@ @@ -1778,22 +1778,22 @@
helios::int3 getGridResolution(void) const
Get the total number of cells in the grid.
void enableMessages(void)
Enable all print messages to the screen.
Stores the state associated with simulation.
Definition Context.h:1882
-
float randu()
Draw a random number from a uniform distribution between 0 and 1.
Definition Context.cpp:1173
-
std::string getPrimitiveTextureFile(uint UUID) const
Get the path to texture map file for primitive. If primitive does not have a texture map,...
Definition Context.cpp:7036
-
std::vector< vec2 > getPrimitiveTextureUV(uint UUID) const
Get u-v texture coordinates at primitive vertices.
Definition Context.cpp:7052
-
bool primitiveTextureHasTransparencyChannel(uint UUID) const
Check if primitive texture map has a transparency channel.
Definition Context.cpp:7056
-
PrimitiveType getPrimitiveType(uint UUID) const
Method to get the Primitive type.
Definition Context.cpp:6861
-
helios::int2 getPrimitiveTextureSize(uint UUID) const
Get the size (number of pixels) of primitive texture map image.
Definition Context.cpp:7044
-
void getDomainBoundingBox(helios::vec2 &xbounds, helios::vec2 &ybounds, helios::vec2 &zbounds) const
Get a box that bounds all primitives in the domain.
Definition Context.cpp:2031
-
std::vector< uint > getAllUUIDs() const
Get all primitive UUIDs currently in the Context.
Definition Context.cpp:1758
-
const std::vector< std::vector< bool > > * getPrimitiveTextureTransparencyData(uint UUID) const
Get the transparency channel pixel data from primitive texture map. If transparency channel does not ...
Definition Context.cpp:7064
-
std::vector< helios::vec3 > getPrimitiveVertices(uint UUID) const
Method to return the (x,y,z) coordinates of the vertices of a Primitive.
Definition Context.cpp:6999
+
float randu()
Draw a random number from a uniform distribution between 0 and 1.
Definition Context.cpp:1168
+
std::string getPrimitiveTextureFile(uint UUID) const
Get the path to texture map file for primitive. If primitive does not have a texture map,...
Definition Context.cpp:7103
+
std::vector< vec2 > getPrimitiveTextureUV(uint UUID) const
Get u-v texture coordinates at primitive vertices.
Definition Context.cpp:7119
+
bool primitiveTextureHasTransparencyChannel(uint UUID) const
Check if primitive texture map has a transparency channel.
Definition Context.cpp:7123
+
PrimitiveType getPrimitiveType(uint UUID) const
Method to get the Primitive type.
Definition Context.cpp:6928
+
helios::int2 getPrimitiveTextureSize(uint UUID) const
Get the size (number of pixels) of primitive texture map image.
Definition Context.cpp:7111
+
void getDomainBoundingBox(helios::vec2 &xbounds, helios::vec2 &ybounds, helios::vec2 &zbounds) const
Get a box that bounds all primitives in the domain.
Definition Context.cpp:2026
+
std::vector< uint > getAllUUIDs() const
Get all primitive UUIDs currently in the Context.
Definition Context.cpp:1753
+
const std::vector< std::vector< bool > > * getPrimitiveTextureTransparencyData(uint UUID) const
Get the transparency channel pixel data from primitive texture map. If transparency channel does not ...
Definition Context.cpp:7131
+
std::vector< helios::vec3 > getPrimitiveVertices(uint UUID) const
Method to return the (x,y,z) coordinates of the vertices of a Primitive.
Definition Context.cpp:7066
SphericalCoord cart2sphere(const vec3 &Cartesian)
Convert Cartesian coordinates to spherical coordinates.
Definition global.cpp:610
float atan2_2pi(float y, float x)
Four quadrant arc tangent between 0 and 2*pi.
Definition global.cpp:584
vec3 sphere2cart(const SphericalCoord &Spherical)
Convert Spherical coordinates to Cartesian coordinates.
Definition global.cpp:617
float acos_safe(float x)
arccosine function to handle cases when round-off errors cause an argument <-1 or >1,...
Definition global.cpp:241
int2 make_int2(int x, int y)
Make an int2 vector from two ints.
-
vec3 cross(const vec3 &a, const vec3 &b)
Cross product of two vec3 vectors.
+
vec3 cross(const vec3 &a, const vec3 &b)
Cross product of two vec3 vectors.
Vector of two elements of type 'int'.
int y
Second element in vector.
int x
First element in vector.
@@ -1804,10 +1804,10 @@
Vector of two elements of type 'float'.
float x
First element in vector.
float y
Second element in vector.
-
Vector of three elements of type 'float'.
-
float x
First element in vector.
-
float z
Third element in vector.
-
float y
Second element in vector.
+
Vector of three elements of type 'float'.
+
float x
First element in vector.
+
float z
Third element in vector.
+
float y
Second element in vector.
diff --git a/doc/html/_aerial_li_d_a_r_8h_source.html b/doc/html/_aerial_li_d_a_r_8h_source.html index 1bc418671..94e6d1765 100644 --- a/doc/html/_aerial_li_d_a_r_8h_source.html +++ b/doc/html/_aerial_li_d_a_r_8h_source.html @@ -38,7 +38,7 @@ @@ -501,13 +501,13 @@
helios::vec3 center
(x,y,z) position of scan surface center
Definition AerialLiDAR.h:40
float exitDiameter
Diameter of laser pulse at exit from the scanner.
Definition AerialLiDAR.h:53
float scandensity
Scan density in points/m^2.
Definition AerialLiDAR.h:49
-
R-G-B color vector.
-
Vector of spherical coordinates (elevation,azimuth)
+
R-G-B color vector.
+
Vector of spherical coordinates (elevation,azimuth)
Vector of two elements of type 'int'.
Vector of three elements of type 'int'.
Vector of two elements of type 'float'.
-
Vector of three elements of type 'float'.
-
Vector of four elements of type 'float'.
+
Vector of three elements of type 'float'.
+
Vector of four elements of type 'float'.
diff --git a/doc/html/_assets_8cpp.html b/doc/html/_assets_8cpp.html index e5ede1909..c1c27f9ec 100644 --- a/doc/html/_assets_8cpp.html +++ b/doc/html/_assets_8cpp.html @@ -38,7 +38,7 @@ @@ -125,6 +125,16 @@ + + + + + + + + + + @@ -163,8 +173,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -252,7 +292,7 @@

-

Definition at line 131 of file Assets.cpp.

+

Definition at line 128 of file Assets.cpp.

@@ -280,7 +320,7 @@

-

Definition at line 125 of file Assets.cpp.

+

Definition at line 122 of file Assets.cpp.

@@ -327,7 +367,7 @@

-

Definition at line 154 of file Assets.cpp.

+

Definition at line 151 of file Assets.cpp.

@@ -365,7 +405,148 @@

-

Definition at line 137 of file Assets.cpp.

+

Definition at line 134 of file Assets.cpp.

+ + + + +

◆ AppledPhytomerCreationFunction()

+ +
+
+

PropertyGetter Function
-
 v1.3.19 +
 v1.3.20
-
 v1.3.19 +
 v1.3.20
-
 v1.3.19 +
 v1.3.20
-
 v1.3.19 +
 v1.3.20
-
 v1.3.19 +
 v1.3.20
-
 v1.3.19 +
 v1.3.20
-
 v1.3.19 +
 v1.3.20
-
 v1.3.19 +
 v1.3.20
 
void AlmondPhytomerCallbackFunction (std::shared_ptr< Phytomer > phytomer)
 
uint AppleLeafPrototype (helios::Context *context_ptr, uint subdivisions, int compound_leaf_index)
 
uint AppleFruitPrototype (helios::Context *context_ptr, uint subdivisions, float time_since_fruit_set)
 
uint AppleFlowerPrototype (helios::Context *context_ptr, uint subdivisions, bool flower_is_open)
 
void AppledPhytomerCreationFunction (std::shared_ptr< Phytomer > phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age)
 
void ApplePhytomerCallbackFunction (std::shared_ptr< Phytomer > phytomer)
 
uint AsparagusLeafPrototype (helios::Context *context_ptr, uint subdivisions, int compound_leaf_index)
 
void AsparagusPhytomerCreationFunction (std::shared_ptr< Phytomer > phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age)
 
void CowpeaPhytomerCreationFunction (std::shared_ptr< Phytomer > phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age)
 
uint GrapevineLeafPrototype (helios::Context *context_ptr, uint subdivisions, int compound_leaf_index)
 
float random_float (float min, float max)
 
bool spheres_overlap (const helios::vec3 &center1, float radius1, const helios::vec3 &center2, float radius2)
 
uint GrapevineFruitPrototype (helios::Context *context_ptr, uint subdivisions, float time_since_fruit_set)
 
void GrapevinePhytomerCreationFunction (std::shared_ptr< Phytomer > phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age)
 
uint PuncturevineLeafPrototype (helios::Context *context_ptr, uint subdivisions, int compound_leaf_index)
 
uint OliveLeafPrototype (helios::Context *context_ptr, uint subdivisions, int compound_leaf_index)
 
uint OliveFruitPrototype (helios::Context *context_ptr, uint subdivisions, float time_since_fruit_set)
 
uint OliveFlowerPrototype (helios::Context *context_ptr, uint subdivisions, bool flower_is_open)
 
void OlivePhytomerCreationFunction (std::shared_ptr< Phytomer > phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age)
 
void OlivePhytomerCallbackFunction (std::shared_ptr< Phytomer > phytomer)
 
uint PistachioLeafPrototype (helios::Context *context_ptr, uint subdivisions, int compound_leaf_index)
 
uint PistachioFruitPrototype (helios::Context *context_ptr, uint subdivisions, float time_since_fruit_set)
 
uint PistachioFlowerPrototype (helios::Context *context_ptr, uint subdivisions, bool flower_is_open)
 
void PistachioPhytomerCreationFunction (std::shared_ptr< Phytomer > phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age)
 
void PistachioPhytomerCallbackFunction (std::shared_ptr< Phytomer > phytomer)
 
uint PuncturevineFlowerPrototype (helios::Context *context_ptr, uint subdivisions, bool flower_is_open)
 
uint RedbudLeafPrototype (helios::Context *context_ptr, uint subdivisions, int compound_leaf_index)
+ + + + + + + + + + + + + + + + + + + + + + + + + +
void AppledPhytomerCreationFunction (std::shared_ptr< Phytomer > phytomer,
uint shoot_node_index,
uint parent_shoot_node_index,
uint shoot_max_nodes,
float plant_age )
+
+ +

Definition at line 191 of file Assets.cpp.

+ +
+ + +

◆ AppleFlowerPrototype()

+ +
+
+ + + + + + + + + + + + + + + + +
uint AppleFlowerPrototype (helios::Context * context_ptr,
uint subdivisions,
bool flower_is_open )
+
+ +

Definition at line 185 of file Assets.cpp.

+ +
+
+ +

◆ AppleFruitPrototype()

+ +
+
+ + + + + + + + + + + + + + + + +
uint AppleFruitPrototype (helios::Context * context_ptr,
uint subdivisions,
float time_since_fruit_set )
+
+ +

Definition at line 179 of file Assets.cpp.

+ +
+
+ +

◆ AppleLeafPrototype()

+ +
+
+ + + + + + + + + + + + + + + + +
uint AppleLeafPrototype (helios::Context * context_ptr,
uint subdivisions,
int compound_leaf_index )
+
+ +

Definition at line 161 of file Assets.cpp.

+ +
+
+ +

◆ ApplePhytomerCallbackFunction()

+ +
+
+ + + + + + + +
void ApplePhytomerCallbackFunction (std::shared_ptr< Phytomer > phytomer)
+
+ +

Definition at line 208 of file Assets.cpp.

@@ -393,7 +574,7 @@

-

Definition at line 164 of file Assets.cpp.

+

Definition at line 218 of file Assets.cpp.

@@ -431,7 +612,7 @@

-

Definition at line 191 of file Assets.cpp.

+

Definition at line 245 of file Assets.cpp.

@@ -459,7 +640,7 @@

-

Definition at line 265 of file Assets.cpp.

+

Definition at line 319 of file Assets.cpp.

@@ -487,7 +668,7 @@

-

Definition at line 259 of file Assets.cpp.

+

Definition at line 313 of file Assets.cpp.

@@ -515,7 +696,7 @@

-

Definition at line 216 of file Assets.cpp.

+

Definition at line 270 of file Assets.cpp.

@@ -543,7 +724,7 @@

-

Definition at line 246 of file Assets.cpp.

+

Definition at line 300 of file Assets.cpp.

@@ -571,7 +752,7 @@

-

Definition at line 201 of file Assets.cpp.

+

Definition at line 255 of file Assets.cpp.

@@ -599,7 +780,7 @@

-

Definition at line 238 of file Assets.cpp.

+

Definition at line 292 of file Assets.cpp.

@@ -637,7 +818,7 @@

-

Definition at line 276 of file Assets.cpp.

+

Definition at line 330 of file Assets.cpp.

@@ -665,7 +846,7 @@

-

Definition at line 300 of file Assets.cpp.

+

Definition at line 357 of file Assets.cpp.

@@ -693,7 +874,7 @@

-

Definition at line 294 of file Assets.cpp.

+

Definition at line 351 of file Assets.cpp.

@@ -808,7 +989,7 @@

-

Definition at line 306 of file Assets.cpp.

+

Definition at line 363 of file Assets.cpp.

@@ -836,7 +1017,7 @@

-

Definition at line 376 of file Assets.cpp.

+

Definition at line 433 of file Assets.cpp.

@@ -864,7 +1045,7 @@

-

Definition at line 370 of file Assets.cpp.

+

Definition at line 427 of file Assets.cpp.

@@ -892,7 +1073,7 @@

-

Definition at line 327 of file Assets.cpp.

+

Definition at line 384 of file Assets.cpp.

@@ -920,7 +1101,7 @@

-

Definition at line 357 of file Assets.cpp.

+

Definition at line 414 of file Assets.cpp.

@@ -948,7 +1129,7 @@

-

Definition at line 312 of file Assets.cpp.

+

Definition at line 369 of file Assets.cpp.

@@ -976,7 +1157,7 @@

-

Definition at line 349 of file Assets.cpp.

+

Definition at line 406 of file Assets.cpp.

@@ -1014,7 +1195,383 @@

-

Definition at line 387 of file Assets.cpp.

+

Definition at line 444 of file Assets.cpp.

+ + + + +

◆ GrapevineFruitPrototype()

+ +
+
+ + + + + + + + + + + + + + + + +
uint GrapevineFruitPrototype (helios::Context * context_ptr,
uint subdivisions,
float time_since_fruit_set )
+
+ +

Definition at line 498 of file Assets.cpp.

+ +
+
+ +

◆ GrapevineLeafPrototype()

+ +
+
+ + + + + + + + + + + + + + + + +
uint GrapevineLeafPrototype (helios::Context * context_ptr,
uint subdivisions,
int compound_leaf_index )
+
+ +

Definition at line 462 of file Assets.cpp.

+ +
+
+ +

◆ GrapevinePhytomerCreationFunction()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
void GrapevinePhytomerCreationFunction (std::shared_ptr< Phytomer > phytomer,
uint shoot_node_index,
uint parent_shoot_node_index,
uint shoot_max_nodes,
float plant_age )
+
+ +

Definition at line 584 of file Assets.cpp.

+ +
+
+ +

◆ OliveFlowerPrototype()

+ +
+
+ + + + + + + + + + + + + + + + +
uint OliveFlowerPrototype (helios::Context * context_ptr,
uint subdivisions,
bool flower_is_open )
+
+ +

Definition at line 654 of file Assets.cpp.

+ +
+
+ +

◆ OliveFruitPrototype()

+ +
+
+ + + + + + + + + + + + + + + + +
uint OliveFruitPrototype (helios::Context * context_ptr,
uint subdivisions,
float time_since_fruit_set )
+
+ +

Definition at line 645 of file Assets.cpp.

+ +
+
+ +

◆ OliveLeafPrototype()

+ +
+
+ + + + + + + + + + + + + + + + +
uint OliveLeafPrototype (helios::Context * context_ptr,
uint subdivisions,
int compound_leaf_index )
+
+ +

Definition at line 622 of file Assets.cpp.

+ +
+
+ +

◆ OlivePhytomerCallbackFunction()

+ +
+
+ + + + + + + +
void OlivePhytomerCallbackFunction (std::shared_ptr< Phytomer > phytomer)
+
+ +

Definition at line 664 of file Assets.cpp.

+ +
+
+ +

◆ OlivePhytomerCreationFunction()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
void OlivePhytomerCreationFunction (std::shared_ptr< Phytomer > phytomer,
uint shoot_node_index,
uint parent_shoot_node_index,
uint shoot_max_nodes,
float plant_age )
+
+ +

Definition at line 660 of file Assets.cpp.

+ +
+
+ +

◆ PistachioFlowerPrototype()

+ +
+
+ + + + + + + + + + + + + + + + +
uint PistachioFlowerPrototype (helios::Context * context_ptr,
uint subdivisions,
bool flower_is_open )
+
+ +

Definition at line 700 of file Assets.cpp.

+ +
+
+ +

◆ PistachioFruitPrototype()

+ +
+
+ + + + + + + + + + + + + + + + +
uint PistachioFruitPrototype (helios::Context * context_ptr,
uint subdivisions,
float time_since_fruit_set )
+
+ +

Definition at line 694 of file Assets.cpp.

+ +
+
+ +

◆ PistachioLeafPrototype()

+ +
+
+ + + + + + + + + + + + + + + + +
uint PistachioLeafPrototype (helios::Context * context_ptr,
uint subdivisions,
int compound_leaf_index )
+
+ +

Definition at line 674 of file Assets.cpp.

+ +
+
+ +

◆ PistachioPhytomerCallbackFunction()

+ +
+
+ + + + + + + +
void PistachioPhytomerCallbackFunction (std::shared_ptr< Phytomer > phytomer)
+
+ +

Definition at line 716 of file Assets.cpp.

+ +
+
+ +

◆ PistachioPhytomerCreationFunction()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
void PistachioPhytomerCreationFunction (std::shared_ptr< Phytomer > phytomer,
uint shoot_node_index,
uint parent_shoot_node_index,
uint shoot_max_nodes,
float plant_age )
+
+ +

Definition at line 706 of file Assets.cpp.

@@ -1042,7 +1599,7 @@

-

Definition at line 421 of file Assets.cpp.

+

Definition at line 729 of file Assets.cpp.

@@ -1070,7 +1627,30 @@

-

Definition at line 405 of file Assets.cpp.

+

Definition at line 606 of file Assets.cpp.

+ + + + +

◆ random_float()

+ +
+
+ + + + + + + + + + + +
float random_float (float min,
float max )
+
+ +

Definition at line 484 of file Assets.cpp.

@@ -1098,7 +1678,7 @@

-

Definition at line 448 of file Assets.cpp.

+

Definition at line 756 of file Assets.cpp.

@@ -1126,7 +1706,7 @@

-

Definition at line 453 of file Assets.cpp.

+

Definition at line 761 of file Assets.cpp.

@@ -1154,7 +1734,7 @@

-

Definition at line 427 of file Assets.cpp.

+

Definition at line 735 of file Assets.cpp.

@@ -1173,7 +1753,7 @@

-

Definition at line 462 of file Assets.cpp.

+

Definition at line 770 of file Assets.cpp.

@@ -1211,7 +1791,7 @@

-

Definition at line 458 of file Assets.cpp.

+

Definition at line 766 of file Assets.cpp.

@@ -1239,7 +1819,7 @@

-

Definition at line 480 of file Assets.cpp.

+

Definition at line 788 of file Assets.cpp.

@@ -1277,7 +1857,7 @@

-

Definition at line 506 of file Assets.cpp.

+

Definition at line 814 of file Assets.cpp.

@@ -1305,7 +1885,7 @@

-

Definition at line 519 of file Assets.cpp.

+

Definition at line 827 of file Assets.cpp.

@@ -1333,7 +1913,7 @@

-

Definition at line 540 of file Assets.cpp.

+

Definition at line 848 of file Assets.cpp.

@@ -1371,7 +1951,7 @@

-

Definition at line 633 of file Assets.cpp.

+

Definition at line 941 of file Assets.cpp.

@@ -1399,7 +1979,7 @@

-

Definition at line 674 of file Assets.cpp.

+

Definition at line 982 of file Assets.cpp.

@@ -1427,7 +2007,7 @@

-

Definition at line 668 of file Assets.cpp.

+

Definition at line 976 of file Assets.cpp.

@@ -1455,7 +2035,7 @@

-

Definition at line 644 of file Assets.cpp.

+

Definition at line 952 of file Assets.cpp.

@@ -1483,7 +2063,7 @@

-

Definition at line 664 of file Assets.cpp.

+

Definition at line 972 of file Assets.cpp.

@@ -1521,7 +2101,40 @@

-

Definition at line 685 of file Assets.cpp.

+

Definition at line 993 of file Assets.cpp.

+ + + + +

◆ spheres_overlap()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + +
bool spheres_overlap (const helios::vec3 & center1,
float radius1,
const helios::vec3 & center2,
float radius2 )
+
+ +

Definition at line 489 of file Assets.cpp.

@@ -1549,7 +2162,7 @@

-

Definition at line 722 of file Assets.cpp.

+

Definition at line 1030 of file Assets.cpp.

@@ -1577,7 +2190,7 @@

-

Definition at line 728 of file Assets.cpp.

+

Definition at line 1036 of file Assets.cpp.

@@ -1605,7 +2218,7 @@

-

Definition at line 703 of file Assets.cpp.

+

Definition at line 1011 of file Assets.cpp.

@@ -1633,7 +2246,7 @@

-

Definition at line 734 of file Assets.cpp.

+

Definition at line 1042 of file Assets.cpp.

@@ -1661,7 +2274,7 @@

-

Definition at line 785 of file Assets.cpp.

+

Definition at line 1093 of file Assets.cpp.

@@ -1689,7 +2302,7 @@

-

Definition at line 779 of file Assets.cpp.

+

Definition at line 1087 of file Assets.cpp.

@@ -1717,7 +2330,7 @@

-

Definition at line 756 of file Assets.cpp.

+

Definition at line 1064 of file Assets.cpp.

@@ -1755,7 +2368,7 @@

-

Definition at line 791 of file Assets.cpp.

+

Definition at line 1099 of file Assets.cpp.

@@ -1783,7 +2396,7 @@

-

Definition at line 810 of file Assets.cpp.

+

Definition at line 1118 of file Assets.cpp.

@@ -1821,7 +2434,7 @@

-

Definition at line 837 of file Assets.cpp.

+

Definition at line 1145 of file Assets.cpp.

@@ -1849,7 +2462,7 @@

-

Definition at line 831 of file Assets.cpp.

+

Definition at line 1139 of file Assets.cpp.

diff --git a/doc/html/_assets_8cpp_source.html b/doc/html/_assets_8cpp_source.html index cde28648c..7be9ef9ce 100644 --- a/doc/html/_assets_8cpp_source.html +++ b/doc/html/_assets_8cpp_source.html @@ -38,7 +38,7 @@ Logo -
 v1.3.19 +
 v1.3.20
@@ -196,773 +196,1093 @@
103
104uint AlmondLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
-
105// std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/AlmondLeaf.obj", make_vec3(0.,0,0), 0, nullrotation, RGB::black, "ZUP", true );
-
106// uint objID = context_ptr->addPolymeshObject( UUIDs );
-
107// return objID;
-
108
-
109 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/AlmondLeaf.png";
-
110
-
111 float leaf_aspect = 0.4; //ratio of leaf width to leaf length
-
112
-
113 float midrib_fold = 0.; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
-
114
-
115 float longitudinal_curvature = 0.05; //curvature factor along x-direction. (+curves upward, -curved downward)
-
116
-
117 float lateral_curvature = 0.1; //curvature factor along y-direction. (+curves upward, -curved downward)
-
118
-
119 uint objID = buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, 0, 0, 0, false);
-
120
-
121 return objID;
-
122
-
123}
-
124
-
125uint AlmondFruitPrototype( helios::Context* context_ptr, uint subdivisions, float time_since_fruit_set ){
-
126 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/AlmondHull_lowres.obj", make_vec3(0.,0,0), 0,nullrotation, RGB::black, "ZUP", true );
-
127 uint objID = context_ptr->addPolymeshObject( UUIDs );
-
128 return objID;
-
129}
-
130
-
131uint AlmondFlowerPrototype( helios::Context* context_ptr, uint subdivisions, bool flower_is_open ){
-
132 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/AlmondFlower.obj", make_vec3(0.0,0,0), 0,nullrotation, RGB::black, "ZUP", true );
-
133 uint objID = context_ptr->addPolymeshObject( UUIDs );
-
134 return objID;
-
135}
-
136
-
137void AlmondPhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ) {
-
138
-
139 if( phytomer->internode_length_max < 0.01 ){ //spurs
-
140 phytomer->setInternodeMaxRadius( 0.005 );
-
141 phytomer->setVegetativeBudState( BUD_DEAD );
-
142 phytomer->scaleLeafPrototypeScale( 0.8 );
-
143 phytomer->setFloralBudState( BUD_DEAD );
-
144 }
-
145
-
146 //blind nodes
-
147// if( shoot_node_index<3 ){
-
148// phytomer->setVegetativeBudState( BUD_DEAD );
-
149// phytomer->setFloralBudState( BUD_DEAD );
-
150// }
-
151
-
152}
-
153
-
154void AlmondPhytomerCallbackFunction( std::shared_ptr<Phytomer> phytomer ){
-
155
-
156 if( phytomer->isdormant ){
-
157 if( phytomer->shoot_index.x >= phytomer->shoot_index.y-3 && phytomer->internode_length_max > 0.01 ){
-
158 phytomer->setVegetativeBudState( BUD_DORMANT ); //first two vegetative buds always break
-
159 }
-
160 }
-
161
-
162}
-
163
-
164uint AsparagusLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
-
165
-
166 float curve_magnitude = context_ptr->randu(0.f,0.2f);
-
167
-
168 std::vector<vec3> nodes;
-
169 nodes.push_back( make_vec3(0,0,0) );
-
170 nodes.push_back( make_vec3( context_ptr->randu(0.4f,0.7f),0,-0.25f*curve_magnitude) );
-
171 nodes.push_back( make_vec3(0.95,0,-0.9f*curve_magnitude) );
-
172 nodes.push_back( make_vec3(1,0,-curve_magnitude) );
-
173
-
174 std::vector<float> radius;
-
175 radius.push_back(0.015);
-
176 radius.push_back(0.015);
-
177 radius.push_back(0.015);
-
178 radius.push_back(0.0);
-
179
-
180 std::vector<RGBcolor> colors;
-
181 colors.push_back( RGB::forestgreen );
-
182 colors.push_back( RGB::forestgreen );
-
183 colors.push_back( RGB::forestgreen );
-
184 colors.push_back( RGB::forestgreen );
-
185
-
186 uint objID = context_ptr->addTubeObject( 8, nodes, radius, colors);
-
187 context_ptr->rotateObject( objID, context_ptr->randu(0,2.f*M_PI), "x" );
+
105
+
106 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/AlmondLeaf.png";
+
107
+
108 float leaf_aspect = 0.4; //ratio of leaf width to leaf length
+
109
+
110 float midrib_fold = 0.; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
+
111
+
112 float longitudinal_curvature = 0.05; //curvature factor along x-direction. (+curves upward, -curved downward)
+
113
+
114 float lateral_curvature = 0.1; //curvature factor along y-direction. (+curves upward, -curved downward)
+
115
+
116 uint objID = buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, 0, 0, 0, false);
+
117
+
118 return objID;
+
119
+
120}
+
121
+
122uint AlmondFruitPrototype( helios::Context* context_ptr, uint subdivisions, float time_since_fruit_set ){
+
123 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/AlmondHull_lowres.obj", make_vec3(0.,0,0), 0,nullrotation, RGB::black, "ZUP", true );
+
124 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
125 return objID;
+
126}
+
127
+
128uint AlmondFlowerPrototype( helios::Context* context_ptr, uint subdivisions, bool flower_is_open ){
+
129 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/AlmondFlower.obj", make_vec3(0.0,0,0), 0,nullrotation, RGB::black, "ZUP", true );
+
130 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
131 return objID;
+
132}
+
133
+
134void AlmondPhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ) {
+
135
+
136 if( phytomer->internode_length_max < 0.01 ){ //spurs
+
137 phytomer->setInternodeMaxRadius( 0.005 );
+
138 phytomer->setVegetativeBudState( BUD_DEAD );
+
139 phytomer->scaleLeafPrototypeScale( 0.8 );
+
140 phytomer->setFloralBudState( BUD_DEAD );
+
141 }
+
142
+
143 //blind nodes
+
144// if( shoot_node_index<3 ){
+
145// phytomer->setVegetativeBudState( BUD_DEAD );
+
146// phytomer->setFloralBudState( BUD_DEAD );
+
147// }
+
148
+
149}
+
150
+
151void AlmondPhytomerCallbackFunction( std::shared_ptr<Phytomer> phytomer ){
+
152
+
153 if( phytomer->isdormant ){
+
154 if( phytomer->shoot_index.x >= phytomer->shoot_index.y-3 && phytomer->internode_length_max > 0.01 ){
+
155 phytomer->setVegetativeBudState( BUD_DORMANT ); //first two vegetative buds always break
+
156 }
+
157 }
+
158
+
159}
+
160
+
161uint AppleLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
162
+
163 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/AppleLeaf.png";
+
164
+
165 float leaf_aspect = 0.6; //ratio of leaf width to leaf length
+
166
+
167 float midrib_fold = 0.2; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
+
168
+
169 float longitudinal_curvature = 0.1; //curvature factor along x-direction. (+curves upward, -curved downward)
+
170
+
171 float lateral_curvature = 0.1; //curvature factor along y-direction. (+curves upward, -curved downward)
+
172
+
173 uint objID = buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, 0, 0, 0, false);
+
174
+
175 return objID;
+
176
+
177}
+
178
+
179uint AppleFruitPrototype( helios::Context* context_ptr, uint subdivisions, float time_since_fruit_set ){
+
180 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/AppleFruit.obj", make_vec3(0.,0,0), 0,nullrotation, RGB::black, "ZUP", true );
+
181 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
182 return objID;
+
183}
+
184
+
185uint AppleFlowerPrototype( helios::Context* context_ptr, uint subdivisions, bool flower_is_open ){
+
186 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/AlmondFlower.obj", make_vec3(0.0,0,0), 0,nullrotation, RGB::black, "ZUP", true );
+
187 uint objID = context_ptr->addPolymeshObject( UUIDs );
188 return objID;
189}
190
-
191void AsparagusPhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ) {
+
191void AppledPhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ) {
192
-
193 //blind nodes
-
194 if( shoot_node_index<=2 ){
-
195 phytomer->scaleLeafPrototypeScale( 0.6 );
-
196 phytomer->setVegetativeBudState( BUD_DEAD );
-
197 }
-
198
-
199}
-
200
-
201uint BeanLeafPrototype_unifoliate(helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
-
202 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/BeanLeaf_unifoliate_centered.png";
-
203
-
204 float leaf_aspect = 0.8; //ratio of leaf width to leaf length
+
193 if( phytomer->internode_length_max < 0.01 ){ //spurs
+
194 phytomer->setInternodeMaxRadius( 0.005 );
+
195 phytomer->setVegetativeBudState( BUD_DEAD );
+
196 phytomer->scaleLeafPrototypeScale( 0.8 );
+
197 phytomer->setFloralBudState( BUD_DEAD );
+
198 }
+
199
+
200 //blind nodes
+
201 if( shoot_node_index<3 ){
+
202 phytomer->setVegetativeBudState( BUD_DEAD );
+
203 phytomer->setFloralBudState( BUD_DEAD );
+
204 }
205
-
206 float midrib_fold = 0.2; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
+
206}
207
-
208 float longitudinal_curvature = -0.2; //curvature factor along x-direction. (+curves upward, -curved downward)
+
208void ApplePhytomerCallbackFunction( std::shared_ptr<Phytomer> phytomer ){
209
-
210 float lateral_curvature = -0.1; //curvature factor along y-direction. (+curves upward, -curved downward)
-
211
-
212 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, 0, 0, 0, true);
-
213
-
214}
+
210 if( phytomer->isdormant ){
+
211 if( phytomer->shoot_index.x >= phytomer->shoot_index.y-3 && phytomer->internode_length_max > 0.01 ){
+
212 phytomer->setVegetativeBudState( BUD_DORMANT ); //first two vegetative buds always break
+
213 }
+
214 }
215
-
216uint BeanLeafPrototype_trifoliate(helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
-
217 std::string leaf_texture;
-
218 if( compound_leaf_index==0 ){
-
219 leaf_texture = "plugins/plantarchitecture/assets/textures/BeanLeaf_tip.png";
-
220 }else if( compound_leaf_index<0 ){
-
221 leaf_texture = "plugins/plantarchitecture/assets/textures/BeanLeaf_left_centered.png";
-
222 }else{
-
223 leaf_texture = "plugins/plantarchitecture/assets/textures/BeanLeaf_right_centered.png";
-
224 }
-
225
-
226 float leaf_aspect = 1.0; //ratio of leaf width to leaf length
+
216}
+
217
+
218uint AsparagusLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
219
+
220 float curve_magnitude = context_ptr->randu(0.f,0.2f);
+
221
+
222 std::vector<vec3> nodes;
+
223 nodes.push_back( make_vec3(0,0,0) );
+
224 nodes.push_back( make_vec3( context_ptr->randu(0.4f,0.7f),0,-0.25f*curve_magnitude) );
+
225 nodes.push_back( make_vec3(0.95,0,-0.9f*curve_magnitude) );
+
226 nodes.push_back( make_vec3(1,0,-curve_magnitude) );
227
-
228 float midrib_fold = 0.025; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
-
229
-
230 float longitudinal_curvature = context_ptr->randu(-0.3f,-0.2f); //curvature factor along x-direction. (+curves upward, -curved downward)
-
231
-
232 float lateral_curvature = -1.; //curvature factor along y-direction. (+curves upward, -curved downward)
+
228 std::vector<float> radius;
+
229 radius.push_back(0.015);
+
230 radius.push_back(0.015);
+
231 radius.push_back(0.015);
+
232 radius.push_back(0.0);
233
-
234 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, 0, 0, 0, true);
-
235
-
236}
-
237
-
238uint BeanLeafPrototype_unifoliate_OBJ(helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
-
239 std::vector<uint> UUIDs;
-
240 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/BeanLeaf_unifoliate.obj", true );
-
241
-
242 uint objID = context_ptr->addPolymeshObject( UUIDs );
-
243 return objID;
-
244}
-
245
-
246uint BeanLeafPrototype_trifoliate_OBJ(helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
-
247 std::vector<uint> UUIDs;
-
248 if( compound_leaf_index==0 ){
-
249 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/BeanLeaf_tip.obj", true );
-
250 }else if( compound_leaf_index<0 ){
-
251 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/BeanLeaf_left.obj", true );
-
252 }else{
-
253 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/BeanLeaf_right.obj", true );
-
254 }
-
255 uint objID = context_ptr->addPolymeshObject( UUIDs );
-
256 return objID;
-
257}
-
258
-
259uint BeanFruitPrototype( helios::Context* context_ptr, uint subdivisions, float time_since_fruit_set ){
-
260 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/BeanPod.obj", true );
-
261 uint objID = context_ptr->addPolymeshObject( UUIDs );
-
262 return objID;
-
263}
-
264
-
265uint BeanFlowerPrototype( helios::Context* context_ptr, uint subdivisions, bool flower_is_open ){
-
266 std::vector<uint> UUIDs;
-
267 if( flower_is_open ){
-
268 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/BeanFlower_open_white.obj", true );
-
269 }else{
-
270 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/BeanFlower_closed_white.obj", true );
-
271 }
-
272 uint objID = context_ptr->addPolymeshObject( UUIDs );
-
273 return objID;
-
274}
-
275
-
276void BeanPhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ){
-
277
-
278 if( shoot_node_index>5 || phytomer->rank>1 ) {
-
279 phytomer->setVegetativeBudState(BUD_DEAD);
-
280 }else{
-
281 phytomer->setFloralBudState(BUD_DEAD);
-
282 }
+
234 std::vector<RGBcolor> colors;
+
235 colors.push_back( RGB::forestgreen );
+
236 colors.push_back( RGB::forestgreen );
+
237 colors.push_back( RGB::forestgreen );
+
238 colors.push_back( RGB::forestgreen );
+
239
+
240 uint objID = context_ptr->addTubeObject( 8, nodes, radius, colors);
+
241 context_ptr->rotateObject( objID, context_ptr->randu(0,2.f*M_PI), "x" );
+
242 return objID;
+
243}
+
244
+
245void AsparagusPhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ) {
+
246
+
247 //blind nodes
+
248 if( shoot_node_index<=2 ){
+
249 phytomer->scaleLeafPrototypeScale( 0.6 );
+
250 phytomer->setVegetativeBudState( BUD_DEAD );
+
251 }
+
252
+
253}
+
254
+
255uint BeanLeafPrototype_unifoliate(helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
256 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/BeanLeaf_unifoliate_centered.png";
+
257
+
258 float leaf_aspect = 0.8; //ratio of leaf width to leaf length
+
259
+
260 float midrib_fold = 0.2; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
+
261
+
262 float longitudinal_curvature = -0.2; //curvature factor along x-direction. (+curves upward, -curved downward)
+
263
+
264 float lateral_curvature = -0.1; //curvature factor along y-direction. (+curves upward, -curved downward)
+
265
+
266 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, 0, 0, 0, true);
+
267
+
268}
+
269
+
270uint BeanLeafPrototype_trifoliate(helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
271 std::string leaf_texture;
+
272 if( compound_leaf_index==0 ){
+
273 leaf_texture = "plugins/plantarchitecture/assets/textures/BeanLeaf_tip.png";
+
274 }else if( compound_leaf_index<0 ){
+
275 leaf_texture = "plugins/plantarchitecture/assets/textures/BeanLeaf_left_centered.png";
+
276 }else{
+
277 leaf_texture = "plugins/plantarchitecture/assets/textures/BeanLeaf_right_centered.png";
+
278 }
+
279
+
280 float leaf_aspect = 1.0; //ratio of leaf width to leaf length
+
281
+
282 float midrib_fold = 0.025; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
283
-
284 //set leaf and internode scale based on position along the shoot
-
285 float leaf_scale = fmin(1.f, 0.2 + 0.8 * plant_age / 15.f);
-
286 phytomer->scaleLeafPrototypeScale(leaf_scale);
+
284 float longitudinal_curvature = context_ptr->randu(-0.3f,-0.2f); //curvature factor along x-direction. (+curves upward, -curved downward)
+
285
+
286 float lateral_curvature = -1.; //curvature factor along y-direction. (+curves upward, -curved downward)
287
-
288 //set internode length based on position along the shoot
-
289 float inode_scale = fmin(1.f, 0.1 + 0.9 * plant_age / 15.f);
-
290 phytomer->scaleInternodeMaxLength(inode_scale);
+
288 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, 0, 0, 0, true);
+
289
+
290}
291
-
292}
-
293
-
294uint BindweedLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
-
295 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/BindweedLeaf.obj", true );
+
292uint BeanLeafPrototype_unifoliate_OBJ(helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
293 std::vector<uint> UUIDs;
+
294 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/BeanLeaf_unifoliate.obj", true );
+
295
296 uint objID = context_ptr->addPolymeshObject( UUIDs );
297 return objID;
298}
299
-
300uint BindweedFlowerPrototype( helios::Context* context_ptr, uint subdivisions, bool flower_is_open ){
-
301 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/BindweedFlower.obj", true );
-
302 uint objID = context_ptr->addPolymeshObject( UUIDs );
-
303 return objID;
-
304}
-
305
-
306uint CheeseweedLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
-
307 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/CheeseweedLeaf.obj", true );
-
308 uint objID = context_ptr->addPolymeshObject( UUIDs );
-
309 return objID;
-
310}
-
311
-
312uint CowpeaLeafPrototype_unifoliate(helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
-
313 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/CowpeaLeaf_unifoliate_centered.png";
-
314
-
315 float leaf_aspect = 0.8; //ratio of leaf width to leaf length
-
316
-
317 float midrib_fold = 0.2; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
+
300uint BeanLeafPrototype_trifoliate_OBJ(helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
301 std::vector<uint> UUIDs;
+
302 if( compound_leaf_index==0 ){
+
303 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/BeanLeaf_tip.obj", true );
+
304 }else if( compound_leaf_index<0 ){
+
305 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/BeanLeaf_left.obj", true );
+
306 }else{
+
307 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/BeanLeaf_right.obj", true );
+
308 }
+
309 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
310 return objID;
+
311}
+
312
+
313uint BeanFruitPrototype( helios::Context* context_ptr, uint subdivisions, float time_since_fruit_set ){
+
314 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/BeanPod.obj", true );
+
315 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
316 return objID;
+
317}
318
-
319 float longitudinal_curvature = -0.2; //curvature factor along x-direction. (+curves upward, -curved downward)
-
320
-
321 float lateral_curvature = -0.1; //curvature factor along y-direction. (+curves upward, -curved downward)
-
322
-
323 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, 0, 0, 0, false);
-
324
-
325}
-
326
-
327uint CowpeaLeafPrototype_trifoliate(helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
-
328 std::string leaf_texture;
-
329 if( compound_leaf_index==0 ){
-
330 leaf_texture = "plugins/plantarchitecture/assets/textures/CowpeaLeaf_tip_centered.png";
-
331 }else if( compound_leaf_index<0 ){
-
332 leaf_texture = "plugins/plantarchitecture/assets/textures/CowpeaLeaf_left.png";
-
333 }else{
-
334 leaf_texture = "plugins/plantarchitecture/assets/textures/CowpeaLeaf_right.png";
-
335 }
-
336
-
337 float leaf_aspect = 0.8; //ratio of leaf width to leaf length
-
338
-
339 float midrib_fold = 0.2; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
+
319uint BeanFlowerPrototype( helios::Context* context_ptr, uint subdivisions, bool flower_is_open ){
+
320 std::vector<uint> UUIDs;
+
321 if( flower_is_open ){
+
322 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/BeanFlower_open_white.obj", true );
+
323 }else{
+
324 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/BeanFlower_closed_white.obj", true );
+
325 }
+
326 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
327 return objID;
+
328}
+
329
+
330void BeanPhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ){
+
331
+
332 if( shoot_node_index>5 || phytomer->rank>1 ) {
+
333 phytomer->setVegetativeBudState(BUD_DEAD);
+
334 }else{
+
335 phytomer->setFloralBudState(BUD_DEAD);
+
336 }
+
337 if( shoot_node_index<=1 && phytomer->rank == 0 ){
+
338 phytomer->setVegetativeBudState(BUD_ACTIVE);
+
339 }
340
-
341 float longitudinal_curvature = context_ptr->randu(-0.4f,-0.1f); //curvature factor along x-direction. (+curves upward, -curved downward)
-
342
-
343 float lateral_curvature = -0.4; //curvature factor along y-direction. (+curves upward, -curved downward)
+
341 //set leaf and internode scale based on position along the shoot
+
342 float leaf_scale = fmin(1.f, 0.2 + 0.8 * plant_age / 15.f);
+
343 phytomer->scaleLeafPrototypeScale(leaf_scale);
344
-
345 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, 0, 0, 0, true);
-
346
-
347}
+
345 //set internode length based on position along the shoot
+
346 float inode_scale = fmin(1.f, 0.1 + 0.9 * plant_age / 15.f);
+
347 phytomer->scaleInternodeMaxLength(inode_scale);
348
-
349uint CowpeaLeafPrototype_unifoliate_OBJ(helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
-
350 std::vector<uint> UUIDs;
-
351 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/CowpeaLeaf_unifoliate.obj", make_vec3(0.,0,0), 0, nullrotation, RGB::black, "ZUP", true );
-
352
+
349}
+
350
+
351uint BindweedLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
352 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/BindweedLeaf.obj", true );
353 uint objID = context_ptr->addPolymeshObject( UUIDs );
354 return objID;
355}
356
-
357uint CowpeaLeafPrototype_trifoliate_OBJ(helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
-
358 std::vector<uint> UUIDs;
-
359 if( compound_leaf_index<0 ){
-
360 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/CowpeaLeaf_left_highres.obj", make_vec3(0.,0,0), 0, nullrotation, RGB::black, "ZUP", true );
-
361 }else if( compound_leaf_index==0 ){
-
362 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/CowpeaLeaf_tip_highres.obj", make_vec3(0.,0,0), 0, nullrotation, RGB::black, "ZUP", true );
-
363 }else{
-
364 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/CowpeaLeaf_right_highres.obj", make_vec3(0.,0,0), 0, nullrotation, RGB::black, "ZUP", true );
-
365 }
-
366 uint objID = context_ptr->addPolymeshObject( UUIDs );
-
367 return objID;
-
368}
-
369
-
370uint CowpeaFruitPrototype( helios::Context* context_ptr, uint subdivisions, float time_since_fruit_set ){
-
371 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/CowpeaPod.obj", make_vec3(0.,0,0), 0.75,nullrotation, RGB::black, "ZUP", true );
-
372 uint objID = context_ptr->addPolymeshObject( UUIDs );
-
373 return objID;
-
374}
+
357uint BindweedFlowerPrototype( helios::Context* context_ptr, uint subdivisions, bool flower_is_open ){
+
358 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/BindweedFlower.obj", true );
+
359 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
360 return objID;
+
361}
+
362
+
363uint CheeseweedLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
364 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/CheeseweedLeaf.obj", true );
+
365 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
366 return objID;
+
367}
+
368
+
369uint CowpeaLeafPrototype_unifoliate(helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
370 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/CowpeaLeaf_unifoliate_centered.png";
+
371
+
372 float leaf_aspect = 0.8; //ratio of leaf width to leaf length
+
373
+
374 float midrib_fold = 0.2; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
375
-
376uint CowpeaFlowerPrototype( helios::Context* context_ptr, uint subdivisions, bool flower_is_open ){
-
377 std::vector<uint> UUIDs;
-
378 if( flower_is_open ){
-
379 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/CowpeaFlower_open_yellow.obj", make_vec3(0.0,0,0), 0,nullrotation, RGB::black, "ZUP", true );
-
380 }else{
-
381 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/CowpeaFlower_closed_yellow.obj", make_vec3(0.0,0,0), 0,nullrotation, RGB::black, "ZUP", true );
-
382 }
-
383 uint objID = context_ptr->addPolymeshObject( UUIDs );
-
384 return objID;
-
385}
-
386
-
387void CowpeaPhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ){
-
388
-
389 if( shoot_node_index>5 || phytomer->rank>1 ) {
-
390 phytomer->setVegetativeBudState(BUD_DEAD);
-
391 }else{
-
392 phytomer->setFloralBudState(BUD_DEAD);
-
393 }
-
394
-
395 //set leaf and internode scale based on position along the shoot
-
396 float leaf_scale = fmin(1.f, 0.2 + 0.8 * plant_age / 15.f);
-
397 phytomer->scaleLeafPrototypeScale(leaf_scale);
-
398
-
399 //set internode length based on position along the shoot
-
400 float inode_scale = fmin(1.f, 0.1 + 0.9 * plant_age / 15.f);
-
401 phytomer->scaleInternodeMaxLength(inode_scale);
-
402
-
403}
-
404
-
405uint PuncturevineLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
-
406
-
407 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/PuncturevineLeaf.png";
-
408
-
409 float leaf_aspect = 0.4; //ratio of leaf width to leaf length
-
410
-
411 float midrib_fold = 0.2; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
-
412
-
413 float longitudinal_curvature = -0.1; //curvature factor along x-direction. (+curves upward, -curved downward)
-
414
-
415 float lateral_curvature = 0.4; //curvature factor along y-direction. (+curves upward, -curved downward)
-
416
-
417 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, 0, 0, 0, false);
-
418
-
419}
-
420
-
421uint PuncturevineFlowerPrototype( helios::Context* context_ptr, uint subdivisions, bool flower_is_open ){
-
422 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/PuncturevineFlower.obj", make_vec3(0.0,0,0), 0,nullrotation, RGB::black, "ZUP", true );
+
376 float longitudinal_curvature = -0.2; //curvature factor along x-direction. (+curves upward, -curved downward)
+
377
+
378 float lateral_curvature = -0.1; //curvature factor along y-direction. (+curves upward, -curved downward)
+
379
+
380 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, 0, 0, 0, false);
+
381
+
382}
+
383
+
384uint CowpeaLeafPrototype_trifoliate(helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
385 std::string leaf_texture;
+
386 if( compound_leaf_index==0 ){
+
387 leaf_texture = "plugins/plantarchitecture/assets/textures/CowpeaLeaf_tip_centered.png";
+
388 }else if( compound_leaf_index<0 ){
+
389 leaf_texture = "plugins/plantarchitecture/assets/textures/CowpeaLeaf_left.png";
+
390 }else{
+
391 leaf_texture = "plugins/plantarchitecture/assets/textures/CowpeaLeaf_right.png";
+
392 }
+
393
+
394 float leaf_aspect = 0.8; //ratio of leaf width to leaf length
+
395
+
396 float midrib_fold = 0.2; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
+
397
+
398 float longitudinal_curvature = context_ptr->randu(-0.4f,-0.1f); //curvature factor along x-direction. (+curves upward, -curved downward)
+
399
+
400 float lateral_curvature = -0.4; //curvature factor along y-direction. (+curves upward, -curved downward)
+
401
+
402 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, 0, 0, 0, true);
+
403
+
404}
+
405
+
406uint CowpeaLeafPrototype_unifoliate_OBJ(helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
407 std::vector<uint> UUIDs;
+
408 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/CowpeaLeaf_unifoliate.obj", make_vec3(0.,0,0), 0, nullrotation, RGB::black, "ZUP", true );
+
409
+
410 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
411 return objID;
+
412}
+
413
+
414uint CowpeaLeafPrototype_trifoliate_OBJ(helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
415 std::vector<uint> UUIDs;
+
416 if( compound_leaf_index<0 ){
+
417 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/CowpeaLeaf_left_highres.obj", make_vec3(0.,0,0), 0, nullrotation, RGB::black, "ZUP", true );
+
418 }else if( compound_leaf_index==0 ){
+
419 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/CowpeaLeaf_tip_highres.obj", make_vec3(0.,0,0), 0, nullrotation, RGB::black, "ZUP", true );
+
420 }else{
+
421 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/CowpeaLeaf_right_highres.obj", make_vec3(0.,0,0), 0, nullrotation, RGB::black, "ZUP", true );
+
422 }
423 uint objID = context_ptr->addPolymeshObject( UUIDs );
424 return objID;
425}
426
-
427uint RedbudLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
-
428 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/RedbudLeaf.png";
-
429
-
430 float leaf_aspect = 1.0; //ratio of leaf width to leaf length
-
431
-
432 float midrib_fold = 0.2; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
-
433
-
434 float longitudinal_curvature = -0.15; //curvature factor along x-direction. (+curves upward, -curved downward)
-
435
-
436 float lateral_curvature = -0.1; //curvature factor along y-direction. (+curves upward, -curved downward)
-
437
-
438 //parameters for leaf wave/wrinkles
-
439 float wave_period = 0.3f; //period factor of leaf waves
-
440 float wave_amplitude = 0.025f; // amplitude of leaf waves
-
441
-
442 uint objID = buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, 0, wave_period, wave_amplitude, false);
-
443 context_ptr->translateObject( objID, make_vec3(-0.3,0,0) );
-
444
-
445 return objID;
-
446}
-
447
-
448uint RedbudFlowerPrototype( helios::Context* context_ptr, uint subdivisions, bool flower_is_open ){
-
449 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/RedbudFlower_open.obj", make_vec3(0.0,0,0), 0,nullrotation, RGB::black, "ZUP", true );
-
450 return context_ptr->addPolymeshObject( UUIDs );
-
451}
-
452
-
453uint RedbudFruitPrototype( helios::Context* context_ptr, uint subdivisions, float time_since_fruit_set ){
-
454 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/RedbudPod.obj", make_vec3(0.,0,0), 0,nullrotation, RGB::black, "ZUP", true );
-
455 return context_ptr->addPolymeshObject( UUIDs );
-
456}
-
457
-
458void RedbudPhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ){
+
427uint CowpeaFruitPrototype( helios::Context* context_ptr, uint subdivisions, float time_since_fruit_set ){
+
428 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/CowpeaPod.obj", make_vec3(0.,0,0), 0.75,nullrotation, RGB::black, "ZUP", true );
+
429 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
430 return objID;
+
431}
+
432
+
433uint CowpeaFlowerPrototype( helios::Context* context_ptr, uint subdivisions, bool flower_is_open ){
+
434 std::vector<uint> UUIDs;
+
435 if( flower_is_open ){
+
436 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/CowpeaFlower_open_yellow.obj", make_vec3(0.0,0,0), 0,nullrotation, RGB::black, "ZUP", true );
+
437 }else{
+
438 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/CowpeaFlower_closed_yellow.obj", make_vec3(0.0,0,0), 0,nullrotation, RGB::black, "ZUP", true );
+
439 }
+
440 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
441 return objID;
+
442}
+
443
+
444void CowpeaPhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ){
+
445
+
446 if( shoot_node_index>5 || phytomer->rank>1 ) {
+
447 phytomer->setVegetativeBudState(BUD_DEAD);
+
448 }else{
+
449 phytomer->setFloralBudState(BUD_DEAD);
+
450 }
+
451
+
452 //set leaf and internode scale based on position along the shoot
+
453 float leaf_scale = fmin(1.f, 0.2 + 0.8 * plant_age / 15.f);
+
454 phytomer->scaleLeafPrototypeScale(leaf_scale);
+
455
+
456 //set internode length based on position along the shoot
+
457 float inode_scale = fmin(1.f, 0.1 + 0.9 * plant_age / 15.f);
+
458 phytomer->scaleInternodeMaxLength(inode_scale);
459
460}
461
-
462void RedbudPhytomerCallbackFunction( std::shared_ptr<Phytomer> phytomer ){
+
462uint GrapevineLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
463
-
464 int Nchild_shoots = randu(0,3);
+
464 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/GrapeLeaf.png";
465
-
466 if( phytomer->isdormant ){
-
467 if( phytomer->rank<=1 ){
-
468 Nchild_shoots = std::max(2,Nchild_shoots);
-
469 }
-
470 if( phytomer->shoot_index.x < phytomer->shoot_index.y-Nchild_shoots ){
-
471 phytomer->setVegetativeBudState( BUD_DEAD );
-
472 }
-
473 else{
-
474 phytomer->setFloralBudState(BUD_DEAD);
-
475 }
-
476 }
-
477
-
478}
+
466 float leaf_aspect = 1.0; //ratio of leaf width to leaf length
+
467
+
468 float midrib_fold = 0.3; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
+
469
+
470 float longitudinal_curvature = context_ptr->randu(-0.4f,0.4f); //curvature factor along x-direction. (+curves upward, -curved downward)
+
471
+
472 float lateral_curvature = 0.; //curvature factor along y-direction. (+curves upward, -curved downward)
+
473
+
474 float wave_period = 0.3f; //period factor of leaf waves
+
475 float wave_amplitude = 0.1f; // amplitude of leaf waves
+
476
+
477 uint objID = buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, 0, wave_period, wave_amplitude, false);
+
478 context_ptr->translateObject( objID, make_vec3(-0.3,0,0) );
479
-
480uint RomaineLettuceLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
-
481
-
482 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/RomaineLettuceLeaf.png";
-
483
-
484// float leaf_aspect = 0.65; //ratio of leaf width to leaf length
-
485 float leaf_aspect = 0.85; //ratio of leaf width to leaf length
-
486
-
487 float midrib_fold = 0.2; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
-
488
-
489// float longitudinal_curvature = context_ptr->randu(-0.05f,0.2f); //curvature factor along x-direction. (+curves upward, -curved downward)
-
490 float longitudinal_curvature = context_ptr->randu(-0.2f,0.05f); //curvature factor along x-direction. (+curves upward, -curved downward)
-
491
-
492 float lateral_curvature = -0.4; //curvature factor along y-direction. (+curves upward, -curved downward)
-
493
-
494 float petiole_roll = 0; //add a small radius roll at the based of the leaf to better mate with the petiole. Value is the magnitude of the roll (+rolls upward, - rolls downward)
-
495
-
496 //parameters for leaf wave/wrinkles
-
497// float wave_period = context_ptr->randu( 0.1f, 0.2f); //period factor of leaf waves
-
498 float wave_period = context_ptr->randu( 0.15f, 0.25f); //period factor of leaf waves
-
499// float wave_amplitude = context_ptr->randu(0.03f,0.075f); // amplitude of leaf waves
-
500 float wave_amplitude = context_ptr->randu(0.05f,0.1f); // amplitude of leaf waves
-
501
-
502 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, petiole_roll, wave_period, wave_amplitude, false);
-
503
-
504}
+
480 return objID;
+
481}
+
482
+
483// Function to generate random float between min and max
+
484float random_float(float min, float max) {
+
485 return min + static_cast<float>(rand()) / (static_cast<float>(RAND_MAX/(max-min)));
+
486}
+
487
+
488// Function to check if two spheres overlap
+
489bool spheres_overlap(const helios::vec3& center1, float radius1, const helios::vec3& center2, float radius2) {
+
490 float distance = std::sqrt(
+
491 std::pow(center1.x - center2.x, 2) +
+
492 std::pow(center1.y - center2.y, 2) +
+
493 std::pow(center1.z - center2.z, 2)
+
494 );
+
495 return distance < (radius1 + radius2);
+
496}
+
497
+
498uint GrapevineFruitPrototype( helios::Context* context_ptr, uint subdivisions, float time_since_fruit_set ){
+
499
+
500 int num_grapes = 75;
+
501 float height = 7.0f; // Height of the cluster
+
502 float base_radius = 2.5f; // Base radius of the cluster
+
503 float taper_factor = 0.6f; // Taper factor (higher means more taper)
+
504 float grape_radius = 0.35f; // Fixed radius for each grape
505
-
506void RomaineLettucePhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ){
-
507
-
508 float fact = float(shoot_max_nodes-shoot_node_index)/float(shoot_max_nodes);
-
509
-
510 //set leaf scale based on position along the shoot
-
511// float scale = fmin(1.f, 1 + 0.1*fact);
-
512// phytomer->scaleLeafPrototypeScale(scale);
-
513
-
514// phytomer->rotateLeaf( 0, 0, make_AxisRotation(-deg2rad(15)*fact, 0, 0));
-
515 phytomer->rotateLeaf( 0, 0, make_AxisRotation(-deg2rad(60)*fact, 0, 0));
-
516
-
517}
-
518
-
519uint SorghumLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
506 std::vector<std::pair<helios::vec3, float>> grapes;
+
507 float z_step = height / num_grapes;
+
508
+
509 // Place the first grape at the bottom center
+
510 helios::vec3 first_center(0.0f, 0.0f, 0.0f);
+
511 grapes.push_back({first_center, grape_radius});
+
512
+
513 // Attempt to place each subsequent grape close to an existing grape
+
514 int max_attempts = 100; // Number of retries to find a tight fit
+
515
+
516 for (int i = 1; i < num_grapes; ++i) {
+
517 float z = i * z_step;
+
518 // Tapered radius based on height (denser at the top, sparser at the bottom)
+
519 float taper_radius = base_radius * (1.0f - taper_factor * (z / height));
520
-
521 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/SorghumLeaf.png";
-
522
-
523 float leaf_aspect = 0.2; //ratio of leaf width to leaf length
-
524
-
525 float midrib_fold_fraction = 0.3;
-
526
-
527 float longitudinal_curvature = context_ptr->randu(-1.2f,-0.8f);
-
528 float lateral_curvature = -0.3;
-
529
-
530 float petiole_roll = 0.04f;
+
521 bool placed = false;
+
522 int attempts = 0;
+
523 while (!placed && attempts < max_attempts) {
+
524 // Randomly select an existing grape as the reference point
+
525 int reference_idx = rand() % grapes.size();
+
526 const helios::vec3& reference_center = grapes[reference_idx].first;
+
527
+
528 // Pick a random offset direction from the reference grape
+
529 float angle = random_float(0, 2 * M_PI);
+
530 float distance = random_float(1.2 * grape_radius, 1.3 * grape_radius); // Keep grapes close but not overlapping
531
-
532 //parameters for leaf wave/wrinkles
-
533 float wave_period = 0.1f; //period factor of leaf waves
-
534 float wave_amplitude = 0.1f; // amplitude of leaf waves
-
535
-
536 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold_fraction, longitudinal_curvature, lateral_curvature, petiole_roll, wave_period, wave_amplitude, false);
-
537
-
538}
-
539
-
540uint SorghumPaniclePrototype( helios::Context* context_ptr, uint subdivisions, float time_since_fruit_set ){
-
541
-
542 if( subdivisions<=1 ){
-
543 subdivisions = 3;
-
544 }
+
532 // Compute the new potential center for the grape
+
533 helios::vec3 new_center(
+
534 reference_center.x + distance * cos(angle),
+
535 reference_center.y + distance * sin(angle),
+
536 random_float(z - 0.5f * z_step, z + 0.5f * z_step)
+
537 );
+
538
+
539 // Check that the new center is within the allowable radius (for tapering)
+
540 float new_center_distance = std::sqrt(new_center.x * new_center.x + new_center.y * new_center.y);
+
541 if (new_center_distance > taper_radius) {
+
542 attempts++;
+
543 continue; // Skip if the new position exceeds the tapered radius
+
544 }
545
-
546 float panicle_height = 1;
-
547 float panicle_width = 0.08;
-
548 float width_seed = 0.08;
-
549 float height_seed = 0.25;
-
550 float seed_tilt = 50;
-
551 subdivisions = 6;
-
552
-
553 std::string seed_texture_file = "plugins/plantarchitecture/assets/textures/SorghumSeed.jpeg";
-
554 RGBcolor stem_color(0.45,0.55,0.42);
-
555
-
556 std::vector<uint> UUIDs;
-
557
-
558 panicle_height -= 0.8*height_seed;
-
559
-
560 std::vector<vec3> nodes_panicle;
-
561 std::vector<float> radius_panicle;
-
562
-
563 for (int n = 0; n < subdivisions ; n++) {
-
564 float x = 0;
-
565 float y = 0;
-
566 float z;
-
567 if( n==0 ){
-
568 z = 0.5f*height_seed/float(subdivisions-1);
-
569 }else if( n==subdivisions-1 ){
-
570 z = (subdivisions-1.5f)*height_seed/float(subdivisions-1);
-
571 }else{
-
572 z = n*height_seed/float(subdivisions-1);
-
573 }
-
574
-
575 float angle = n * M_PI /float(subdivisions-1);
-
576 float dr = 0.5f * width_seed * sin(angle);
+
546 // Check for collisions with existing grapes
+
547 bool collision = false;
+
548 for (const auto& grape : grapes) {
+
549 if (spheres_overlap(new_center, grape_radius, grape.first, grape.second)) {
+
550 collision = true;
+
551 break;
+
552 }
+
553 }
+
554
+
555 // If no collision, place the grape
+
556 if (!collision) {
+
557 grapes.push_back({new_center, grape_radius});
+
558 placed = true;
+
559 }
+
560
+
561 attempts++;
+
562 }
+
563
+
564 }
+
565
+
566 std::vector<uint> UUIDs;
+
567 for (const auto& grape : grapes) {
+
568 std::vector<uint> UUIDs_tmp = context_ptr->addSphere( 10, grape.first, grape.second, "../../../plugins/plantarchitecture/assets/textures/GrapeBerry.jpg" );
+
569 UUIDs.insert(UUIDs.end(), UUIDs_tmp.begin(), UUIDs_tmp.end());
+
570 }
+
571
+
572 context_ptr->rotatePrimitive( UUIDs, -0.5*M_PI, "y");
+
573
+
574 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
575 return objID;
+
576}
577
-
578 nodes_panicle.push_back(make_vec3(x, y, z));
-
579 radius_panicle.push_back(dr);
-
580
-
581 }
-
582
-
583 std::vector<uint> UUIDs_seed_ptype = context_ptr->addTube( subdivisions, nodes_panicle, radius_panicle,seed_texture_file.c_str());
-
584
-
585 int Ntheta = ceil( 6.f*panicle_height/height_seed );
-
586 int Nphi = ceil( 2.f*M_PI*panicle_width/width_seed);
-
587
-
588 for(int j=0; j < Nphi; j++ ) {
-
589 for (int i = 0; i < Ntheta; i++) {
+
578//uint GrapevineFlowerPrototype( helios::Context* context_ptr, uint subdivisions, bool flower_is_open ){
+
579// std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/OliveFlower_open.obj", make_vec3(0.0,0,0), 0,nullrotation, RGB::black, "ZUP", true );
+
580// uint objID = context_ptr->addPolymeshObject( UUIDs );
+
581// return objID;
+
582//}
+
583
+
584void GrapevinePhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ) {
+
585
+
586 //blind nodes
+
587 if( shoot_node_index>=2 ){
+
588 phytomer->setFloralBudState( BUD_DEAD );
+
589 }
590
-
591 if( i==0 && j==0 ){
-
592 continue;
-
593 }
-
594
-
595 std::vector<uint> UUIDs_copy = context_ptr->copyPrimitive(UUIDs_seed_ptype);
-
596 context_ptr->scalePrimitive( UUIDs_copy, make_vec3(1,1,1)*context_ptr->randu(0.9f,1.1f));
-
597
-
598 float phi = 2.f * M_PI * float(j + 0.5f*float(i%2)) / float(Nphi);
-
599 float theta = acos(1 - 2 * float(i + float(j)/float(Nphi)) / float(Ntheta));
-
600 float x = sin(theta) * cos(phi);
-
601 float y = sin(theta) * sin(phi);
-
602 float z = 0.5f + 0.5f*cos(theta);
-
603
-
604 x *= 0.5f * panicle_width;
-
605 y *= 0.5f * panicle_width;
-
606 z *= panicle_height;
+
591}
+
592
+
593//void GrapevinePhytomerCallbackFunction( std::shared_ptr<Phytomer> phytomer ){
+
594//
+
595// if( phytomer->isdormant ){
+
596// if( phytomer->shoot_index.x >= phytomer->shoot_index.y-1 ){
+
597// phytomer->setVegetativeBudState( BUD_DORMANT ); //first vegetative buds always break
+
598// }
+
599// if( phytomer->shoot_index.x <= phytomer->shoot_index.y-4 ){
+
600// phytomer->setFloralBudState( BUD_DORMANT ); //first vegetative buds always break
+
601// }
+
602// }
+
603//
+
604//}
+
605
+
606uint PuncturevineLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
607
-
608 float tilt = - deg2rad(seed_tilt) * sqrtf(1.f - z / panicle_height);
+
608 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/PuncturevineLeaf.png";
609
-
610 context_ptr->rotatePrimitive(UUIDs_copy, tilt, "x");
-
611 context_ptr->rotatePrimitive(UUIDs_copy, phi - 0.5f * M_PI, "z");
-
612
-
613 context_ptr->translatePrimitive(UUIDs_copy, make_vec3(x, y, z));
-
614 UUIDs.insert(UUIDs.end(), UUIDs_copy.begin(), UUIDs_copy.end());
+
610 float leaf_aspect = 0.4; //ratio of leaf width to leaf length
+
611
+
612 float midrib_fold = 0.2; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
+
613
+
614 float longitudinal_curvature = -0.1; //curvature factor along x-direction. (+curves upward, -curved downward)
615
-
616 }
-
617 }
-
618
-
619 context_ptr->deletePrimitive(UUIDs_seed_ptype);
-
620
-
621 std::vector<uint> UUIDs_sphere = context_ptr->addSphere( 10, make_vec3(0,0,0.5*panicle_height), 0.5f, seed_texture_file.c_str() );
-
622 context_ptr->scalePrimitiveAboutPoint( UUIDs_sphere, make_vec3(1.9*panicle_width, 1.9*panicle_width, 0.8*panicle_height), make_vec3(0,0,0.5*panicle_height));
-
623 UUIDs.insert(UUIDs.end(), UUIDs_sphere.begin(), UUIDs_sphere.end());
-
624
-
625 context_ptr->rotatePrimitive(UUIDs, 0.5f*M_PI, "y");
-
626 context_ptr->translatePrimitive( UUIDs, make_vec3(-0.2,0,0));
-
627
-
628 uint objID = context_ptr->addPolymeshObject( UUIDs );
-
629 return objID;
-
630
-
631}
-
632
-
633void SorghumPhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ){
-
634
-
635 //set leaf scale based on position along the shoot
-
636 float scale = fmin(1.f, 0.7 + 0.3*float(shoot_node_index)/5.f);
-
637 phytomer->scaleLeafPrototypeScale(scale);
-
638
-
639 //set internode length based on position along the shoot
-
640 phytomer->scaleInternodeMaxLength(scale);
-
641
-
642}
-
643
-
644uint SoybeanLeafPrototype_trifoliate(helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
-
645// std::vector<uint> UUIDs;
-
646// UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/SoybeanLeaf.obj", make_vec3(0.,0,0), 0, nullrotation, RGB::black, "ZUP", true );
-
647// uint objID = context_ptr->addPolymeshObject( UUIDs );
-
648// return objID;
-
649
-
650 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/SoybeanLeaf.png";
-
651
-
652 float leaf_aspect = 1.0; //ratio of leaf width to leaf length
+
616 float lateral_curvature = 0.4; //curvature factor along y-direction. (+curves upward, -curved downward)
+
617
+
618 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, 0, 0, 0, false);
+
619
+
620}
+
621
+
622uint OliveLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
623
+
624// std::string leaf_texture = "plugins/plantarchitecture/assets/textures/OliveLeaf.png";
+
625//
+
626// float leaf_aspect = 0.4; //ratio of leaf width to leaf length
+
627//
+
628// float midrib_fold = 0.; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
+
629//
+
630// float longitudinal_curvature = 0.05; //curvature factor along x-direction. (+curves upward, -curved downward)
+
631//
+
632// float lateral_curvature = 0.1; //curvature factor along y-direction. (+curves upward, -curved downward)
+
633//
+
634// uint objID = buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, 0, 0, 0, false);
+
635
+
636 std::vector<uint> UUIDs_upper = context_ptr->addTile(make_vec3(0.5,0,0), make_vec2(1,0.2), nullrotation, make_int2(subdivisions,subdivisions), "plugins/plantarchitecture/assets/textures/OliveLeaf_upper.png");
+
637 std::vector<uint> UUIDs_lower = context_ptr->addTile(make_vec3(0.5,0,-1e-4), make_vec2(1,0.2), nullrotation, make_int2(subdivisions,subdivisions), "plugins/plantarchitecture/assets/textures/OliveLeaf_lower.png");
+
638 context_ptr->rotatePrimitive( UUIDs_lower, M_PI, "x" );
+
639
+
640 UUIDs_upper.insert(UUIDs_upper.end(), UUIDs_lower.begin(), UUIDs_lower.end());
+
641 uint objID = context_ptr->addPolymeshObject( UUIDs_upper );
+
642 return objID;
+
643}
+
644
+
645uint OliveFruitPrototype( helios::Context* context_ptr, uint subdivisions, float time_since_fruit_set ){
+
646 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/OliveFruit.obj", make_vec3(0.,0,0), 0,nullrotation, RGB::black, "ZUP", true );
+
647 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
648 std::vector<uint> UUIDs_fruit = context_ptr->filterPrimitivesByData( context_ptr->getObjectPrimitiveUUIDs(objID), "object_label", "fruit");
+
649// context_ptr->setPrimitiveColor( UUIDs_fruit, make_RGBcolor(0.3,0.15,0.2)); //purple
+
650 context_ptr->setPrimitiveColor( UUIDs_fruit, make_RGBcolor(0.65,0.7,0.4)); //green
+
651 return objID;
+
652}
653
-
654 float midrib_fold = 0.1; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
-
655
-
656 float longitudinal_curvature = context_ptr->randu(-0.2f,0.f); //curvature factor along x-direction. (+curves upward, -curved downward)
-
657
-
658 float lateral_curvature = -0.25; //curvature factor along y-direction. (+curves upward, -curved downward)
+
654uint OliveFlowerPrototype( helios::Context* context_ptr, uint subdivisions, bool flower_is_open ){
+
655 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/OliveFlower_open.obj", make_vec3(0.0,0,0), 0,nullrotation, RGB::black, "ZUP", true );
+
656 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
657 return objID;
+
658}
659
-
660 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, 0, 0, 0, true);
+
660void OlivePhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ) {
661
662}
663
-
664uint SoybeanLeafPrototype_unifoliate(helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
-
665 return SoybeanLeafPrototype_trifoliate(context_ptr, subdivisions, compound_leaf_index ); //\todo Add separate model for unifoliate leaves
-
666}
-
667
-
668uint SoybeanFruitPrototype( helios::Context* context_ptr, uint subdivisions, float time_since_fruit_set ){
-
669 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/SoybeanPod.obj", make_vec3(0.,0,0), 0,nullrotation, RGB::black, "ZUP", true );
-
670 uint objID = context_ptr->addPolymeshObject( UUIDs );
-
671 return objID;
+
664void OlivePhytomerCallbackFunction( std::shared_ptr<Phytomer> phytomer ){
+
665
+
666 if( phytomer->isdormant ){
+
667 if( phytomer->shoot_index.x < phytomer->shoot_index.y-8 ){
+
668 phytomer->setFloralBudState( BUD_DEAD );
+
669 }
+
670 }
+
671
672}
673
-
674uint SoybeanFlowerPrototype( helios::Context* context_ptr, uint subdivisions, bool flower_is_open ){
-
675 std::vector<uint> UUIDs;
-
676 if( flower_is_open ){
-
677 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/SoybeanFlower_open_white.obj", make_vec3(0.0,0,0), 0,nullrotation, RGB::black, "ZUP", true );
-
678 }else{
-
679 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/BeanFlower_closed_white.obj", make_vec3(0.0,0,0), 0,nullrotation, RGB::black, "ZUP", true );
-
680 }
-
681 uint objID = context_ptr->addPolymeshObject( UUIDs );
-
682 return objID;
-
683}
-
684
-
685void SoybeanPhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ){
-
686
-
687 if( shoot_node_index>5 || phytomer->rank>1 ) {
-
688 phytomer->setVegetativeBudState(BUD_DEAD);
-
689 }else{
-
690 phytomer->setFloralBudState(BUD_DEAD);
-
691 }
-
692
-
693 //set leaf and internode scale based on position along the shoot
-
694 float leaf_scale = fmin(1.f, 0.2 + 0.8 * plant_age / 15.f);
-
695 phytomer->scaleLeafPrototypeScale(leaf_scale);
-
696
-
697 //set internode length based on position along the shoot
-
698 float inode_scale = fmin(1.f, 0.1 + 0.9 * plant_age / 15.f);
-
699 phytomer->scaleInternodeMaxLength(inode_scale);
-
700
-
701}
-
702
-
703uint StrawberryLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
-
704
-
705 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/StrawberryLeaf.png";
-
706
-
707 float leaf_aspect = 1.0; //ratio of leaf width to leaf length
-
708
-
709 float midrib_fold_fraction = 0.2;
-
710
-
711 float longitudinal_curvature = -0.01;
-
712 float lateral_curvature = -0.2;
+
674uint PistachioLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
675
+
676 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/PistachioLeaf.png";
+
677
+
678 float leaf_aspect = 0.6; //ratio of leaf width to leaf length
+
679
+
680 float midrib_fold = 0.; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
+
681
+
682 float longitudinal_curvature = context_ptr->randu(-0.4f,0.4f); //curvature factor along x-direction. (+curves upward, -curved downward)
+
683
+
684 float lateral_curvature = 0.; //curvature factor along y-direction. (+curves upward, -curved downward)
+
685
+
686 float wave_period = 0.3f; //period factor of leaf waves
+
687 float wave_amplitude = 0.1f; // amplitude of leaf waves
+
688
+
689 uint objID = buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, 0, wave_period, wave_amplitude, false);
+
690
+
691 return objID;
+
692}
+
693
+
694uint PistachioFruitPrototype( helios::Context* context_ptr, uint subdivisions, float time_since_fruit_set ){
+
695 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/PistachioNut.obj", make_vec3(0.,0,0), 0,nullrotation, RGB::black, "ZUP", true );
+
696 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
697 return objID;
+
698}
+
699
+
700uint PistachioFlowerPrototype( helios::Context* context_ptr, uint subdivisions, bool flower_is_open ){
+
701 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/OliveFlower_open.obj", make_vec3(0.0,0,0), 0,nullrotation, RGB::black, "ZUP", true );
+
702 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
703 return objID;
+
704}
+
705
+
706void PistachioPhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ) {
+
707
+
708 //blind nodes
+
709 if( shoot_node_index<2 ){
+
710 phytomer->setVegetativeBudState( BUD_DEAD );
+
711 phytomer->setFloralBudState( BUD_DEAD );
+
712 }
713
-
714 //parameters for leaf wave/wrinkles
-
715 float wave_period = 0.3f; //period factor of leaf waves
-
716 float wave_amplitude = 0.01f; // amplitude of leaf waves
+
714}
+
715
+
716void PistachioPhytomerCallbackFunction( std::shared_ptr<Phytomer> phytomer ){
717
-
718 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold_fraction, longitudinal_curvature, lateral_curvature, 0, wave_period, wave_amplitude, true);
-
719
-
720}
-
721
-
722uint StrawberryFlowerPrototype( helios::Context* context_ptr, uint subdivisions, bool flower_is_open ){
-
723 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/StrawberryFlower.obj", make_vec3(0.0,0,0), 0,nullrotation, RGB::black, "ZUP", true );
-
724 uint objID = context_ptr->addPolymeshObject( UUIDs );
-
725 return objID;
-
726}
-
727
-
728uint StrawberryFruitPrototype( helios::Context* context_ptr, uint subdivisions, float time_since_fruit_set ){
-
729 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/StrawberryFruit.obj", make_vec3(0.,0,0), 0,nullrotation, RGB::black, "ZUP", true );
-
730 uint objID = context_ptr->addPolymeshObject( UUIDs );
-
731 return objID;
-
732}
-
733
-
734uint SugarbeetLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
-
735
-
736 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/SugarbeetLeaf.png";
+
718 if( phytomer->isdormant ){
+
719 if( phytomer->shoot_index.x >= phytomer->shoot_index.y-1 ){
+
720 phytomer->setVegetativeBudState( BUD_DORMANT ); //first vegetative buds always break
+
721 }
+
722 if( phytomer->shoot_index.x <= phytomer->shoot_index.y-4 ){
+
723 phytomer->setFloralBudState( BUD_DORMANT ); //first vegetative buds always break
+
724 }
+
725 }
+
726
+
727}
+
728
+
729uint PuncturevineFlowerPrototype( helios::Context* context_ptr, uint subdivisions, bool flower_is_open ){
+
730 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/PuncturevineFlower.obj", make_vec3(0.0,0,0), 0,nullrotation, RGB::black, "ZUP", true );
+
731 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
732 return objID;
+
733}
+
734
+
735uint RedbudLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
736 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/RedbudLeaf.png";
737
-
738 float leaf_aspect = 0.4; //ratio of leaf width to leaf length
+
738 float leaf_aspect = 1.0; //ratio of leaf width to leaf length
739
-
740 float midrib_fold = 0.1; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
+
740 float midrib_fold = 0.2; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
741
-
742 float longitudinal_curvature = -0.2; //curvature factor along x-direction. (+curves upward, -curved downward)
+
742 float longitudinal_curvature = -0.15; //curvature factor along x-direction. (+curves upward, -curved downward)
743
-
744 float lateral_curvature = 0.4; //curvature factor along y-direction. (+curves upward, -curved downward)
+
744 float lateral_curvature = -0.1; //curvature factor along y-direction. (+curves upward, -curved downward)
745
-
746 float petiole_roll = 0.75; //add a small radius roll at the based of the leaf to better mate with the petiole. Value is the magnitude of the roll (+rolls upward, - rolls downward)
-
747
-
748 //parameters for leaf wave/wrinkles
-
749 float wave_period = context_ptr->randu( 0.08f, 0.15f); //period factor of leaf waves
-
750 float wave_amplitude = context_ptr->randu(0.02f,0.04f); // amplitude of leaf waves
-
751
-
752 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, petiole_roll, wave_period, wave_amplitude, false);
-
753
+
746 //parameters for leaf wave/wrinkles
+
747 float wave_period = 0.3f; //period factor of leaf waves
+
748 float wave_amplitude = 0.025f; // amplitude of leaf waves
+
749
+
750 uint objID = buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, 0, wave_period, wave_amplitude, false);
+
751 context_ptr->translateObject( objID, make_vec3(-0.3,0,0) );
+
752
+
753 return objID;
754}
755
-
756uint TomatoLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
-
757// std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/TomatoLeaf.obj", make_vec3(0.,0,0), 0, nullrotation, RGB::black, "ZUP", true );
-
758// uint objID = context_ptr->addPolymeshObject( UUIDs );
-
759// return objID;
+
756uint RedbudFlowerPrototype( helios::Context* context_ptr, uint subdivisions, bool flower_is_open ){
+
757 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/RedbudFlower_open.obj", make_vec3(0.0,0,0), 0,nullrotation, RGB::black, "ZUP", true );
+
758 return context_ptr->addPolymeshObject( UUIDs );
+
759}
760
-
761 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/TomatoLeaf_centered.png";
-
762
-
763 float leaf_aspect = 0.5; //ratio of leaf width to leaf length
-
764
-
765 float midrib_fold = 0.1; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
-
766
-
767 float longitudinal_curvature = context_ptr->randu(-0.45f,-0.2f); //curvature factor along x-direction. (+curves upward, -curved downward)
-
768
-
769 float lateral_curvature = -0.3; //curvature factor along y-direction. (+curves upward, -curved downward)
-
770
-
771 //parameters for leaf wave/wrinkles
-
772 float wave_period = 0.35f; //period factor of leaf waves
-
773 float wave_amplitude = 0.08f; // amplitude of leaf waves
-
774
-
775 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, 0, wave_period, wave_amplitude, false);
-
776
-
777}
-
778
-
779uint TomatoFruitPrototype( helios::Context* context_ptr, uint subdivisions, float time_since_fruit_set ){
-
780 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/TomatoFruit.obj", make_vec3(0.,0,0), 0.75,nullrotation, RGB::black, "ZUP", true );
-
781 uint objID = context_ptr->addPolymeshObject( UUIDs );
-
782 return objID;
-
783}
-
784
-
785uint TomatoFlowerPrototype( helios::Context* context_ptr, uint subdivisions, bool flower_is_open ){
-
786 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/TomatoFlower.obj", make_vec3(0.0,0,0), 0.75,nullrotation, RGB::black, "ZUP", true );
-
787 uint objID = context_ptr->addPolymeshObject( UUIDs );
-
788 return objID;
-
789}
-
790
-
791void TomatoPhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ){
-
792
-
793 if( shoot_node_index>5 || phytomer->rank>1 ) {
-
794 phytomer->setVegetativeBudState(BUD_DEAD);
-
795 }
-
796 if( shoot_node_index<8 && phytomer->rank==0 ){
-
797 phytomer->setFloralBudState(BUD_DEAD);
-
798 }
+
761uint RedbudFruitPrototype( helios::Context* context_ptr, uint subdivisions, float time_since_fruit_set ){
+
762 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/RedbudPod.obj", make_vec3(0.,0,0), 0,nullrotation, RGB::black, "ZUP", true );
+
763 return context_ptr->addPolymeshObject( UUIDs );
+
764}
+
765
+
766void RedbudPhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ){
+
767
+
768}
+
769
+
770void RedbudPhytomerCallbackFunction( std::shared_ptr<Phytomer> phytomer ){
+
771
+
772 int Nchild_shoots = randu(0,3);
+
773
+
774 if( phytomer->isdormant ){
+
775 if( phytomer->rank<=1 ){
+
776 Nchild_shoots = std::max(2,Nchild_shoots);
+
777 }
+
778 if( phytomer->shoot_index.x < phytomer->shoot_index.y-Nchild_shoots ){
+
779 phytomer->setVegetativeBudState( BUD_DEAD );
+
780 }
+
781 else{
+
782 phytomer->setFloralBudState(BUD_DEAD);
+
783 }
+
784 }
+
785
+
786}
+
787
+
788uint RomaineLettuceLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
789
+
790 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/RomaineLettuceLeaf.png";
+
791
+
792// float leaf_aspect = 0.65; //ratio of leaf width to leaf length
+
793 float leaf_aspect = 0.85; //ratio of leaf width to leaf length
+
794
+
795 float midrib_fold = 0.2; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
+
796
+
797// float longitudinal_curvature = context_ptr->randu(-0.05f,0.2f); //curvature factor along x-direction. (+curves upward, -curved downward)
+
798 float longitudinal_curvature = context_ptr->randu(-0.2f,0.05f); //curvature factor along x-direction. (+curves upward, -curved downward)
799
-
800 //set leaf and internode scale based on position along the shoot
-
801 float leaf_scale = fmin(1.f, 0.5 + 0.5 * plant_age / 10.f);
-
802 phytomer->scaleLeafPrototypeScale(leaf_scale);
+
800 float lateral_curvature = -0.4; //curvature factor along y-direction. (+curves upward, -curved downward)
+
801
+
802 float petiole_roll = 0; //add a small radius roll at the based of the leaf to better mate with the petiole. Value is the magnitude of the roll (+rolls upward, - rolls downward)
803
-
804 //set internode length based on position along the shoot
-
805 float inode_scale = fmin(1.f, 0.7 + 0.3 * plant_age / 10.f);
-
806 phytomer->scaleInternodeMaxLength(inode_scale);
-
807
-
808}
+
804 //parameters for leaf wave/wrinkles
+
805// float wave_period = context_ptr->randu( 0.1f, 0.2f); //period factor of leaf waves
+
806 float wave_period = context_ptr->randu( 0.15f, 0.25f); //period factor of leaf waves
+
807// float wave_amplitude = context_ptr->randu(0.03f,0.075f); // amplitude of leaf waves
+
808 float wave_amplitude = context_ptr->randu(0.05f,0.1f); // amplitude of leaf waves
809
-
810uint WheatLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
810 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, petiole_roll, wave_period, wave_amplitude, false);
811
-
812 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/SorghumLeaf.png";
+
812}
813
-
814 float leaf_aspect = 0.2; //ratio of leaf width to leaf length
+
814void RomaineLettucePhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ){
815
-
816 float midrib_fold_fraction = 0.3;
+
816 float fact = float(shoot_max_nodes-shoot_node_index)/float(shoot_max_nodes);
817
-
818 float longitudinal_curvature = context_ptr->randu(-2.2f,-1.5f);
-
819 float lateral_curvature = -0.3;
-
820
-
821 float petiole_roll = 0.04f;
-
822
-
823 //parameters for leaf wave/wrinkles
-
824 float wave_period = 0.1f; //period factor of leaf waves
-
825 float wave_amplitude = 0.05f; // amplitude of leaf waves
+
818 //set leaf scale based on position along the shoot
+
819// float scale = fmin(1.f, 1 + 0.1*fact);
+
820// phytomer->scaleLeafPrototypeScale(scale);
+
821
+
822// phytomer->rotateLeaf( 0, 0, make_AxisRotation(-deg2rad(15)*fact, 0, 0));
+
823 phytomer->rotateLeaf( 0, 0, make_AxisRotation(-deg2rad(60)*fact, 0, 0));
+
824
+
825}
826
-
827 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold_fraction, longitudinal_curvature, lateral_curvature, petiole_roll, wave_period, wave_amplitude, false);
+
827uint SorghumLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
828
-
829}
+
829 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/SorghumLeaf.png";
830
-
831uint WheatSpikePrototype( helios::Context* context_ptr, uint subdivisions, float time_since_fruit_set ){
-
832 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/WheatSpike.obj", make_vec3(0.,0,0), 0,nullrotation, RGB::black, "ZUP", true );
-
833 uint objID = context_ptr->addPolymeshObject( UUIDs );
-
834 return objID;
-
835}
-
836
-
837void WheatPhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ){
-
838
-
839 //set leaf scale based on position along the shoot
-
840 float scale = fmin(1.f, 0.7 + 0.3*float(shoot_node_index)/5.f);
-
841 phytomer->scaleLeafPrototypeScale(scale);
-
842
-
843 //set internode length based on position along the shoot
-
844 phytomer->scaleInternodeMaxLength(scale);
+
831 float leaf_aspect = 0.2; //ratio of leaf width to leaf length
+
832
+
833 float midrib_fold_fraction = 0.3;
+
834
+
835 float longitudinal_curvature = context_ptr->randu(-1.2f,-0.8f);
+
836 float lateral_curvature = -0.3;
+
837
+
838 float petiole_roll = 0.04f;
+
839
+
840 //parameters for leaf wave/wrinkles
+
841 float wave_period = 0.1f; //period factor of leaf waves
+
842 float wave_amplitude = 0.1f; // amplitude of leaf waves
+
843
+
844 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold_fraction, longitudinal_curvature, lateral_curvature, petiole_roll, wave_period, wave_amplitude, false);
845
846}
+
847
+
848uint SorghumPaniclePrototype( helios::Context* context_ptr, uint subdivisions, float time_since_fruit_set ){
+
849
+
850 if( subdivisions<=1 ){
+
851 subdivisions = 3;
+
852 }
+
853
+
854 float panicle_height = 1;
+
855 float panicle_width = 0.08;
+
856 float width_seed = 0.08;
+
857 float height_seed = 0.25;
+
858 float seed_tilt = 50;
+
859 subdivisions = 6;
+
860
+
861 std::string seed_texture_file = "plugins/plantarchitecture/assets/textures/SorghumSeed.jpeg";
+
862 RGBcolor stem_color(0.45,0.55,0.42);
+
863
+
864 std::vector<uint> UUIDs;
+
865
+
866 panicle_height -= 0.8*height_seed;
+
867
+
868 std::vector<vec3> nodes_panicle;
+
869 std::vector<float> radius_panicle;
+
870
+
871 for (int n = 0; n < subdivisions ; n++) {
+
872 float x = 0;
+
873 float y = 0;
+
874 float z;
+
875 if( n==0 ){
+
876 z = 0.5f*height_seed/float(subdivisions-1);
+
877 }else if( n==subdivisions-1 ){
+
878 z = (subdivisions-1.5f)*height_seed/float(subdivisions-1);
+
879 }else{
+
880 z = n*height_seed/float(subdivisions-1);
+
881 }
+
882
+
883 float angle = float(n) * M_PI /float(subdivisions-1);
+
884 float dr = std::fmax(0.f, 0.5f * width_seed * sin(angle));
+
885
+
886 nodes_panicle.push_back(make_vec3(x, y, z));
+
887 radius_panicle.push_back(dr);
+
888
+
889 }
+
890
+
891 std::vector<uint> UUIDs_seed_ptype = context_ptr->addTube( subdivisions, nodes_panicle, radius_panicle,seed_texture_file.c_str());
+
892
+
893 int Ntheta = ceil( 6.f*panicle_height/height_seed );
+
894 int Nphi = ceil( 2.f*M_PI*panicle_width/width_seed);
+
895
+
896 for(int j=0; j < Nphi; j++ ) {
+
897 for (int i = 0; i < Ntheta; i++) {
+
898
+
899 if( i==0 && j==0 ){
+
900 continue;
+
901 }
+
902
+
903 std::vector<uint> UUIDs_copy = context_ptr->copyPrimitive(UUIDs_seed_ptype);
+
904 context_ptr->scalePrimitive( UUIDs_copy, make_vec3(1,1,1)*context_ptr->randu(0.9f,1.1f));
+
905
+
906 float phi = 2.f * M_PI * float(j + 0.5f*float(i%2)) / float(Nphi);
+
907 float theta = acos(1 - 2 * float(i + float(j)/float(Nphi)) / float(Ntheta));
+
908 float x = sin(theta) * cos(phi);
+
909 float y = sin(theta) * sin(phi);
+
910 float z = 0.5f + 0.5f*cos(theta);
+
911
+
912 x *= 0.5f * panicle_width;
+
913 y *= 0.5f * panicle_width;
+
914 z *= panicle_height;
+
915
+
916 float tilt = - deg2rad(seed_tilt) * sqrtf(1.f - z / panicle_height);
+
917
+
918 context_ptr->rotatePrimitive(UUIDs_copy, tilt, "x");
+
919 context_ptr->rotatePrimitive(UUIDs_copy, phi - 0.5f * M_PI, "z");
+
920
+
921 context_ptr->translatePrimitive(UUIDs_copy, make_vec3(x, y, z));
+
922 UUIDs.insert(UUIDs.end(), UUIDs_copy.begin(), UUIDs_copy.end());
+
923
+
924 }
+
925 }
+
926
+
927 context_ptr->deletePrimitive(UUIDs_seed_ptype);
+
928
+
929 std::vector<uint> UUIDs_sphere = context_ptr->addSphere( 10, make_vec3(0,0,0.5*panicle_height), 0.5f, seed_texture_file.c_str() );
+
930 context_ptr->scalePrimitiveAboutPoint( UUIDs_sphere, make_vec3(1.9*panicle_width, 1.9*panicle_width, 0.8*panicle_height), make_vec3(0,0,0.5*panicle_height));
+
931 UUIDs.insert(UUIDs.end(), UUIDs_sphere.begin(), UUIDs_sphere.end());
+
932
+
933 context_ptr->rotatePrimitive(UUIDs, 0.5f*M_PI, "y");
+
934 context_ptr->translatePrimitive( UUIDs, make_vec3(-0.2,0,0));
+
935
+
936 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
937 return objID;
+
938
+
939}
+
940
+
941void SorghumPhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ){
+
942
+
943 //set leaf scale based on position along the shoot
+
944 float scale = fmin(1.f, 0.7 + 0.3*float(shoot_node_index)/5.f);
+
945 phytomer->scaleLeafPrototypeScale(scale);
+
946
+
947 //set internode length based on position along the shoot
+
948 phytomer->scaleInternodeMaxLength(scale);
+
949
+
950}
+
951
+
952uint SoybeanLeafPrototype_trifoliate(helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
953// std::vector<uint> UUIDs;
+
954// UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/SoybeanLeaf.obj", make_vec3(0.,0,0), 0, nullrotation, RGB::black, "ZUP", true );
+
955// uint objID = context_ptr->addPolymeshObject( UUIDs );
+
956// return objID;
+
957
+
958 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/SoybeanLeaf.png";
+
959
+
960 float leaf_aspect = 1.0; //ratio of leaf width to leaf length
+
961
+
962 float midrib_fold = 0.1; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
+
963
+
964 float longitudinal_curvature = context_ptr->randu(-0.2f,0.f); //curvature factor along x-direction. (+curves upward, -curved downward)
+
965
+
966 float lateral_curvature = -0.25; //curvature factor along y-direction. (+curves upward, -curved downward)
+
967
+
968 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, 0, 0, 0, true);
+
969
+
970}
+
971
+
972uint SoybeanLeafPrototype_unifoliate(helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
973 return SoybeanLeafPrototype_trifoliate(context_ptr, subdivisions, compound_leaf_index ); //\todo Add separate model for unifoliate leaves
+
974}
+
975
+
976uint SoybeanFruitPrototype( helios::Context* context_ptr, uint subdivisions, float time_since_fruit_set ){
+
977 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/SoybeanPod.obj", make_vec3(0.,0,0), 0,nullrotation, RGB::black, "ZUP", true );
+
978 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
979 return objID;
+
980}
+
981
+
982uint SoybeanFlowerPrototype( helios::Context* context_ptr, uint subdivisions, bool flower_is_open ){
+
983 std::vector<uint> UUIDs;
+
984 if( flower_is_open ){
+
985 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/SoybeanFlower_open_white.obj", make_vec3(0.0,0,0), 0,nullrotation, RGB::black, "ZUP", true );
+
986 }else{
+
987 UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/BeanFlower_closed_white.obj", make_vec3(0.0,0,0), 0,nullrotation, RGB::black, "ZUP", true );
+
988 }
+
989 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
990 return objID;
+
991}
+
992
+
993void SoybeanPhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ){
+
994
+
995 if( shoot_node_index>5 || phytomer->rank>1 ) {
+
996 phytomer->setVegetativeBudState(BUD_DEAD);
+
997 }else{
+
998 phytomer->setFloralBudState(BUD_DEAD);
+
999 }
+
1000
+
1001 //set leaf and internode scale based on position along the shoot
+
1002 float leaf_scale = fmin(1.f, 0.2 + 0.8 * plant_age / 15.f);
+
1003 phytomer->scaleLeafPrototypeScale(leaf_scale);
+
1004
+
1005 //set internode length based on position along the shoot
+
1006 float inode_scale = fmin(1.f, 0.1 + 0.9 * plant_age / 15.f);
+
1007 phytomer->scaleInternodeMaxLength(inode_scale);
+
1008
+
1009}
+
1010
+
1011uint StrawberryLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
1012
+
1013 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/StrawberryLeaf.png";
+
1014
+
1015 float leaf_aspect = 1.0; //ratio of leaf width to leaf length
+
1016
+
1017 float midrib_fold_fraction = 0.2;
+
1018
+
1019 float longitudinal_curvature = -0.01;
+
1020 float lateral_curvature = -0.2;
+
1021
+
1022 //parameters for leaf wave/wrinkles
+
1023 float wave_period = 0.3f; //period factor of leaf waves
+
1024 float wave_amplitude = 0.01f; // amplitude of leaf waves
+
1025
+
1026 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold_fraction, longitudinal_curvature, lateral_curvature, 0, wave_period, wave_amplitude, true);
+
1027
+
1028}
+
1029
+
1030uint StrawberryFlowerPrototype( helios::Context* context_ptr, uint subdivisions, bool flower_is_open ){
+
1031 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/StrawberryFlower.obj", make_vec3(0.0,0,0), 0,nullrotation, RGB::black, "ZUP", true );
+
1032 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
1033 return objID;
+
1034}
+
1035
+
1036uint StrawberryFruitPrototype( helios::Context* context_ptr, uint subdivisions, float time_since_fruit_set ){
+
1037 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/StrawberryFruit.obj", make_vec3(0.,0,0), 0,nullrotation, RGB::black, "ZUP", true );
+
1038 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
1039 return objID;
+
1040}
+
1041
+
1042uint SugarbeetLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
1043
+
1044 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/SugarbeetLeaf.png";
+
1045
+
1046 float leaf_aspect = 0.4; //ratio of leaf width to leaf length
+
1047
+
1048 float midrib_fold = 0.1; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
+
1049
+
1050 float longitudinal_curvature = -0.2; //curvature factor along x-direction. (+curves upward, -curved downward)
+
1051
+
1052 float lateral_curvature = 0.4; //curvature factor along y-direction. (+curves upward, -curved downward)
+
1053
+
1054 float petiole_roll = 0.75; //add a small radius roll at the based of the leaf to better mate with the petiole. Value is the magnitude of the roll (+rolls upward, - rolls downward)
+
1055
+
1056 //parameters for leaf wave/wrinkles
+
1057 float wave_period = context_ptr->randu( 0.08f, 0.15f); //period factor of leaf waves
+
1058 float wave_amplitude = context_ptr->randu(0.02f,0.04f); // amplitude of leaf waves
+
1059
+
1060 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, petiole_roll, wave_period, wave_amplitude, false);
+
1061
+
1062}
+
1063
+
1064uint TomatoLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
1065// std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/TomatoLeaf.obj", make_vec3(0.,0,0), 0, nullrotation, RGB::black, "ZUP", true );
+
1066// uint objID = context_ptr->addPolymeshObject( UUIDs );
+
1067// return objID;
+
1068
+
1069 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/TomatoLeaf_centered.png";
+
1070
+
1071 float leaf_aspect = 0.5; //ratio of leaf width to leaf length
+
1072
+
1073 float midrib_fold = 0.1; //fraction of folding along midrib (=0 leaf is flat, =1 leaf is completely folded in half)
+
1074
+
1075 float longitudinal_curvature = context_ptr->randu(-0.45f,-0.2f); //curvature factor along x-direction. (+curves upward, -curved downward)
+
1076
+
1077 float lateral_curvature = -0.3; //curvature factor along y-direction. (+curves upward, -curved downward)
+
1078
+
1079 //parameters for leaf wave/wrinkles
+
1080 float wave_period = 0.35f; //period factor of leaf waves
+
1081 float wave_amplitude = 0.08f; // amplitude of leaf waves
+
1082
+
1083 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold, longitudinal_curvature, lateral_curvature, 0, wave_period, wave_amplitude, false);
+
1084
+
1085}
+
1086
+
1087uint TomatoFruitPrototype( helios::Context* context_ptr, uint subdivisions, float time_since_fruit_set ){
+
1088 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/TomatoFruit.obj", make_vec3(0.,0,0), 0.75,nullrotation, RGB::black, "ZUP", true );
+
1089 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
1090 return objID;
+
1091}
+
1092
+
1093uint TomatoFlowerPrototype( helios::Context* context_ptr, uint subdivisions, bool flower_is_open ){
+
1094 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/TomatoFlower.obj", make_vec3(0.0,0,0), 0.75,nullrotation, RGB::black, "ZUP", true );
+
1095 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
1096 return objID;
+
1097}
+
1098
+
1099void TomatoPhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ){
+
1100
+
1101 if( shoot_node_index>5 || phytomer->rank>1 ) {
+
1102 phytomer->setVegetativeBudState(BUD_DEAD);
+
1103 }
+
1104 if( shoot_node_index<8 && phytomer->rank==0 ){
+
1105 phytomer->setFloralBudState(BUD_DEAD);
+
1106 }
+
1107
+
1108 //set leaf and internode scale based on position along the shoot
+
1109 float leaf_scale = fmin(1.f, 0.5 + 0.5 * plant_age / 10.f);
+
1110 phytomer->scaleLeafPrototypeScale(leaf_scale);
+
1111
+
1112 //set internode length based on position along the shoot
+
1113 float inode_scale = fmin(1.f, 0.7 + 0.3 * plant_age / 10.f);
+
1114 phytomer->scaleInternodeMaxLength(inode_scale);
+
1115
+
1116}
+
1117
+
1118uint WheatLeafPrototype( helios::Context* context_ptr, uint subdivisions, int compound_leaf_index ){
+
1119
+
1120 std::string leaf_texture = "plugins/plantarchitecture/assets/textures/SorghumLeaf.png";
+
1121
+
1122 float leaf_aspect = 0.2; //ratio of leaf width to leaf length
+
1123
+
1124 float midrib_fold_fraction = 0.3;
+
1125
+
1126 float longitudinal_curvature = context_ptr->randu(-2.2f,-1.5f);
+
1127 float lateral_curvature = -0.3;
+
1128
+
1129 float petiole_roll = 0.04f;
+
1130
+
1131 //parameters for leaf wave/wrinkles
+
1132 float wave_period = 0.1f; //period factor of leaf waves
+
1133 float wave_amplitude = 0.05f; // amplitude of leaf waves
+
1134
+
1135 return buildGenericLeafPrototype(context_ptr, subdivisions, leaf_texture, leaf_aspect, midrib_fold_fraction, longitudinal_curvature, lateral_curvature, petiole_roll, wave_period, wave_amplitude, false);
+
1136
+
1137}
+
1138
+
1139uint WheatSpikePrototype( helios::Context* context_ptr, uint subdivisions, float time_since_fruit_set ){
+
1140 std::vector<uint> UUIDs = context_ptr->loadOBJ( "plugins/plantarchitecture/assets/obj/WheatSpike.obj", make_vec3(0.,0,0), 0,nullrotation, RGB::black, "ZUP", true );
+
1141 uint objID = context_ptr->addPolymeshObject( UUIDs );
+
1142 return objID;
+
1143}
+
1144
+
1145void WheatPhytomerCreationFunction( std::shared_ptr<Phytomer> phytomer, uint shoot_node_index, uint parent_shoot_node_index, uint shoot_max_nodes, float plant_age ){
+
1146
+
1147 //set leaf scale based on position along the shoot
+
1148 float scale = fmin(1.f, 0.7 + 0.3*float(shoot_node_index)/5.f);
+
1149 phytomer->scaleLeafPrototypeScale(scale);
+
1150
+
1151 //set internode length based on position along the shoot
+
1152 phytomer->scaleInternodeMaxLength(scale);
+
1153
+
1154}
uint buildGenericLeafPrototype(helios::Context *context_ptr, uint subdivisions, const std::string &leaf_texture, float leaf_aspect_ratio, float midrib_fold_fraction, float longitudinal_curvature, float lateral_curvature, float petiole_roll, float wave_period, float wave_amplitude, bool build_petiolule)
Function to procedurally build a generic leaf prototype with features such as midrib fold,...
Definition Assets.cpp:20
Stores the state associated with simulation.
Definition Context.h:1882
-
void translatePrimitive(uint UUID, const vec3 &shift)
Translate a primitive using its UUID.
Definition Context.cpp:1401
-
void deletePrimitive(uint UUID)
Delete a single primitive from the context.
Definition Context.cpp:1531
-
void rotateObject(uint ObjID, float rotation_radians, const char *rotation_axis_xyz)
Rotate a single compound object about the x, y, or z axis.
Definition Context.cpp:2832
-
float randu()
Draw a random number from a uniform distribution between 0 and 1.
Definition Context.cpp:1173
-
void rotatePrimitive(uint UUID, float rot, const char *axis)
Rotate a primitive about the x, y, or z axis using its UUID.
Definition Context.cpp:1415
-
void translateObject(uint ObjID, const vec3 &shift)
Translate a single compound object.
Definition Context.cpp:2822
-
uint copyPrimitive(uint UUID)
Make a copy of a primitive from the context.
Definition Context.cpp:1573
+
void setPrimitiveColor(uint UUID, const helios::RGBcolor &color)
Method to set the diffuse color of a Primitive.
Definition Context.cpp:7083
+
void translatePrimitive(uint UUID, const vec3 &shift)
Translate a primitive using its UUID.
Definition Context.cpp:1396
+
void deletePrimitive(uint UUID)
Delete a single primitive from the context.
Definition Context.cpp:1526
+
void rotateObject(uint ObjID, float rotation_radians, const char *rotation_axis_xyz)
Rotate a single compound object about the x, y, or z axis.
Definition Context.cpp:2827
+
std::vector< uint > filterPrimitivesByData(const std::vector< uint > &UUIDs, const std::string &primitive_data_label, float filter_value, const std::string &comparator)
Filter a set of primitives based on their primitive data and a condition and float value.
+
float randu()
Draw a random number from a uniform distribution between 0 and 1.
Definition Context.cpp:1168
+
void rotatePrimitive(uint UUID, float rot, const char *axis)
Rotate a primitive about the x, y, or z axis using its UUID.
Definition Context.cpp:1410
+
void translateObject(uint ObjID, const vec3 &shift)
Translate a single compound object.
Definition Context.cpp:2817
+
std::vector< uint > getObjectPrimitiveUUIDs(uint ObjID) const
Get primitive UUIDs associated with compound object (single object ID input)
Definition Context.cpp:2887
+
uint copyPrimitive(uint UUID)
Make a copy of a primitive from the context.
Definition Context.cpp:1568
std::vector< uint > loadOBJ(const char *filename, bool silent=false)
Load geometry contained in a Wavefront OBJ file (.obj). Model will be placed at the origin without an...
-
void scalePrimitive(uint UUID, const helios::vec3 &S)
Scale a primitive using its UUID relative to the origin (0,0,0)
Definition Context.cpp:1486
-
void scalePrimitiveAboutPoint(uint UUID, const helios::vec3 &S, const helios::vec3 point)
Scale a primitive using its UUID about an arbitrary point in space.
Definition Context.cpp:1507
+
void scalePrimitive(uint UUID, const helios::vec3 &S)
Scale a primitive using its UUID relative to the origin (0,0,0)
Definition Context.cpp:1481
+
void scalePrimitiveAboutPoint(uint UUID, const helios::vec3 &S, const helios::vec3 point)
Scale a primitive using its UUID about an arbitrary point in space.
Definition Context.cpp:1502
SphericalCoord nullrotation
Default null SphericalCoord that applies no rotation.
Definition global.cpp:57
-
uint addTubeObject(uint radial_subdivisions, const std::vector< vec3 > &nodes, const std::vector< float > &radius)
Add a 3D tube compound object to the Context.
Definition Context.cpp:4638
-
uint addPolymeshObject(const std::vector< uint > &UUIDs)
Add new Polymesh Compound Object.
Definition Context.cpp:5276
-
std::vector< uint > addSphere(uint Ndivs, const vec3 &center, float radius)
Add a spherical compound object to the Context.
Definition Context.cpp:5523
-
std::vector< uint > addTube(uint Ndivs, const std::vector< vec3 > &nodes, const std::vector< float > &radius)
Add a 3D tube compound object to the Context.
Definition Context.cpp:5807
+
uint addTubeObject(uint radial_subdivisions, const std::vector< vec3 > &nodes, const std::vector< float > &radius)
Add a 3D tube compound object to the Context.
Definition Context.cpp:4690
+
uint addPolymeshObject(const std::vector< uint > &UUIDs)
Add new Polymesh Compound Object.
Definition Context.cpp:5343
+
std::vector< uint > addSphere(uint Ndivs, const vec3 &center, float radius)
Add a spherical compound object to the Context.
Definition Context.cpp:5590
+
std::vector< uint > addTube(uint Ndivs, const std::vector< vec3 > &nodes, const std::vector< float > &radius)
Add a 3D tube compound object to the Context.
Definition Context.cpp:5874
+
std::vector< uint > addTile(const vec3 &center, const vec2 &size, const SphericalCoord &rotation, const int2 &subdiv)
Add a patch that is subdivided into a regular grid of sub-patches (tiled)
Definition Context.cpp:5753
float randu()
Random number from a uniform distribution between 0 and 1.
Definition global.cpp:223
+
float min(const std::vector< float > &vect)
Minimum value of a vector of floats.
Definition global.cpp:1018
float deg2rad(float deg)
Convert degrees to radians.
Definition global.cpp:576
-
uint addTriangle(const helios::vec3 &vertex0, const helios::vec3 &vertex1, const helios::vec3 &vertex2)
Add new Triangle geometric primitive.
Definition Context.cpp:1323
-
vec3 make_vec3(float x, float y, float z)
Make a vec3 from three floats.
-
R-G-B color vector.
+
float max(const std::vector< float > &vect)
Maximum value of a vector of floats.
Definition global.cpp:1064
+
uint addTriangle(const helios::vec3 &vertex0, const helios::vec3 &vertex1, const helios::vec3 &vertex2)
Add new Triangle geometric primitive.
Definition Context.cpp:1318
+
int2 make_int2(int x, int y)
Make an int2 vector from two ints.
+
vec2 make_vec2(float x, float y)
Make a vec2 from two floats.
+
RGBcolor make_RGBcolor(float r, float g, float b)
Make an RGBcolor vector.
+
vec3 make_vec3(float x, float y, float z)
Make a vec3 from three floats.
+
R-G-B color vector.
Vector of two elements of type 'float'.
-
Vector of three elements of type 'float'.
+
Vector of three elements of type 'float'.
+
float x
First element in vector.
+
float z
Third element in vector.
+
float y
Second element in vector.