BRL-CAD / brlcad

BRL-CAD is a powerful cross-platform open source combinatorial solid modeling system
https://brlcad.org
Other
686 stars 140 forks source link

ignored error condition still results in a call to bu_log #107

Open kennethsdavis opened 8 months ago

kennethsdavis commented 8 months ago

Upon determining the lack of convergence, the rt_poly_findroot function calls bu_log and returns -1 (indicating an error occurred). However, the only user of this function (rt_poly_roots) ignores the error. Should messages be printed to log if they are "not considered" errors?

If the contents of the log were free of non-error messages, then the log would be more helpful to users. Specifically, it would be nice if the default behavior was to only report to the log things that the user could do something about. Generally, having log categories such as SEVERE, ERROR, WARNING, DEVELOPER, etc. and letting API users configure the log would be most useful.

kennethsdavis commented 8 months ago

The message printed is:

rt_poly_findroot: solving for eto didn't converge in 100 iterations, b=1.70928, diff=6361.43
nxZ=-1.30739R+2.65762e-133I, p0=79.7586R+1.97747e-133I

See src/librt/roots.c@168 for the call to bu_log and srv/librt/roots.c@320 for the ignored error condition.

Following is the code to reproduce:

// BRL-CAD/brlcad issue #107
#include <iostream>
#include <list>

#include <brlcad.h>

int main(int argc, char** argv)
{
   const std::string model_path = "cup.g"; // fill in the complete path to the cup.g example model
   const std::string ray_trace_root = "mug.r";

   auto ray_trace_interface = rt_dirbuild(model_path.c_str(), nullptr, 0);
   if (!ray_trace_interface)
   {
      std::cerr << "Error opening model database (\"" << model_path << "\")." << std::endl;
      return EXIT_FAILURE;
   }

   if (rt_gettree(ray_trace_interface, ray_trace_root.c_str()) != 0)
   {
      std::cerr << "Error getting tree named \"" << ray_trace_root << "\"." << std::endl;
      rt_free_rti(ray_trace_interface);
      return EXIT_FAILURE;
   }

   rt_prep(ray_trace_interface);

   const resource default_resource = RT_RESOURCE_INIT_ZERO;
   auto shootray_resource = std::make_shared<resource>(default_resource);
   rt_init_resource(shootray_resource.get(), 1, ray_trace_interface);

   application _application;
   RT_APPLICATION_INIT(&_application);
   _application.a_rt_i = ray_trace_interface;
   _application.a_hit = [](application*, partition*, seg*) { return 1; };
   _application.a_miss = [](application*) { return 0; };
   _application.a_resource = shootray_resource.get();

   VSET(_application.a_ray.r_pt, -1.729022089258255e+02, 1.229739165827910e+02, 6.890996603378248e+01);
   VSET(_application.a_ray.r_dir, 1.636995904838637e+02, -5.290310632309118e+01, -3.152325200202280e+01);

   rt_shootray(&_application);

   rt_clean(ray_trace_interface);
   rt_free_rti(ray_trace_interface);

   return EXIT_SUCCESS;
}