text: /*                 BSplineSurface.cpp
   * BRL-CAD
   *
   * Copyright (c) 1994-2022 United States Government as represented by
   * the U.S. Army Research Laboratory.
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public License
   * version 2.1 as published by the Free Software Foundation.
   *
   * This program is distributed in the hope that it will be useful, but
   * WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
   * License along with this file; see the file named COPYING for more
   * information.
   */
  /** @file step/BSplineSurface.cpp
   *
   * Routines to interface to STEP "BSplineSurface".
   *
   */
  
  #include "STEPWrapper.h"
  #include "Factory.h"
  
  #include "CartesianPoint.h"
  #include "BSplineSurface.h"
  
  #define CLASSNAME "BSplineSurface"
  #define ENTITYNAME "B_Spline_Surface"
  string BSplineSurface::entityname = Factory::RegisterClass(ENTITYNAME, (FactoryMethod)BSplineSurface::Create);
  
  static const char *B_spline_surface_form_string[] = {
      "plane_surf",
      "cylindrical_surf",
      "conical_surf",
      "spherical_surf",
      "toroidal_surf",
      "surf_of_revolution",
      "ruled_surf",
      "generalised_cone",
      "quadric_surf",
      "surf_of_linear_extrusion",
      "unspecified",
      "unset"
  };
  
  BSplineSurface::BSplineSurface()
  {
      step = NULL;
      id = 0;
      control_points_list = NULL;
      u_degree = 0;
      v_degree = 0;
      surface_form = B_spline_surface_form_unset;
      u_closed = LUnset;
      v_closed = LUnset;
      self_intersect = LUnset;
  }
  
  BSplineSurface::BSplineSurface(STEPWrapper *sw, int step_id)
  {
      step = sw;
      id = step_id;
      control_points_list = NULL;
      u_degree = 0;
      v_degree = 0;
      surface_form = B_spline_surface_form_unset;
      u_closed = LUnset;
      v_closed = LUnset;
      self_intersect = LUnset;
  }
  
  BSplineSurface::~BSplineSurface()
  {
      // elements created through factory will be deleted there.
      if (control_points_list) {
  	LIST_OF_LIST_OF_POINTS::iterator i;
  	for (i = control_points_list->begin(); i != control_points_list->end(); ++i) {
  	    LIST_OF_POINTS *points = *i;
  	    points->clear();
  	    delete points;
  	}
  	control_points_list->clear();
  	delete control_points_list;
      }
  }
  
  bool
  BSplineSurface::Load(STEPWrapper *sw, SDAI_Application_instance *sse)
  {
  
      step = sw;
      id = sse->STEPfile_id;
  
      if (!BoundedSurface::Load(step, sse)) {
  	std::cout << CLASSNAME << ":Error loading base class ::BoundedSurface." << std::endl;
  	goto step_error;
      }
  
      // need to do this for local attributes to makes sure we have
      // the actual entity and not a complex/supertype parent
      sse = step->getEntity(sse, ENTITYNAME);
  
      u_degree = step->getIntegerAttribute(sse, "u_degree");
      v_degree = step->getIntegerAttribute(sse, "v_degree");
      if (!u_degree || !v_degree) {
  	/* If we don't have degrees, error */
  	goto step_error;
      }
  
      if (control_points_list == NULL) {
  	control_points_list = step->getListOfListOfPoints(sse, "control_points_list");
  	if (!control_points_list) {
  	    /* If we had an entity but couldn't load it, error */
  	    goto step_error;
  	}
      }
      surface_form = (B_spline_surface_form)step->getEnumAttribute(sse, "surface_form");
      V_MIN(surface_form, B_spline_surface_form_unset);
  
      u_closed = step->getLogicalAttribute(sse, "u_closed");
      v_closed = step->getLogicalAttribute(sse, "v_closed");
      self_intersect = step->getLogicalAttribute(sse, "self_intersect");
  
      sw->entity_status[id] = STEP_LOADED;
      return true;
  step_error:
      sw->entity_status[id] = STEP_LOAD_ERROR;
      return false;
  }
  
  void
  BSplineSurface::Print(int level)
  {
      TAB(level);
      std::cout << CLASSNAME << ":" << name << "(";
      std::cout << "ID:" << STEPid() << ")" << std::endl;
  
      TAB(level);
      std::cout << "Attributes:" << std::endl;
      TAB(level + 1);
      std::cout << "control_points:" << std::endl;
      LIST_OF_LIST_OF_POINTS::iterator i;
      int cnt = 0;
      for (i = control_points_list->begin(); i != control_points_list->end(); ++i) {
  	LIST_OF_POINTS::iterator j;
  	LIST_OF_POINTS *p = *i;
  	TAB(level + 1);
  	std::cout << "line " << cnt++ << ":" << std::endl;
  	for (j = p->begin(); j != p->end(); ++j) {
  	    (*j)->Print(level + 1);
  	}
      }
  
      TAB(level + 1);
      std::cout << "u_degree:" << u_degree << std::endl;
      TAB(level + 1);
      std::cout << "v_degree:" << v_degree << std::endl;
  
      TAB(level + 1);
      std::cout << "u_closed:" << step->getLogicalString((Logical)u_closed) << std::endl;
      TAB(level + 1);
      std::cout << "v_closed:" << step->getLogicalString((Logical)v_closed) << std::endl;
      TAB(level + 1);
      std::cout << "self_intersect:" << step->getLogicalString((Logical)self_intersect) << std::endl;
      TAB(level + 1);
      std::cout << "surface_form:" << B_spline_surface_form_string[surface_form] << std::endl;
  
      TAB(level);
      std::cout << "Inherited Attributes:" << std::endl;
      BoundedSurface::Print(level + 1);
  }
  
  STEPEntity *
  BSplineSurface::GetInstance(STEPWrapper *sw, int id)
  {
      return new BSplineSurface(sw, id);
  }
  
  STEPEntity *
  BSplineSurface::Create(STEPWrapper *sw, SDAI_Application_instance *sse)
  {
      return STEPEntity::CreateEntity(sw, sse, GetInstance, CLASSNAME);
  }
  
  string
  BSplineSurface::Form()
  {
      return B_spline_surface_form_string[surface_form];
  }
  
  // Local Variables:
  // tab-width: 8
  // mode: C++
  // c-basic-offset: 4
  // indent-tabs-mode: t
  // c-file-style: "stroustrup"
  // End:
  // ex: shiftwidth=4 tabstop=8
  