From 5902446fa953279771e20145f24101c393e3f20a Mon Sep 17 00:00:00 2001 From: "Onur R. Bingol" Date: Tue, 12 Dec 2017 00:23:58 -0600 Subject: [PATCH 01/18] Change local install target name --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b710582..463fe07 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -270,7 +270,7 @@ set_property( # # Create a custom install target for calling inside Jetbrains CLion # -add_custom_target( install_${PROJECT_NAME} +add_custom_target( install_project $(CMAKE_COMMAND) --build . --target install COMMENT "Installing ${PROJECT_NAME}..." ) From 3d02e91b689e1955452803a8afc5ae5adbe10ce8 Mon Sep 17 00:00:00 2001 From: "Onur R. Bingol" Date: Tue, 12 Dec 2017 02:45:40 -0600 Subject: [PATCH 02/18] Updated comments in CMakeLists.txt and removed header gen module --- CMakeLists.txt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 463fe07..f604dd4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ if( MSVC ) endif( MSVC ) # Required for GenerateExportHeader module -include( GenerateExportHeader ) +#include( GenerateExportHeader ) # Activate GCC C++11 support for CMake versions before v3.1 if( CMAKE_VERSION VERSION_LESS 3.1 ) @@ -135,7 +135,7 @@ set( ACIS_SOURCES_Modeler # Generate Python module add_library( Modeler SHARED ${ACIS_SOURCES_Modeler} ) -# Set link targets. Note that Modeler has dependencies towards most helper modules. +# Set link targets target_link_libraries( Modeler ${ACIS_LINK_LIBRARIES} ${PYTHON_LIBRARIES} ) # Add the build location to the include directories @@ -236,6 +236,7 @@ add_custom_target( uninstall # # Generate a "complete install" target +# This target installs the module to Python's site-packages directory by creating a .pth file # # Run INSTALL target and then, generate .pth file in the site-packages directory @@ -247,6 +248,7 @@ add_custom_target( install_module # # Generate a "complete uninstall" target +# This target uninstalls the module from Python's site-packages directory by deleting the .pth file # # Run UNINSTALL target and remove .pth file generated by the "install_module" target @@ -268,7 +270,8 @@ set_property( ) # -# Create a custom install target for calling inside Jetbrains CLion +# Create a custom install target for calling from IDEs +# This target installs the module and example scripts to the user-specified directory # add_custom_target( install_project $(CMAKE_COMMAND) --build . --target install From 4317b4dafe41a4fa4540190e639d6e8b32cf0242 Mon Sep 17 00:00:00 2001 From: "Onur R. Bingol" Date: Tue, 12 Dec 2017 03:09:07 -0600 Subject: [PATCH 03/18] Moved functions not starting with "api_" to acis_api2.h/.cpp --- CMakeLists.txt | 2 ++ src/acis_api.cpp | 75 -------------------------------------------- src/acis_api.h | 3 -- src/acis_api2.cpp | 77 ++++++++++++++++++++++++++++++++++++++++++++++ src/acis_api2.h | 37 ++++++++++++++++++++++ src/acis_modeler.h | 1 + 6 files changed, 117 insertions(+), 78 deletions(-) create mode 100644 src/acis_api2.cpp create mode 100644 src/acis_api2.h diff --git a/CMakeLists.txt b/CMakeLists.txt index f604dd4..3a08264 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -120,6 +120,8 @@ set( ACIS_SOURCES_Modeler src/acis_modeler.h src/acis_api.cpp src/acis_api.h + src/acis_api2.cpp + src/acis_api2.h src/acis_classes.cpp src/acis_classes.h src/acis_entity.cpp diff --git a/src/acis_api.cpp b/src/acis_api.cpp index 98810d1..2f98119 100644 --- a/src/acis_api.cpp +++ b/src/acis_api.cpp @@ -68,45 +68,6 @@ a3dp_api_stop_modeller(PyObject *self) Py_RETURN_NONE; } -PyObject * -a3dp_is_modeler_started(PyObject *self) -{ - // Initialize variables - logical check_modeler; - - // Call ACIS API - check_modeler = is_modeler_started(); - - // Return Python value - if (check_modeler) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; -} - -PyObject * -a3dp_spa_unlock_products(PyObject *self, PyObject *arg) -{ - // Check if the input is a string - if (!PyUnicode_Check(arg)) - { - PyErr_SetString(PyExc_ValueError, "Expecting a string"); - return NULL; - } - - // Convert PyObject to C-style string - const char *unlock_str = PyUnicode_AsUTF8(arg); - - // Call ACIS Licensing API - spa_unlock_result out = spa_unlock_products(unlock_str); - - // If license is good, then return True. Otherwise, return the licensing error message - if (SPA_UNLOCK_PASS == out.get_state()) - Py_RETURN_TRUE; - else - return PyUnicode_FromString(out.get_message_text()); -} - PyObject * a3dp_api_set_dbl_option(PyObject *self, PyObject *args, PyObject *kwargs) { @@ -1323,42 +1284,6 @@ a3dp_api_sweep_with_options(PyObject *self, PyObject *args, PyObject *kwargs) } } -PyObject * -a3dp_get_owner_transf(PyObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *input_ent = NULL; - - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "entity", - NULL - }; - - // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &input_ent)) - return NULL; - - if (!_PyCheck_ENTITY(input_ent)) - { - PyErr_SetString(PyExc_TypeError, "Expecting ENTITY object"); - return NULL; - } - - // Get the ACIS object from the user input - ENTITY *&_ent = ((a3dp_ENTITY *) input_ent)->_acis_obj; - - // Execute ACIS function - SPAtransf retval = get_owner_transf(_ent); - - // Generate a new SPAtransf python object and set its ACIS object value - PyObject *retobj = _PyNew_SPAtransf(); - *((a3dp_SPAtransf *) retobj)->_acis_obj = retval; - - // Return SPAtransf python object - return retobj; -} - PyObject * a3dp_api_get_faces(PyObject *self, PyObject *args, PyObject *kwargs) { diff --git a/src/acis_api.h b/src/acis_api.h index 0be2dbe..d7e966e 100644 --- a/src/acis_api.h +++ b/src/acis_api.h @@ -28,8 +28,6 @@ extern "C" { PyObject *a3dp_api_start_modeller(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_stop_modeller(PyObject *self); -PyObject *a3dp_is_modeler_started(PyObject *self); -PyObject *a3dp_spa_unlock_products(PyObject *self, PyObject *arg); PyObject *a3dp_api_set_dbl_option(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_set_int_option(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_set_str_option(PyObject *self, PyObject *args, PyObject *kwargs); @@ -54,7 +52,6 @@ PyObject *a3dp_api_get_file_info(PyObject *self, PyObject *args, PyObject *kwarg PyObject *a3dp_api_save_version(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_make_sweep_path(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_sweep_with_options(PyObject *self, PyObject *args, PyObject *kwargs); -PyObject *a3dp_get_owner_transf(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_get_faces(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_get_edges(PyObject *self, PyObject *args, PyObject *kwargs); diff --git a/src/acis_api2.cpp b/src/acis_api2.cpp new file mode 100644 index 0000000..a5ef5e1 --- /dev/null +++ b/src/acis_api2.cpp @@ -0,0 +1,77 @@ +#include "acis_api2.h" + + +PyObject * +a3dp_is_modeler_started(PyObject *self) +{ + // Initialize variables + logical check_modeler; + + // Call ACIS API + check_modeler = is_modeler_started(); + + // Return Python value + if (check_modeler) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; +} + +PyObject * +a3dp_spa_unlock_products(PyObject *self, PyObject *arg) +{ + // Check if the input is a string + if (!PyUnicode_Check(arg)) + { + PyErr_SetString(PyExc_ValueError, "Expecting a string"); + return NULL; + } + + // Convert PyObject to C-style string + const char *unlock_str = PyUnicode_AsUTF8(arg); + + // Call ACIS Licensing API + spa_unlock_result out = spa_unlock_products(unlock_str); + + // If license is good, then return True. Otherwise, return the licensing error message + if (SPA_UNLOCK_PASS == out.get_state()) + Py_RETURN_TRUE; + else + return PyUnicode_FromString(out.get_message_text()); +} + +PyObject * +a3dp_get_owner_transf(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *input_ent = NULL; + + // List of keyword arguments that this function can take + char *kwlist[] = + { + (char *) "entity", + NULL + }; + + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &input_ent)) + return NULL; + + if (!_PyCheck_ENTITY(input_ent)) + { + PyErr_SetString(PyExc_TypeError, "Expecting ENTITY object"); + return NULL; + } + + // Get the ACIS object from the user input + ENTITY *&_ent = ((a3dp_ENTITY *) input_ent)->_acis_obj; + + // Execute ACIS function + SPAtransf retval = get_owner_transf(_ent); + + // Generate a new SPAtransf python object and set its ACIS object value + PyObject *retobj = _PyNew_SPAtransf(); + *((a3dp_SPAtransf *) retobj)->_acis_obj = retval; + + // Return SPAtransf python object + return retobj; +} diff --git a/src/acis_api2.h b/src/acis_api2.h new file mode 100644 index 0000000..fb816fb --- /dev/null +++ b/src/acis_api2.h @@ -0,0 +1,37 @@ +/** + * + * Python 3 wrapper module for Spatial Corporation's 3D ACIS Modeler + * + * ACIS and SAT are registered trademarks of Spatial Corporation. + * + * The Python module is developed by Onur R. Bingol and released under MIT license. + * Please see the LICENSE file for details. + * + */ + +#ifndef A3DPY_API2_H +#define A3DPY_API2_H + +#include +#include + +#include "acis_includes.h" +#include "acis_entity.h" +#include "acis_operators.h" +#include "acis_classes.h" +#include "acis_enums.h" +#include "utilities.h" + +#ifdef __cplusplus +extern "C" { +#endif + +PyObject *a3dp_is_modeler_started(PyObject *self); +PyObject *a3dp_spa_unlock_products(PyObject *self, PyObject *arg); +PyObject *a3dp_get_owner_transf(PyObject *self, PyObject *args, PyObject *kwargs); + +#ifdef __cplusplus +} +#endif + +#endif // !A3DPY_API2_H diff --git a/src/acis_modeler.h b/src/acis_modeler.h index a7028bf..fd47556 100644 --- a/src/acis_modeler.h +++ b/src/acis_modeler.h @@ -16,5 +16,6 @@ #include #include "acis_api.h" +#include "acis_api2.h" #endif // !A3DPY_MODELER_H From 2adf5eca5cf92945e8f6942a65a8de67aaf986d4 Mon Sep 17 00:00:00 2001 From: "Onur R. Bingol" Date: Thu, 14 Dec 2017 23:48:50 -0600 Subject: [PATCH 04/18] Add BoolOptions class --- src/acis_classes.cpp | 93 ++++++++++++++++++++++++++++++++++++++++++++ src/acis_classes.h | 11 ++++++ src/acis_includes.h | 1 + src/acis_modeler.cpp | 8 +++- 4 files changed, 112 insertions(+), 1 deletion(-) diff --git a/src/acis_classes.cpp b/src/acis_classes.cpp index b7474f4..7a4d717 100644 --- a/src/acis_classes.cpp +++ b/src/acis_classes.cpp @@ -2283,3 +2283,96 @@ _PyCheck_sweep_options(PyObject *ob) { return PyObject_TypeCheck(ob, &a3dp_type_sweep_options); } + + +/** + * BoolOptions + */ + +static void +a3dp_BoolOptions_dealloc(a3dp_BoolOptions *self) +{ + // Delete ACIS object + ACIS_DELETE self->_acis_obj; + + Py_TYPE(self)->tp_free((PyObject *) self); +} + +static PyObject * +a3dp_BoolOptions_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + a3dp_BoolOptions *self; + + self = (a3dp_BoolOptions *) type->tp_alloc(type, 0); + if (self != NULL) + { + // Just getting rid of the dangling pointer + self->_acis_obj = NULL; + } + + return (PyObject *) self; +} + +static int +a3dp_BoolOptions_init(a3dp_BoolOptions *self, PyObject *args, PyObject *kwargs) +{ + // Initialize the ACIS object + self->_acis_obj = ACIS_NEW BoolOptions(); + + return 0; +} + +PyTypeObject + a3dp_type_BoolOptions = + { + PyVarObject_HEAD_INIT(NULL, 0) + "ACIS.BoolOptions", /* tp_name */ + sizeof(a3dp_BoolOptions), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor) a3dp_BoolOptions_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + "BoolOptions class holds information and options for a Boolean operation", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc) a3dp_BoolOptions_init, /* tp_init */ + 0, /* tp_alloc */ + a3dp_BoolOptions_new, /* tp_new */ + }; + +PyObject * +_PyNew_BoolOptions() +{ + return PyObject_CallObject((PyObject *) &a3dp_type_BoolOptions, NULL); +} + +bool +_PyCheck_BoolOptions(PyObject *ob) +{ + return PyObject_TypeCheck(ob, &a3dp_type_BoolOptions); +} diff --git a/src/acis_classes.h b/src/acis_classes.h index a40ca33..4a233c6 100644 --- a/src/acis_classes.h +++ b/src/acis_classes.h @@ -89,6 +89,13 @@ typedef struct make_sweep_path_options *_acis_obj; } a3dp_make_sweep_path_options; +// Define BoolOptions +typedef struct +{ + PyObject_HEAD + BoolOptions *_acis_obj; +} a3dp_BoolOptions; + extern PyTypeObject a3dp_type_SPAposition; extern PyTypeObject a3dp_type_SPAvector; extern PyTypeObject a3dp_type_SPAunit_vector; @@ -99,6 +106,7 @@ extern PyTypeObject a3dp_type_SPApar_vec; extern PyTypeObject a3dp_type_FileInfo; extern PyTypeObject a3dp_type_sweep_options; extern PyTypeObject a3dp_type_make_sweep_path_options; +extern PyTypeObject a3dp_type_BoolOptions; #ifdef __cplusplus extern "C" { @@ -133,6 +141,9 @@ bool _PyCheck_sweep_options(PyObject *ob); PyObject *_PyNew_make_sweep_path_options(); bool _PyCheck_make_sweep_path_options(PyObject *ob); +PyObject *_PyNew_BoolOptions(); +bool _PyCheck_BoolOptions(PyObject *ob); + #ifdef __cplusplus } #endif diff --git a/src/acis_includes.h b/src/acis_includes.h index f986116..a86d2b9 100644 --- a/src/acis_includes.h +++ b/src/acis_includes.h @@ -31,6 +31,7 @@ #include #include #include +#include #endif // !A3DPY_INCLUDES_H diff --git a/src/acis_modeler.cpp b/src/acis_modeler.cpp index 8fa0fe5..f1e57cf 100644 --- a/src/acis_modeler.cpp +++ b/src/acis_modeler.cpp @@ -303,11 +303,17 @@ PyInit_Modeler(void) Py_INCREF(&a3dp_type_surface); PyModule_AddObject(m, "surface", (PyObject *) &a3dp_type_surface); - // Initialize ACIS ENTITY_LIST class as a Python type + // ENTITY_LIST if (PyType_Ready(&a3dp_type_ENTITY_LIST) < 0) return NULL; Py_INCREF(&a3dp_type_ENTITY_LIST); PyModule_AddObject(m, "ENTITY_LIST", (PyObject *) &a3dp_type_ENTITY_LIST); + // BoolOptions + if (PyType_Ready(&a3dp_type_BoolOptions) < 0) + return NULL; + Py_INCREF(&a3dp_type_BoolOptions); + PyModule_AddObject(m, "BoolOptions", (PyObject *) &a3dp_type_BoolOptions); + return m; } From 42c85d0f6c5f21256cc703d5cde4ba14fa36d434 Mon Sep 17 00:00:00 2001 From: "Onur R. Bingol" Date: Sun, 17 Dec 2017 15:48:06 -0600 Subject: [PATCH 05/18] Update api_boolean_chop_body API call --- src/acis_api.cpp | 92 +++++++++++++++++++++++++++++++++++++++++++- src/acis_modeler.cpp | 1 - 2 files changed, 90 insertions(+), 3 deletions(-) diff --git a/src/acis_api.cpp b/src/acis_api.cpp index 2f98119..3106e9e 100644 --- a/src/acis_api.cpp +++ b/src/acis_api.cpp @@ -867,8 +867,96 @@ a3dp_api_imprint(PyObject *self, PyObject *args, PyObject *kwargs) PyObject * a3dp_api_boolean_chop_body(PyObject *self, PyObject *args, PyObject *kwargs) { - /* TO-DO: Implement api_boolean_chop_body */ + PyObject *input_tool = NULL, *input_blank = NULL; + PyObject *input_outside = NULL, *input_leftovers = NULL, *input_result_body = NULL; + PyObject *input_boolopts = NULL; + int input_nonreg, input_ndbool_keep; + + // List of keyword arguments that this function can take + char *kwlist[] = + { + (char *) "tool", + (char *) "blank", + (char *) "nonreg", + (char *) "outside", + (char *) "leftovers", + (char *) "result_body", + (char *) "ndbool_keep", + (char *) "boolopts", + NULL + }; + + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOiOOiO|O", kwlist, + &input_tool, &input_blank, &input_nonreg, &input_outside, &input_leftovers, &input_ndbool_keep, + &input_result_body, &input_boolopts)) + return NULL; + + // Type checks + if (!_PyCheck_BODY(input_tool)) + { + PyErr_SetString(PyExc_TypeError, "Tool must be a BODY object"); return NULL; + } + + if (!_PyCheck_BODY(input_blank)) + { + PyErr_SetString(PyExc_TypeError, "Blank must be a BODY object"); + return NULL; + } + + if (!_PyCheck_BODY(input_outside)) + { + PyErr_SetString(PyExc_TypeError, "Outisde must be a BODY object"); + return NULL; + } + + if (!_PyCheck_BODY(input_leftovers)) + { + PyErr_SetString(PyExc_TypeError, "Leftovers must be a BODY object"); + return NULL; + } + + if (!_PyCheck_BODY(input_result_body)) + { + PyErr_SetString(PyExc_TypeError, "Result body must be a BODY object"); + return NULL; + } + + API_BEGIN + + // Convert PyObject to ACIS objects + BODY *&_tool = (BODY *&) ((a3dp_BODY *) input_tool)->base_obj._acis_obj; + BODY *&_blank = (BODY *&) ((a3dp_BODY *) input_blank)->base_obj._acis_obj; + BODY *&_outside = (BODY *&) ((a3dp_BODY *) input_outside)->base_obj._acis_obj; + BODY *&_leftovers = (BODY *&) ((a3dp_BODY *) input_leftovers)->base_obj._acis_obj; + BODY *&_result_body = (BODY *&) ((a3dp_BODY *) input_result_body)->base_obj._acis_obj; + NDBOOL_KEEP _ndbool_keep = NDBOOL_KEEP(input_ndbool_keep); + + if (input_boolopts != NULL) + { + if (!_PyCheck_NDBOOL_KEEP(input_boolopts)) + { + PyErr_SetString(PyExc_TypeError, "boolopts variable must be a BoolOptions object"); + return NULL; + } + + BoolOptions *&_boolopts = (BoolOptions *&) ((a3dp_BoolOptions *) input_boolopts)->_acis_obj; + + result = api_boolean_chop_body(_tool, _blank, input_nonreg, _outside, _leftovers, _ndbool_keep, _result_body, _boolopts); + } + else + { + result = api_boolean_chop_body(_tool, _blank, input_nonreg, _outside, _leftovers, _ndbool_keep, _result_body); + } + + API_END + + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; } PyObject * @@ -924,7 +1012,7 @@ a3dp_api_save_entity_list(PyObject *self, PyObject *args, PyObject *kwargs) API_NOP_END // Don't forget to close the file handle - fclose(_file_handle); + fclose(_file_handle); // Check outcome if (!check_outcome(result)) diff --git a/src/acis_modeler.cpp b/src/acis_modeler.cpp index f1e57cf..5ab5d2e 100644 --- a/src/acis_modeler.cpp +++ b/src/acis_modeler.cpp @@ -126,7 +126,6 @@ PyInit_Modeler(void) if (PyType_Ready(&a3dp_type_FileInfo) < 0) return NULL; - Py_INCREF(&a3dp_type_FileInfo); PyModule_AddObject(m, "FileInfo", (PyObject *) &a3dp_type_FileInfo); From edb2d91b676831cb93dd57d56ef7ac9d81fa2302 Mon Sep 17 00:00:00 2001 From: "Onur R. Bingol" Date: Sun, 17 Dec 2017 15:55:55 -0600 Subject: [PATCH 06/18] Convert int value to logical type --- src/acis_api.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/acis_api.cpp b/src/acis_api.cpp index 3106e9e..24a251e 100644 --- a/src/acis_api.cpp +++ b/src/acis_api.cpp @@ -932,6 +932,7 @@ a3dp_api_boolean_chop_body(PyObject *self, PyObject *args, PyObject *kwargs) BODY *&_leftovers = (BODY *&) ((a3dp_BODY *) input_leftovers)->base_obj._acis_obj; BODY *&_result_body = (BODY *&) ((a3dp_BODY *) input_result_body)->base_obj._acis_obj; NDBOOL_KEEP _ndbool_keep = NDBOOL_KEEP(input_ndbool_keep); + logical _nonreg = (input_nonreg == 0) ? FALSE : TRUE; if (input_boolopts != NULL) { @@ -943,11 +944,11 @@ a3dp_api_boolean_chop_body(PyObject *self, PyObject *args, PyObject *kwargs) BoolOptions *&_boolopts = (BoolOptions *&) ((a3dp_BoolOptions *) input_boolopts)->_acis_obj; - result = api_boolean_chop_body(_tool, _blank, input_nonreg, _outside, _leftovers, _ndbool_keep, _result_body, _boolopts); + result = api_boolean_chop_body(_tool, _blank, _nonreg, _outside, _leftovers, _ndbool_keep, _result_body, _boolopts); } else { - result = api_boolean_chop_body(_tool, _blank, input_nonreg, _outside, _leftovers, _ndbool_keep, _result_body); + result = api_boolean_chop_body(_tool, _blank, _nonreg, _outside, _leftovers, _ndbool_keep, _result_body); } API_END From 3b369ec8774d3acd1f06eb74f0449efbcf12b466 Mon Sep 17 00:00:00 2001 From: "Onur R. Bingol" Date: Sun, 17 Dec 2017 15:56:15 -0600 Subject: [PATCH 07/18] Add api_logging function --- src/acis_api.cpp | 31 +++++++++++++++++++++++++++++++ src/acis_api.h | 1 + src/acis_modeler.cpp | 3 ++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/acis_api.cpp b/src/acis_api.cpp index 24a251e..2bb312c 100644 --- a/src/acis_api.cpp +++ b/src/acis_api.cpp @@ -1480,3 +1480,34 @@ a3dp_api_get_edges(PyObject *self, PyObject *args, PyObject *kwargs) } } + +PyObject * +a3dp_api_logging(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int input_on_off; + + // List of keyword arguments that this function can take + char *kwlist[] = + { + (char *) "on_off", + NULL + }; + + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &input_on_off)) + return NULL; + + logical _on_off = (input_on_off == 0) ? FALSE : TRUE; + + API_BEGIN + + result = api_logging(_on_off); + + API_END + + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; +} diff --git a/src/acis_api.h b/src/acis_api.h index d7e966e..af9476f 100644 --- a/src/acis_api.h +++ b/src/acis_api.h @@ -54,6 +54,7 @@ PyObject *a3dp_api_make_sweep_path(PyObject *self, PyObject *args, PyObject *kwa PyObject *a3dp_api_sweep_with_options(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_get_faces(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_get_edges(PyObject *self, PyObject *args, PyObject *kwargs); +PyObject *a3dp_api_logging(PyObject *self, PyObject *args, PyObject *kwargs); #ifdef __cplusplus } diff --git a/src/acis_modeler.cpp b/src/acis_modeler.cpp index 5ab5d2e..939408e 100644 --- a/src/acis_modeler.cpp +++ b/src/acis_modeler.cpp @@ -59,7 +59,8 @@ static PyMethodDef { "get_resmch", (PyCFunction) a3dp_get_resmch, METH_NOARGS, "Gets the resmch resolution" }, { "get_resnor", (PyCFunction) a3dp_get_resnor, METH_NOARGS, "Gets the SPAresnor resolution" }, { "distance_to_point", (PyCFunction) a3dp_distance_to_point, METH_VARARGS | METH_KEYWORDS, "Determines the distance between two points" }, - { "distance_to_point_squared", (PyCFunction) a3dp_distance_to_point_squared, METH_VARARGS | METH_KEYWORDS, "\tComputes the squared distance between two positions" }, + { "distance_to_point_squared", (PyCFunction) a3dp_distance_to_point_squared, METH_VARARGS | METH_KEYWORDS, "Computes the squared distance between two positions" }, + { "api_logging", (PyCFunction) a3dp_api_logging, METH_VARARGS | METH_KEYWORDS, "Sets logging of entity modifications on or off for roll back purposes" }, { NULL, NULL, 0, NULL } }; From a3007a78cffe794705ee5955690979bb21cc1958 Mon Sep 17 00:00:00 2001 From: "Onur R. Bingol" Date: Sun, 17 Dec 2017 16:23:19 -0600 Subject: [PATCH 08/18] Add api_body_to_1d, api_body_to_2d and api_get_entity_id functions --- src/acis_api.cpp | 129 +++++++++++++++++++++++++++++++++++++++++++ src/acis_api.h | 3 + src/acis_modeler.cpp | 3 + 3 files changed, 135 insertions(+) diff --git a/src/acis_api.cpp b/src/acis_api.cpp index 2bb312c..9697ea9 100644 --- a/src/acis_api.cpp +++ b/src/acis_api.cpp @@ -1511,3 +1511,132 @@ a3dp_api_logging(PyObject *self, PyObject *args, PyObject *kwargs) else Py_RETURN_NONE; } + +PyObject * +a3dp_api_body_to_1d(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *input_body = NULL, *input_ref_faces = NULL; + int input_fix_normals; + + // List of keyword arguments that this function can take + char *kwlist[] = + { + (char *) "body", + (char *) "fix_normals", + (char *) "ref_faces", + NULL + }; + + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|O", kwlist, &input_body, &input_fix_normals, &input_ref_faces)) + return NULL; + + if (!_PyCheck_BODY(input_body)) + { + PyErr_SetString(PyExc_TypeError, "Input body must be a BODY object"); + return NULL; + } + + BODY *&_body = (BODY *&) ((a3dp_BODY *) input_body)->base_obj._acis_obj; + logical _fix_normals = (input_fix_normals == 0) ? FALSE : TRUE; + ENTITY_LIST _ref_faces = *(ENTITY_LIST *) NULL_REF; + + if (input_ref_faces != NULL) + { + if (!_PyCheck_BODY(input_body)) + { + PyErr_SetString(PyExc_TypeError, "Input body must be a BODY object"); + return NULL; + } + + _ref_faces = *((a3dp_ENTITY_LIST *) input_ref_faces)->_acis_obj; + } + + API_BEGIN + + result = api_body_to_1d(_body, _fix_normals, _ref_faces); + + API_END + + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; +} + +PyObject * +a3dp_api_body_to_2d(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *input_body = NULL; + + // List of keyword arguments that this function can take + char *kwlist[] = + { + (char *) "body", + NULL + }; + + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &input_body)) + return NULL; + + if (!_PyCheck_BODY(input_body)) + { + PyErr_SetString(PyExc_TypeError, "Input body must be a BODY object"); + return NULL; + } + + BODY *&_body = (BODY *&) ((a3dp_BODY *) input_body)->base_obj._acis_obj; + + API_BEGIN + + result = api_body_to_2d(_body); + + API_END + + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; +} + +PyObject * +a3dp_api_get_entity_id(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *input_ent = NULL; + + // List of keyword arguments that this function can take + char *kwlist[] = + { + (char *) "ent", + NULL + }; + + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &input_ent)) + return NULL; + + if (!_PyCheck_ENTITY(input_ent)) + { + PyErr_SetString(PyExc_TypeError, "Expecting an ENTITY object"); + return NULL; + } + + ENTITY *_ent = ((a3dp_ENTITY *) input_ent)->_acis_obj; + // tag_id_type is a typedef'd int + tag_id_type _id; + + API_BEGIN + + result = api_get_entity_id(_ent, _id); + + API_END + + // Check outcome + if (!check_outcome(result)) + return NULL; + else + return PyLong_FromLong((long) _id); +} diff --git a/src/acis_api.h b/src/acis_api.h index af9476f..de046e8 100644 --- a/src/acis_api.h +++ b/src/acis_api.h @@ -55,6 +55,9 @@ PyObject *a3dp_api_sweep_with_options(PyObject *self, PyObject *args, PyObject * PyObject *a3dp_api_get_faces(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_get_edges(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_logging(PyObject *self, PyObject *args, PyObject *kwargs); +PyObject *a3dp_api_body_to_1d(PyObject *self, PyObject *args, PyObject *kwargs); +PyObject *a3dp_api_body_to_2d(PyObject *self, PyObject *args, PyObject *kwargs); +PyObject *a3dp_api_get_entity_id(PyObject *self, PyObject *args, PyObject *kwargs); #ifdef __cplusplus } diff --git a/src/acis_modeler.cpp b/src/acis_modeler.cpp index 939408e..c90accd 100644 --- a/src/acis_modeler.cpp +++ b/src/acis_modeler.cpp @@ -61,6 +61,9 @@ static PyMethodDef { "distance_to_point", (PyCFunction) a3dp_distance_to_point, METH_VARARGS | METH_KEYWORDS, "Determines the distance between two points" }, { "distance_to_point_squared", (PyCFunction) a3dp_distance_to_point_squared, METH_VARARGS | METH_KEYWORDS, "Computes the squared distance between two positions" }, { "api_logging", (PyCFunction) a3dp_api_logging, METH_VARARGS | METH_KEYWORDS, "Sets logging of entity modifications on or off for roll back purposes" }, + { "api_body_to_1d", (PyCFunction) a3dp_api_body_to_1d, METH_VARARGS | METH_KEYWORDS, "Converts a double-sided body to a single-sided body" }, + { "api_body_to_2d", (PyCFunction) a3dp_api_body_to_2d, METH_VARARGS | METH_KEYWORDS, "Converts single-sided faces to double-sided faces" }, + { "api_get_entity_id", (PyCFunction) a3dp_api_get_entity_id, METH_VARARGS | METH_KEYWORDS, "Returns a unique integer identifier for a given ENTITY" }, { NULL, NULL, 0, NULL } }; From 6e13f972261e2cfb8c1c2e60ede41e7554512aea Mon Sep 17 00:00:00 2001 From: "Onur R. Bingol" Date: Sun, 17 Dec 2017 21:29:32 -0600 Subject: [PATCH 09/18] Add api_restore_entity_list wrapper --- src/acis_api.cpp | 62 ++++++++++++++++++++++++++++++++++++++++++++ src/acis_api.h | 1 + src/acis_modeler.cpp | 1 + 3 files changed, 64 insertions(+) diff --git a/src/acis_api.cpp b/src/acis_api.cpp index 9697ea9..1d5db09 100644 --- a/src/acis_api.cpp +++ b/src/acis_api.cpp @@ -1022,6 +1022,68 @@ a3dp_api_save_entity_list(PyObject *self, PyObject *args, PyObject *kwargs) Py_RETURN_NONE; } +PyObject * +a3dp_api_restore_entity_list(PyObject *self, PyObject *args, PyObject *kwargs) +{ + // According to the documentation, Python 3 doesn't do good with FILE* objects, so we take "file name" as an input + const char *input_filename = NULL; + int input_savemode; + PyObject *input_entitylist = NULL; + + // List of keyword arguments that this function can take + char *kwlist[] = + { + (char *) "file_name", + (char *) "text_mode", + (char *) "entities", + NULL + }; + + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO", kwlist, &input_filename, &input_savemode, &input_entitylist)) + return NULL; + + // Check if the input is an ENTITY_LIST + if (!_PyCheck_ENTITY_LIST(input_entitylist)) + { + PyErr_SetString(PyExc_TypeError, "Expecting ENTITY_LIST object"); + return NULL; + } + + // Using the file name input as a string, create a file handle + FILE *_file_handle = fopen(input_filename, "r"); + + // Check if the file has been opened correctly + if (_file_handle == NULL) + { + PyErr_SetString(PyExc_IOError, "Cannot open file for writing!"); + return NULL; + } + + // Set file writing mode + logical _text_mode = (input_savemode == 0) ? FALSE : TRUE; + + API_NOP_BEGIN + + // Convert PyObject to ENTITY_LIST + ENTITY_LIST *_save_list = ((a3dp_ENTITY_LIST *) input_entitylist)->_acis_obj; + + + // Call ACIS API and check outcome + result = api_restore_entity_list(_file_handle, _text_mode, *_save_list); + + API_NOP_END + + // Don't forget to close the file handle + fclose(_file_handle); + + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; +} + PyObject * a3dp_api_set_file_info(PyObject *self, PyObject *args, PyObject *kwargs) { diff --git a/src/acis_api.h b/src/acis_api.h index de046e8..74eea6a 100644 --- a/src/acis_api.h +++ b/src/acis_api.h @@ -47,6 +47,7 @@ PyObject *a3dp_api_subtract(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_imprint(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_boolean_chop_body(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_save_entity_list(PyObject *self, PyObject *args, PyObject *kwargs); +PyObject *a3dp_api_restore_entity_list(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_set_file_info(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_get_file_info(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_save_version(PyObject *self, PyObject *args, PyObject *kwargs); diff --git a/src/acis_modeler.cpp b/src/acis_modeler.cpp index c90accd..ddee8e4 100644 --- a/src/acis_modeler.cpp +++ b/src/acis_modeler.cpp @@ -14,6 +14,7 @@ static PyMethodDef { "api_start_modeler", (PyCFunction) a3dp_api_start_modeller, METH_VARARGS | METH_KEYWORDS, "Alternative way to call api_start_modeller()" }, { "api_stop_modeler", (PyCFunction) a3dp_api_stop_modeller, METH_NOARGS, "Alternative way to call api_stop_modeller()" }, { "api_save_entity_list", (PyCFunction) a3dp_api_save_entity_list, METH_VARARGS | METH_KEYWORDS, "Writes entities to a file in text or binary format" }, + { "api_restore_entity_list", (PyCFunction) a3dp_api_restore_entity_list, METH_VARARGS | METH_KEYWORDS, "Restores entities from file in text or binary format" }, { "api_set_file_info", (PyCFunction) a3dp_api_set_file_info, METH_VARARGS | METH_KEYWORDS, "Sets required header info to be written to ACIS save files" }, { "api_get_file_info", (PyCFunction) a3dp_api_get_file_info, METH_O | METH_KEYWORDS, "Gets header info from the last restored file" }, { "api_save_version", (PyCFunction) a3dp_api_save_version, METH_VARARGS | METH_KEYWORDS, "Sets the save file format" }, From 1e2c535e0d32e021c847e89b620e9a8b7a483fdf Mon Sep 17 00:00:00 2001 From: "Onur R. Bingol" Date: Sun, 17 Dec 2017 21:30:23 -0600 Subject: [PATCH 10/18] Update api_subtract wrapper with BoolOptions --- src/acis_api.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/acis_api.cpp b/src/acis_api.cpp index 1d5db09..a5540c6 100644 --- a/src/acis_api.cpp +++ b/src/acis_api.cpp @@ -755,18 +755,19 @@ a3dp_api_intersect(PyObject *self, PyObject *args, PyObject *kwargs) PyObject * a3dp_api_subtract(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject *input_tool = NULL, *input_blank = NULL; + PyObject *input_tool = NULL, *input_blank = NULL, *input_boolopts = NULL; // List of keyword arguments that this function can take char *kwlist[] = { (char *) "tool", (char *) "blank", + (char *) "boolopts", NULL }; // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &input_tool, &input_blank)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O", kwlist, &input_tool, &input_blank, &input_boolopts)) return NULL; // Type checks for ACIS objects @@ -782,14 +783,29 @@ a3dp_api_subtract(PyObject *self, PyObject *args, PyObject *kwargs) return NULL; } + if (input_boolopts != NULL) + if (!_PyCheck_BoolOptions(input_boolopts)) + { + PyErr_SetString(PyExc_TypeError, "boolopts must be a BoolOptions object"); + return NULL; + } + API_BEGIN // Convert PyObject to ACIS objects BODY *&_tool = (BODY *&) ((a3dp_BODY *) input_tool)->base_obj._acis_obj; BODY *&_blank = (BODY *&) ((a3dp_BODY *) input_blank)->base_obj._acis_obj; - // Call ACIS API - result = api_subtract(_tool, _blank); + if (input_boolopts) + { + BoolOptions *_boolopts = ((a3dp_BoolOptions *) input_boolopts)->_acis_obj; + result = api_subtract(_tool, _blank, _boolopts); + } + else + { + result = api_subtract(_tool, _blank); + } + API_END From d112fa47e048f224b222fc23ab992032d4ea9215 Mon Sep 17 00:00:00 2001 From: "Onur R. Bingol" Date: Sun, 17 Dec 2017 21:38:53 -0600 Subject: [PATCH 11/18] Automatic code reformatting in IDE --- src/acis_api.cpp | 1994 +++++++++++++++++++++++----------------------- 1 file changed, 997 insertions(+), 997 deletions(-) diff --git a/src/acis_api.cpp b/src/acis_api.cpp index a5540c6..b5de9ec 100644 --- a/src/acis_api.cpp +++ b/src/acis_api.cpp @@ -6,634 +6,634 @@ bool disabled_acis_freelisting = false; PyObject * a3dp_api_start_modeller(PyObject *self, PyObject *args, PyObject *kwargs) { - int input_n = 0; - int input_freelisting = 1; + int input_n = 0; + int input_freelisting = 1; - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "n", - (char *) "freelisting", - NULL - }; - - // Try to parse input arguments and/or keywords - // api_start_modeller does not utilize the "n" argument, but following the implementation but make it optional - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist, &input_n, &input_freelisting)) - return NULL; - - // Disable ACIS freelisting facility if freelisting=False - if (!input_freelisting) + // List of keyword arguments that this function can take + char *kwlist[] = { - // Display a warning message - PyErr_WarnEx(PyExc_Warning, "Disabling ACIS freelisting...", 0); - // Disable ACIS freelisting - base_configuration base_config; - base_config.enable_freelists = FALSE; - base_config.raw_allocator = malloc; - base_config.raw_destructor = free; - initialize_base(&base_config); - // Set the global variable for terminate_nase - disabled_acis_freelisting = true; - } + (char *) "n", + (char *) "freelisting", + NULL + }; + + // Try to parse input arguments and/or keywords + // api_start_modeller does not utilize the "n" argument, but following the implementation but make it optional + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist, &input_n, &input_freelisting)) + return NULL; - // Call ACIS API and check outcome - outcome result; - result = api_start_modeller(input_n); - if (!check_outcome(result)) - return NULL; - else - Py_RETURN_NONE; + // Disable ACIS freelisting facility if freelisting=False + if (!input_freelisting) + { + // Display a warning message + PyErr_WarnEx(PyExc_Warning, "Disabling ACIS freelisting...", 0); + // Disable ACIS freelisting + base_configuration base_config; + base_config.enable_freelists = FALSE; + base_config.raw_allocator = malloc; + base_config.raw_destructor = free; + initialize_base(&base_config); + // Set the global variable for terminate_nase + disabled_acis_freelisting = true; + } + + // Call ACIS API and check outcome + outcome result; + result = api_start_modeller(input_n); + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; } PyObject * a3dp_api_stop_modeller(PyObject *self) { - // Call ACIS API and check outcome - outcome result; - result = api_stop_modeller(); + // Call ACIS API and check outcome + outcome result; + result = api_stop_modeller(); - // If ACIS freelisting disabled, we need to call terminate_base() - if (disabled_acis_freelisting) - { - // Display a warning message - PyErr_WarnEx(PyExc_Warning, "Terminating ACIS...", 0); - terminate_base(); - } + // If ACIS freelisting disabled, we need to call terminate_base() + if (disabled_acis_freelisting) + { + // Display a warning message + PyErr_WarnEx(PyExc_Warning, "Terminating ACIS...", 0); + terminate_base(); + } - // Check outcome - if (!check_outcome(result)) - return NULL; - else - Py_RETURN_NONE; + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; } PyObject * a3dp_api_set_dbl_option(PyObject *self, PyObject *args, PyObject *kwargs) { - const char *input_name = NULL; - double input_value; + const char *input_name = NULL; + double input_value; - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "name", - (char *) "value", - NULL - }; + // List of keyword arguments that this function can take + char *kwlist[] = + { + (char *) "name", + (char *) "value", + NULL + }; - // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sd", kwlist, &input_name, &input_value)) - return NULL; + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sd", kwlist, &input_name, &input_value)) + return NULL; - API_BEGIN + API_BEGIN result = api_set_dbl_option(input_name, input_value); - API_END + API_END - // Check outcome - if (!check_outcome(result)) - return NULL; - else - Py_RETURN_NONE; + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; } PyObject * a3dp_api_set_int_option(PyObject *self, PyObject *args, PyObject *kwargs) { - const char *input_name = NULL; - int input_value; + const char *input_name = NULL; + int input_value; - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "name", - (char *) "value", - NULL - }; + // List of keyword arguments that this function can take + char *kwlist[] = + { + (char *) "name", + (char *) "value", + NULL + }; - // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si", kwlist, &input_name, &input_value)) - return NULL; + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si", kwlist, &input_name, &input_value)) + return NULL; - API_BEGIN + API_BEGIN result = api_set_int_option(input_name, input_value); - API_END + API_END - // Check outcome - if (!check_outcome(result)) - return NULL; - else - Py_RETURN_NONE; + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; } PyObject * a3dp_api_set_str_option(PyObject *self, PyObject *args, PyObject *kwargs) { - const char *input_name = NULL; - const char *input_value = NULL; + const char *input_name = NULL; + const char *input_value = NULL; - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "name", - (char *) "value", - NULL - }; + // List of keyword arguments that this function can take + char *kwlist[] = + { + (char *) "name", + (char *) "value", + NULL + }; - // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss", kwlist, &input_name, &input_value)) - return NULL; + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss", kwlist, &input_name, &input_value)) + return NULL; - API_BEGIN + API_BEGIN result = api_set_str_option(input_name, input_value); - API_END + API_END - // Check outcome - if (!check_outcome(result)) - return NULL; - else - Py_RETURN_NONE; + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; } PyObject * a3dp_api_solid_block(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject *input_pt1 = NULL, *input_pt2 = NULL, *input_block = NULL; + PyObject *input_pt1 = NULL, *input_pt2 = NULL, *input_block = NULL; - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "pt1", - (char *) "pt2", - (char *) "block", - NULL - }; - - // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOO", kwlist, &input_pt1, &input_pt2, &input_block)) - return NULL; - - // Type checks for ACIS objects - if (!_PyCheck_SPAposition(input_pt1)) + // List of keyword arguments that this function can take + char *kwlist[] = { - PyErr_SetString(PyExc_TypeError, "The first argument must be a SPAposition object"); - return NULL; - } + (char *) "pt1", + (char *) "pt2", + (char *) "block", + NULL + }; - if (!_PyCheck_SPAposition(input_pt2)) - { - PyErr_SetString(PyExc_TypeError, "The second argument must be a SPAposition object"); - return NULL; - } + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOO", kwlist, &input_pt1, &input_pt2, &input_block)) + return NULL; - if (!_PyCheck_BODY(input_block)) - { - PyErr_SetString(PyExc_TypeError, "The third argument must be a BODY object"); - return NULL; - } + // Type checks for ACIS objects + if (!_PyCheck_SPAposition(input_pt1)) + { + PyErr_SetString(PyExc_TypeError, "The first argument must be a SPAposition object"); + return NULL; + } + + if (!_PyCheck_SPAposition(input_pt2)) + { + PyErr_SetString(PyExc_TypeError, "The second argument must be a SPAposition object"); + return NULL; + } + + if (!_PyCheck_BODY(input_block)) + { + PyErr_SetString(PyExc_TypeError, "The third argument must be a BODY object"); + return NULL; + } - API_BEGIN + API_BEGIN - // Convert PyObject to ACIS objects - SPAposition *_pt1 = ((a3dp_SPAposition *) input_pt1)->_acis_obj; - SPAposition *_pt2 = ((a3dp_SPAposition *) input_pt2)->_acis_obj; - BODY *&_block = (BODY *&) ((a3dp_BODY *) input_block)->base_obj._acis_obj; + // Convert PyObject to ACIS objects + SPAposition *_pt1 = ((a3dp_SPAposition *) input_pt1)->_acis_obj; + SPAposition *_pt2 = ((a3dp_SPAposition *) input_pt2)->_acis_obj; + BODY * &_block = (BODY *&) ((a3dp_BODY *) input_block)->base_obj._acis_obj; - // Call ACIS API - result = api_solid_block(*_pt1, *_pt2, _block); + // Call ACIS API + result = api_solid_block(*_pt1, *_pt2, _block); - API_END + API_END - // Check outcome - if (!check_outcome(result)) - return NULL; - else - Py_RETURN_NONE; + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; } PyObject * a3dp_api_make_cuboid(PyObject *self, PyObject *args, PyObject *kwargs) { - double input_x, input_y, input_z; - PyObject *input_body = NULL; + double input_x, input_y, input_z; + PyObject *input_body = NULL; - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "x", - (char *) "y", - (char *) "z", - (char *) "body", - NULL - }; - - // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "dddO", kwlist, &input_x, &input_y, &input_z, &input_body)) - return NULL; - - // Type checks for ACIS objects - if (!_PyCheck_BODY(input_body)) + // List of keyword arguments that this function can take + char *kwlist[] = { - PyErr_SetString(PyExc_TypeError, "The fourth argument must be a BODY object"); - return NULL; - } + (char *) "x", + (char *) "y", + (char *) "z", + (char *) "body", + NULL + }; + + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "dddO", kwlist, &input_x, &input_y, &input_z, &input_body)) + return NULL; - API_BEGIN + // Type checks for ACIS objects + if (!_PyCheck_BODY(input_body)) + { + PyErr_SetString(PyExc_TypeError, "The fourth argument must be a BODY object"); + return NULL; + } - // Convert PyObject to ACIS objects - BODY *&_body = (BODY *&) ((a3dp_BODY *) input_body)->base_obj._acis_obj; + API_BEGIN - // Call ACIS API - result = api_make_cuboid(input_x, input_y, input_z, _body); + // Convert PyObject to ACIS objects + BODY * &_body = (BODY *&) ((a3dp_BODY *) input_body)->base_obj._acis_obj; - API_END + // Call ACIS API + result = api_make_cuboid(input_x, input_y, input_z, _body); - // Check outcome - if (!check_outcome(result)) - return NULL; - else - Py_RETURN_NONE; + API_END + + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; } PyObject * a3dp_api_make_frustum(PyObject *self, PyObject *args, PyObject *kwargs) { - double input_height, input_radius1, input_radius2, input_top; - PyObject *input_frust = NULL; + double input_height, input_radius1, input_radius2, input_top; + PyObject *input_frust = NULL; - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "height", - (char *) "radius1", - (char *) "radius2", - (char *) "top", - (char *) "frust", - NULL - }; - - // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ddddO", kwlist, &input_height, &input_radius1, &input_radius2, &input_top, &input_frust)) - return NULL; - - // Type checks for ACIS objects - if (!_PyCheck_BODY(input_frust)) + // List of keyword arguments that this function can take + char *kwlist[] = { - PyErr_SetString(PyExc_TypeError, "The fifth argument must be a BODY object"); - return NULL; - } + (char *) "height", + (char *) "radius1", + (char *) "radius2", + (char *) "top", + (char *) "frust", + NULL + }; - API_BEGIN + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ddddO", kwlist, &input_height, &input_radius1, &input_radius2, &input_top, &input_frust)) + return NULL; - // Convert PyObject to ACIS objects - BODY *&_frust = (BODY *&) ((a3dp_BODY *) input_frust)->base_obj._acis_obj; + // Type checks for ACIS objects + if (!_PyCheck_BODY(input_frust)) + { + PyErr_SetString(PyExc_TypeError, "The fifth argument must be a BODY object"); + return NULL; + } + + API_BEGIN - // Call ACIS API - result = api_make_frustum(input_height, input_radius1, input_radius2, input_top, _frust); + // Convert PyObject to ACIS objects + BODY * &_frust = (BODY *&) ((a3dp_BODY *) input_frust)->base_obj._acis_obj; - API_END + // Call ACIS API + result = api_make_frustum(input_height, input_radius1, input_radius2, input_top, _frust); - // Check outcome - if (!check_outcome(result)) - return NULL; - else - Py_RETURN_NONE; + API_END + + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; } PyObject * a3dp_api_make_prism(PyObject *self, PyObject *args, PyObject *kwargs) { - double input_height, input_radius1, input_radius2; - int input_nsides; - PyObject *input_prism = NULL; + double input_height, input_radius1, input_radius2; + int input_nsides; + PyObject *input_prism = NULL; - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "height", - (char *) "radius1", - (char *) "radius2", - (char *) "nsides", - (char *) "frust", - NULL - }; - - // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "dddiO", kwlist, &input_height, &input_radius1, &input_radius2, &input_nsides, &input_prism)) - return NULL; - - // Type checks for ACIS objects - if (!_PyCheck_BODY(input_prism)) + // List of keyword arguments that this function can take + char *kwlist[] = { - PyErr_SetString(PyExc_TypeError, "The fifth argument must be a BODY object"); - return NULL; - } + (char *) "height", + (char *) "radius1", + (char *) "radius2", + (char *) "nsides", + (char *) "frust", + NULL + }; - API_BEGIN + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "dddiO", kwlist, &input_height, &input_radius1, &input_radius2, &input_nsides, &input_prism)) + return NULL; - // Convert PyObject to ACIS objects - BODY *&_prism = (BODY *&) ((a3dp_BODY *) input_prism)->base_obj._acis_obj; + // Type checks for ACIS objects + if (!_PyCheck_BODY(input_prism)) + { + PyErr_SetString(PyExc_TypeError, "The fifth argument must be a BODY object"); + return NULL; + } - // Call ACIS API - result = api_make_prism(input_height, input_radius1, input_radius2, input_nsides, _prism); + API_BEGIN - API_END + // Convert PyObject to ACIS objects + BODY * &_prism = (BODY *&) ((a3dp_BODY *) input_prism)->base_obj._acis_obj; - // Check outcome - if (!check_outcome(result)) - return NULL; - else - Py_RETURN_NONE; + // Call ACIS API + result = api_make_prism(input_height, input_radius1, input_radius2, input_nsides, _prism); + + API_END + + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; } PyObject * a3dp_api_make_pyramid(PyObject *self, PyObject *args, PyObject *kwargs) { - double input_height, input_radius1, input_radius2, input_top; - int input_nsides; - PyObject *input_pyramid = NULL; + double input_height, input_radius1, input_radius2, input_top; + int input_nsides; + PyObject *input_pyramid = NULL; - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "height", - (char *) "radius1", - (char *) "radius2", - (char *) "top", - (char *) "nsides", - (char *) "pyramid", - NULL - }; - - // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ddddiO", kwlist, &input_height, &input_radius1, &input_radius2, &input_top, &input_nsides, &input_pyramid)) - return NULL; - - // Type checks for ACIS objects - if (!_PyCheck_BODY(input_pyramid)) + // List of keyword arguments that this function can take + char *kwlist[] = { - PyErr_SetString(PyExc_TypeError, "The sixth argument must be a BODY object"); - return NULL; - } + (char *) "height", + (char *) "radius1", + (char *) "radius2", + (char *) "top", + (char *) "nsides", + (char *) "pyramid", + NULL + }; - API_BEGIN + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ddddiO", kwlist, &input_height, &input_radius1, &input_radius2, &input_top, &input_nsides, &input_pyramid)) + return NULL; - // Convert PyObject to ACIS objects - BODY *&_pyramid = (BODY *&) ((a3dp_BODY *) input_pyramid)->base_obj._acis_obj; + // Type checks for ACIS objects + if (!_PyCheck_BODY(input_pyramid)) + { + PyErr_SetString(PyExc_TypeError, "The sixth argument must be a BODY object"); + return NULL; + } - // Call ACIS API - result = api_make_pyramid(input_height, input_radius1, input_radius2, input_top, input_nsides, _pyramid); + API_BEGIN - API_END + // Convert PyObject to ACIS objects + BODY * &_pyramid = (BODY *&) ((a3dp_BODY *) input_pyramid)->base_obj._acis_obj; - // Check outcome - if (!check_outcome(result)) - return NULL; - else - Py_RETURN_NONE; + // Call ACIS API + result = api_make_pyramid(input_height, input_radius1, input_radius2, input_top, input_nsides, _pyramid); + + API_END + + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; } PyObject * a3dp_api_make_sphere(PyObject *self, PyObject *args, PyObject *kwargs) { - double input_radius; - PyObject *input_sph = NULL; + double input_radius; + PyObject *input_sph = NULL; - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "radius", - (char *) "sph", - NULL - }; + // List of keyword arguments that this function can take + char *kwlist[] = + { + (char *) "radius", + (char *) "sph", + NULL + }; - // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ddddiO", kwlist, &input_radius, &input_sph)) - return NULL; + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ddddiO", kwlist, &input_radius, &input_sph)) + return NULL; - // Type checks for ACIS objects - if (!_PyCheck_BODY(input_sph)) - { - PyErr_SetString(PyExc_TypeError, "The second argument must be a BODY object"); - return NULL; - } + // Type checks for ACIS objects + if (!_PyCheck_BODY(input_sph)) + { + PyErr_SetString(PyExc_TypeError, "The second argument must be a BODY object"); + return NULL; + } - API_BEGIN + API_BEGIN - // Convert PyObject to ACIS objects - BODY *&_sph = (BODY *&) ((a3dp_BODY *) input_sph)->base_obj._acis_obj; + // Convert PyObject to ACIS objects + BODY * &_sph = (BODY *&) ((a3dp_BODY *) input_sph)->base_obj._acis_obj; - // Call ACIS API - result = api_make_sphere(input_radius, _sph); + // Call ACIS API + result = api_make_sphere(input_radius, _sph); - API_END + API_END - // Check outcome - if (!check_outcome(result)) - return NULL; - else - Py_RETURN_NONE; + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; } PyObject * a3dp_api_make_torus(PyObject *self, PyObject *args, PyObject *kwargs) { - double input_major_r, input_minor_r; - PyObject *input_tor = NULL; + double input_major_r, input_minor_r; + PyObject *input_tor = NULL; - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "major_radius", - (char *) "minor_radius", - (char *) "tor", - NULL - }; - - // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ddddiO", kwlist, &input_major_r, &input_minor_r, &input_tor)) - return NULL; - - // Type checks for ACIS objects - if (!_PyCheck_BODY(input_tor)) + // List of keyword arguments that this function can take + char *kwlist[] = { - PyErr_SetString(PyExc_TypeError, "The third argument must be a BODY object"); - return NULL; - } + (char *) "major_radius", + (char *) "minor_radius", + (char *) "tor", + NULL + }; + + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ddddiO", kwlist, &input_major_r, &input_minor_r, &input_tor)) + return NULL; + + // Type checks for ACIS objects + if (!_PyCheck_BODY(input_tor)) + { + PyErr_SetString(PyExc_TypeError, "The third argument must be a BODY object"); + return NULL; + } - API_BEGIN + API_BEGIN - // Convert PyObject to ACIS objects - BODY *&_tor = (BODY *&) ((a3dp_BODY *) input_tor)->base_obj._acis_obj; + // Convert PyObject to ACIS objects + BODY * &_tor = (BODY *&) ((a3dp_BODY *) input_tor)->base_obj._acis_obj; - // Call ACIS API - result = api_make_torus(input_major_r, input_minor_r, _tor); + // Call ACIS API + result = api_make_torus(input_major_r, input_minor_r, _tor); - API_END + API_END - // Check outcome - if (!check_outcome(result)) - return NULL; - else - Py_RETURN_NONE; + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; } PyObject * a3dp_api_apply_transf(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject *input_entity = NULL, *input_trans = NULL; + PyObject *input_entity = NULL, *input_trans = NULL; - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "entity", - (char *) "trans", - NULL - }; + // List of keyword arguments that this function can take + char *kwlist[] = + { + (char *) "entity", + (char *) "trans", + NULL + }; - // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &input_entity, &input_trans)) - return NULL; + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &input_entity, &input_trans)) + return NULL; - // Type checks for ACIS objects - if (!_PyCheck_BODY(input_entity)) - { - PyErr_SetString(PyExc_TypeError, "The first argument must be a BODY object"); - return NULL; - } + // Type checks for ACIS objects + if (!_PyCheck_BODY(input_entity)) + { + PyErr_SetString(PyExc_TypeError, "The first argument must be a BODY object"); + return NULL; + } - if (!_PyCheck_SPAtransf(input_trans)) - { - PyErr_SetString(PyExc_TypeError, "The second argument must be a SPAtransf object"); - return NULL; - } + if (!_PyCheck_SPAtransf(input_trans)) + { + PyErr_SetString(PyExc_TypeError, "The second argument must be a SPAtransf object"); + return NULL; + } - API_BEGIN + API_BEGIN - // Convert PyObject to ACIS objects - ENTITY *&_entity = ((a3dp_BODY *) input_entity)->base_obj._acis_obj; - SPAtransf *&_trans = ((a3dp_SPAtransf *) input_trans)->_acis_obj; + // Convert PyObject to ACIS objects + ENTITY * &_entity = ((a3dp_BODY *) input_entity)->base_obj._acis_obj; + SPAtransf *&_trans = ((a3dp_SPAtransf *) input_trans)->_acis_obj; - // Call ACIS API - result = api_apply_transf(_entity, *_trans); + // Call ACIS API + result = api_apply_transf(_entity, *_trans); - API_END + API_END - // Check outcome - if (!check_outcome(result)) - return NULL; - else - Py_RETURN_NONE; + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; } PyObject * a3dp_api_remove_transf(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject *input_entity = NULL; + PyObject *input_entity = NULL; - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "entity", - NULL - }; + // List of keyword arguments that this function can take + char *kwlist[] = + { + (char *) "entity", + NULL + }; - // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &input_entity)) - return NULL; + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &input_entity)) + return NULL; - // Type checks for ACIS objects - if (!_PyCheck_BODY(input_entity)) - { - PyErr_SetString(PyExc_TypeError, "The first argument must be a BODY object"); - return NULL; - } + // Type checks for ACIS objects + if (!_PyCheck_BODY(input_entity)) + { + PyErr_SetString(PyExc_TypeError, "The first argument must be a BODY object"); + return NULL; + } - API_BEGIN + API_BEGIN - // Convert PyObject to ACIS objects - ENTITY *&_entity = ((a3dp_BODY *) input_entity)->base_obj._acis_obj; + // Convert PyObject to ACIS objects + ENTITY * &_entity = ((a3dp_BODY *) input_entity)->base_obj._acis_obj; - // Call ACIS API - result = api_remove_transf(_entity); + // Call ACIS API + result = api_remove_transf(_entity); - API_END + API_END - // Check outcome - if (!check_outcome(result)) - return NULL; - else - Py_RETURN_NONE; + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; } PyObject * a3dp_api_sheet_from_ff(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject *input_faces = NULL, *input_body = NULL; + PyObject *input_faces = NULL, *input_body = NULL; - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "faces", - (char *) "body", - NULL - }; + // List of keyword arguments that this function can take + char *kwlist[] = + { + (char *) "faces", + (char *) "body", + NULL + }; - // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &input_faces, &input_body)) - return NULL; + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &input_faces, &input_body)) + return NULL; - // First argument must be a tuple of faces - PyObject *seq = PySequence_Fast(input_faces, "First argument must be a sequence of FACE objects"); + // First argument must be a tuple of faces + PyObject *seq = PySequence_Fast(input_faces, "First argument must be a sequence of FACE objects"); - // ACIS API has a limitation in api_sheet_from_ff function: As of version R2017, it can handle only 1 face - Py_ssize_t face_array_size = PySequence_Fast_GET_SIZE(seq); - if (face_array_size <= 0) - { - PyErr_SetString(PyExc_ValueError, "Sequence cannot be empty"); - Py_DECREF(seq); - return NULL; - } - else if (face_array_size > 1) - { - PyErr_WarnEx(PyExc_Warning, "ACIS API does not support generation of sheet bodies from multiple faces.", 0); - } + // ACIS API has a limitation in api_sheet_from_ff function: As of version R2017, it can handle only 1 face + Py_ssize_t face_array_size = PySequence_Fast_GET_SIZE(seq); + if (face_array_size <= 0) + { + PyErr_SetString(PyExc_ValueError, "Sequence cannot be empty"); + Py_DECREF(seq); + return NULL; + } + else if (face_array_size > 1) + { + PyErr_WarnEx(PyExc_Warning, "ACIS API does not support generation of sheet bodies from multiple faces.", 0); + } - PyObject *faceobj = PySequence_Fast_GET_ITEM(seq, 0); + PyObject *faceobj = PySequence_Fast_GET_ITEM(seq, 0); - API_BEGIN + API_BEGIN - FACE *&_face = (FACE *&) ((a3dp_FACE *) faceobj)->base_obj._acis_obj; + FACE * &_face = (FACE *&) ((a3dp_FACE *) faceobj)->base_obj._acis_obj; - FACE *_faces[1]; - _faces[0] = _face; + FACE * _faces[1]; + _faces[0] = _face; - BODY *&_body = (BODY *&) ((a3dp_BODY *) input_body)->base_obj._acis_obj; + BODY * &_body = (BODY *&) ((a3dp_BODY *) input_body)->base_obj._acis_obj; - result = api_sheet_from_ff(1, _faces, _body); + result = api_sheet_from_ff(1, _faces, _body); - API_END + API_END - // PySequence_Fast generates a new reference - Py_DECREF(seq); + // PySequence_Fast generates a new reference + Py_DECREF(seq); - // Check outcome - if (!check_outcome(result)) - { - // Returning NULL means that we have an error - return NULL; - } - else - { - // Returning none means that we have no errors - Py_RETURN_NONE; - } + // Check outcome + if (!check_outcome(result)) + { + // Returning NULL means that we have an error + return NULL; + } + else + { + // Returning none means that we have no errors + Py_RETURN_NONE; + } } /** @@ -643,241 +643,241 @@ a3dp_api_sheet_from_ff(PyObject *self, PyObject *args, PyObject *kwargs) PyObject * a3dp_api_unite(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject *input_tool = NULL, *input_blank = NULL; + PyObject *input_tool = NULL, *input_blank = NULL; - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "tool", - (char *) "blank", - NULL - }; + // List of keyword arguments that this function can take + char *kwlist[] = + { + (char *) "tool", + (char *) "blank", + NULL + }; - // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &input_tool, &input_blank)) - return NULL; + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &input_tool, &input_blank)) + return NULL; - // Type checks for ACIS objects - if (!_PyCheck_BODY(input_tool)) - { - PyErr_SetString(PyExc_TypeError, "Tool must be a BODY object"); - return NULL; - } + // Type checks for ACIS objects + if (!_PyCheck_BODY(input_tool)) + { + PyErr_SetString(PyExc_TypeError, "Tool must be a BODY object"); + return NULL; + } - if (!_PyCheck_BODY(input_blank)) - { - PyErr_SetString(PyExc_TypeError, "Blank must be a BODY object"); - return NULL; - } + if (!_PyCheck_BODY(input_blank)) + { + PyErr_SetString(PyExc_TypeError, "Blank must be a BODY object"); + return NULL; + } - API_BEGIN + API_BEGIN - // Convert PyObject to ACIS objects - BODY *&_tool = (BODY *&) ((a3dp_BODY *) input_tool)->base_obj._acis_obj; - BODY *&_blank = (BODY *&) ((a3dp_BODY *) input_blank)->base_obj._acis_obj; + // Convert PyObject to ACIS objects + BODY * &_tool = (BODY *&) ((a3dp_BODY *) input_tool)->base_obj._acis_obj; + BODY * &_blank = (BODY *&) ((a3dp_BODY *) input_blank)->base_obj._acis_obj; - // Call ACIS API - result = api_unite(_tool, _blank); + // Call ACIS API + result = api_unite(_tool, _blank); - API_END + API_END - // Check outcome - if (!check_outcome(result)) - { - // Returning NULL means that we have an error - return NULL; - } - else - { - // Boolean operations automatically delete tool bodies, but for python, we need to set reference to NULL too - __make_null(input_tool); - // Returning none means that we have no errors - Py_RETURN_NONE; - } + // Check outcome + if (!check_outcome(result)) + { + // Returning NULL means that we have an error + return NULL; + } + else + { + // Boolean operations automatically delete tool bodies, but for python, we need to set reference to NULL too + __make_null(input_tool); + // Returning none means that we have no errors + Py_RETURN_NONE; + } } PyObject * a3dp_api_intersect(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject *input_tool = NULL, *input_blank = NULL; + PyObject *input_tool = NULL, *input_blank = NULL; - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "tool", - (char *) "blank", - NULL - }; + // List of keyword arguments that this function can take + char *kwlist[] = + { + (char *) "tool", + (char *) "blank", + NULL + }; - // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &input_tool, &input_blank)) - return NULL; + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &input_tool, &input_blank)) + return NULL; - // Type checks for ACIS objects - if (!_PyCheck_BODY(input_tool)) - { - PyErr_SetString(PyExc_TypeError, "Tool must be a BODY object"); - return NULL; - } + // Type checks for ACIS objects + if (!_PyCheck_BODY(input_tool)) + { + PyErr_SetString(PyExc_TypeError, "Tool must be a BODY object"); + return NULL; + } - if (!_PyCheck_BODY(input_blank)) - { - PyErr_SetString(PyExc_TypeError, "Blank must be a BODY object"); - return NULL; - } + if (!_PyCheck_BODY(input_blank)) + { + PyErr_SetString(PyExc_TypeError, "Blank must be a BODY object"); + return NULL; + } - API_BEGIN + API_BEGIN - // Convert PyObject to ACIS objects - BODY *&_tool = (BODY *&) ((a3dp_BODY *) input_tool)->base_obj._acis_obj; - BODY *&_blank = (BODY *&) ((a3dp_BODY *) input_blank)->base_obj._acis_obj; + // Convert PyObject to ACIS objects + BODY * &_tool = (BODY *&) ((a3dp_BODY *) input_tool)->base_obj._acis_obj; + BODY * &_blank = (BODY *&) ((a3dp_BODY *) input_blank)->base_obj._acis_obj; - // Call ACIS API - result = api_intersect(_tool, _blank); + // Call ACIS API + result = api_intersect(_tool, _blank); - API_END + API_END - // Check outcome - if (!check_outcome(result)) - { - // Returning NULL means that we have an error - return NULL; - } - else - { - // Boolean operations automatically delete tool bodies, but for python, we need to set reference to NULL too - __make_null(input_tool); - // Returning none means that we have no errors - Py_RETURN_NONE; - } + // Check outcome + if (!check_outcome(result)) + { + // Returning NULL means that we have an error + return NULL; + } + else + { + // Boolean operations automatically delete tool bodies, but for python, we need to set reference to NULL too + __make_null(input_tool); + // Returning none means that we have no errors + Py_RETURN_NONE; + } } PyObject * a3dp_api_subtract(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject *input_tool = NULL, *input_blank = NULL, *input_boolopts = NULL; + PyObject *input_tool = NULL, *input_blank = NULL, *input_boolopts = NULL; - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "tool", - (char *) "blank", - (char *) "boolopts", - NULL - }; - - // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O", kwlist, &input_tool, &input_blank, &input_boolopts)) - return NULL; - - // Type checks for ACIS objects - if (!_PyCheck_BODY(input_tool)) + // List of keyword arguments that this function can take + char *kwlist[] = { - PyErr_SetString(PyExc_TypeError, "Tool must be a BODY object"); - return NULL; - } + (char *) "tool", + (char *) "blank", + (char *) "boolopts", + NULL + }; - if (!_PyCheck_BODY(input_blank)) - { - PyErr_SetString(PyExc_TypeError, "Blank must be a BODY object"); - return NULL; - } + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O", kwlist, &input_tool, &input_blank, &input_boolopts)) + return NULL; - if (input_boolopts != NULL) - if (!_PyCheck_BoolOptions(input_boolopts)) + // Type checks for ACIS objects + if (!_PyCheck_BODY(input_tool)) { - PyErr_SetString(PyExc_TypeError, "boolopts must be a BoolOptions object"); + PyErr_SetString(PyExc_TypeError, "Tool must be a BODY object"); return NULL; } - API_BEGIN - - // Convert PyObject to ACIS objects - BODY *&_tool = (BODY *&) ((a3dp_BODY *) input_tool)->base_obj._acis_obj; - BODY *&_blank = (BODY *&) ((a3dp_BODY *) input_blank)->base_obj._acis_obj; + if (!_PyCheck_BODY(input_blank)) + { + PyErr_SetString(PyExc_TypeError, "Blank must be a BODY object"); + return NULL; + } - if (input_boolopts) - { - BoolOptions *_boolopts = ((a3dp_BoolOptions *) input_boolopts)->_acis_obj; - result = api_subtract(_tool, _blank, _boolopts); - } - else + if (input_boolopts != NULL) + if (!_PyCheck_BoolOptions(input_boolopts)) { - result = api_subtract(_tool, _blank); + PyErr_SetString(PyExc_TypeError, "boolopts must be a BoolOptions object"); + return NULL; } + API_BEGIN + + // Convert PyObject to ACIS objects + BODY * &_tool = (BODY *&) ((a3dp_BODY *) input_tool)->base_obj._acis_obj; + BODY * &_blank = (BODY *&) ((a3dp_BODY *) input_blank)->base_obj._acis_obj; + + if (input_boolopts) + { + BoolOptions *_boolopts = ((a3dp_BoolOptions *) input_boolopts)->_acis_obj; + result = api_subtract(_tool, _blank, _boolopts); + } + else + { + result = api_subtract(_tool, _blank); + } - API_END - // Check outcome - if (!check_outcome(result)) - { - // Returning NULL means that we have an error - return NULL; - } - else - { - // Boolean operations automatically delete tool bodies, but for python, we need to set reference to NULL too - __make_null(input_tool); - // Returning none means that we have no errors - Py_RETURN_NONE; - } + API_END + + // Check outcome + if (!check_outcome(result)) + { + // Returning NULL means that we have an error + return NULL; + } + else + { + // Boolean operations automatically delete tool bodies, but for python, we need to set reference to NULL too + __make_null(input_tool); + // Returning none means that we have no errors + Py_RETURN_NONE; + } } PyObject * a3dp_api_imprint(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject *input_tool = NULL, *input_blank = NULL; + PyObject *input_tool = NULL, *input_blank = NULL; - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "tool", - (char *) "blank", - NULL - }; + // List of keyword arguments that this function can take + char *kwlist[] = + { + (char *) "tool", + (char *) "blank", + NULL + }; - // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &input_tool, &input_blank)) - return NULL; + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &input_tool, &input_blank)) + return NULL; - // Type checks for ACIS objects - if (!_PyCheck_BODY(input_tool)) - { - PyErr_SetString(PyExc_TypeError, "Tool must be a BODY object"); - return NULL; - } + // Type checks for ACIS objects + if (!_PyCheck_BODY(input_tool)) + { + PyErr_SetString(PyExc_TypeError, "Tool must be a BODY object"); + return NULL; + } - if (!_PyCheck_BODY(input_blank)) - { - PyErr_SetString(PyExc_TypeError, "Blank must be a BODY object"); - return NULL; - } + if (!_PyCheck_BODY(input_blank)) + { + PyErr_SetString(PyExc_TypeError, "Blank must be a BODY object"); + return NULL; + } - API_BEGIN + API_BEGIN - // Convert PyObject to ACIS objects - BODY *&_tool = (BODY *&) ((a3dp_BODY *) input_tool)->base_obj._acis_obj; - BODY *&_blank = (BODY *&) ((a3dp_BODY *) input_blank)->base_obj._acis_obj; + // Convert PyObject to ACIS objects + BODY * &_tool = (BODY *&) ((a3dp_BODY *) input_tool)->base_obj._acis_obj; + BODY * &_blank = (BODY *&) ((a3dp_BODY *) input_blank)->base_obj._acis_obj; - // Call ACIS API - result = api_imprint(_tool, _blank); + // Call ACIS API + result = api_imprint(_tool, _blank); - API_END + API_END - // Check outcome - if (!check_outcome(result)) - { - // Returning NULL means that we have an error - return NULL; - } - else - { - // Boolean operations automatically delete tool bodies, but for python, we need to set reference to NULL too - __make_null(input_tool); - // Returning none means that we have no errors - Py_RETURN_NONE; - } + // Check outcome + if (!check_outcome(result)) + { + // Returning NULL means that we have an error + return NULL; + } + else + { + // Boolean operations automatically delete tool bodies, but for python, we need to set reference to NULL too + __make_null(input_tool); + // Returning none means that we have no errors + Py_RETURN_NONE; + } } PyObject * @@ -941,31 +941,31 @@ a3dp_api_boolean_chop_body(PyObject *self, PyObject *args, PyObject *kwargs) API_BEGIN - // Convert PyObject to ACIS objects - BODY *&_tool = (BODY *&) ((a3dp_BODY *) input_tool)->base_obj._acis_obj; - BODY *&_blank = (BODY *&) ((a3dp_BODY *) input_blank)->base_obj._acis_obj; - BODY *&_outside = (BODY *&) ((a3dp_BODY *) input_outside)->base_obj._acis_obj; - BODY *&_leftovers = (BODY *&) ((a3dp_BODY *) input_leftovers)->base_obj._acis_obj; - BODY *&_result_body = (BODY *&) ((a3dp_BODY *) input_result_body)->base_obj._acis_obj; - NDBOOL_KEEP _ndbool_keep = NDBOOL_KEEP(input_ndbool_keep); - logical _nonreg = (input_nonreg == 0) ? FALSE : TRUE; + // Convert PyObject to ACIS objects + BODY * &_tool = (BODY *&) ((a3dp_BODY *) input_tool)->base_obj._acis_obj; + BODY * &_blank = (BODY *&) ((a3dp_BODY *) input_blank)->base_obj._acis_obj; + BODY * &_outside = (BODY *&) ((a3dp_BODY *) input_outside)->base_obj._acis_obj; + BODY * &_leftovers = (BODY *&) ((a3dp_BODY *) input_leftovers)->base_obj._acis_obj; + BODY * &_result_body = (BODY *&) ((a3dp_BODY *) input_result_body)->base_obj._acis_obj; + NDBOOL_KEEP _ndbool_keep = NDBOOL_KEEP(input_ndbool_keep); + logical _nonreg = (input_nonreg == 0) ? FALSE : TRUE; - if (input_boolopts != NULL) - { - if (!_PyCheck_NDBOOL_KEEP(input_boolopts)) - { - PyErr_SetString(PyExc_TypeError, "boolopts variable must be a BoolOptions object"); - return NULL; - } + if (input_boolopts != NULL) + { + if (!_PyCheck_NDBOOL_KEEP(input_boolopts)) + { + PyErr_SetString(PyExc_TypeError, "boolopts variable must be a BoolOptions object"); + return NULL; + } - BoolOptions *&_boolopts = (BoolOptions *&) ((a3dp_BoolOptions *) input_boolopts)->_acis_obj; + BoolOptions *&_boolopts = (BoolOptions *&) ((a3dp_BoolOptions *) input_boolopts)->_acis_obj; - result = api_boolean_chop_body(_tool, _blank, _nonreg, _outside, _leftovers, _ndbool_keep, _result_body, _boolopts); - } - else - { - result = api_boolean_chop_body(_tool, _blank, _nonreg, _outside, _leftovers, _ndbool_keep, _result_body); - } + result = api_boolean_chop_body(_tool, _blank, _nonreg, _outside, _leftovers, _ndbool_keep, _result_body, _boolopts); + } + else + { + result = api_boolean_chop_body(_tool, _blank, _nonreg, _outside, _leftovers, _ndbool_keep, _result_body); + } API_END @@ -979,63 +979,63 @@ a3dp_api_boolean_chop_body(PyObject *self, PyObject *args, PyObject *kwargs) PyObject * a3dp_api_save_entity_list(PyObject *self, PyObject *args, PyObject *kwargs) { - // According to the documentation, Python 3 doesn't do good with FILE* objects, so we take "file name" as an input - const char *input_filename = NULL; - int input_savemode; - PyObject *input_entitylist = NULL; - - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "file_name", - (char *) "text_mode", - (char *) "entity_list_save", - NULL - }; - - // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO", kwlist, &input_filename, &input_savemode, &input_entitylist)) - return NULL; - - // Check if the input is an ENTITY_LIST - if (!_PyCheck_ENTITY_LIST(input_entitylist)) + // According to the documentation, Python 3 doesn't do good with FILE* objects, so we take "file name" as an input + const char *input_filename = NULL; + int input_savemode; + PyObject *input_entitylist = NULL; + + // List of keyword arguments that this function can take + char *kwlist[] = { - PyErr_SetString(PyExc_TypeError, "Expecting ENTITY_LIST object"); - return NULL; - } + (char *) "file_name", + (char *) "text_mode", + (char *) "entity_list_save", + NULL + }; - // Using the file name input as a string, create a file handle - FILE *_file_handle = fopen(input_filename, "w"); + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO", kwlist, &input_filename, &input_savemode, &input_entitylist)) + return NULL; - // Check if the file has been opened correctly - if (_file_handle == NULL) - { - PyErr_SetString(PyExc_IOError, "Cannot open file for writing!"); - return NULL; - } + // Check if the input is an ENTITY_LIST + if (!_PyCheck_ENTITY_LIST(input_entitylist)) + { + PyErr_SetString(PyExc_TypeError, "Expecting ENTITY_LIST object"); + return NULL; + } + + // Using the file name input as a string, create a file handle + FILE *_file_handle = fopen(input_filename, "w"); + + // Check if the file has been opened correctly + if (_file_handle == NULL) + { + PyErr_SetString(PyExc_IOError, "Cannot open file for writing!"); + return NULL; + } - // Set file writing mode - logical _text_mode = (input_savemode == 0) ? FALSE : TRUE; + // Set file writing mode + logical _text_mode = (input_savemode == 0) ? FALSE : TRUE; - API_NOP_BEGIN + API_NOP_BEGIN - // Convert PyObject to ENTITY_LIST - ENTITY_LIST *_save_list = ((a3dp_ENTITY_LIST *) input_entitylist)->_acis_obj; + // Convert PyObject to ENTITY_LIST + ENTITY_LIST *_save_list = ((a3dp_ENTITY_LIST *) input_entitylist)->_acis_obj; - // Call ACIS API and check outcome - result = api_save_entity_list(_file_handle, _text_mode, *_save_list); + // Call ACIS API and check outcome + result = api_save_entity_list(_file_handle, _text_mode, *_save_list); - API_NOP_END + API_NOP_END - // Don't forget to close the file handle - fclose(_file_handle); + // Don't forget to close the file handle + fclose(_file_handle); - // Check outcome - if (!check_outcome(result)) - return NULL; - else - Py_RETURN_NONE; + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; } PyObject * @@ -1081,12 +1081,12 @@ a3dp_api_restore_entity_list(PyObject *self, PyObject *args, PyObject *kwargs) API_NOP_BEGIN - // Convert PyObject to ENTITY_LIST - ENTITY_LIST *_save_list = ((a3dp_ENTITY_LIST *) input_entitylist)->_acis_obj; + // Convert PyObject to ENTITY_LIST + ENTITY_LIST *_save_list = ((a3dp_ENTITY_LIST *) input_entitylist)->_acis_obj; - // Call ACIS API and check outcome - result = api_restore_entity_list(_file_handle, _text_mode, *_save_list); + // Call ACIS API and check outcome + result = api_restore_entity_list(_file_handle, _text_mode, *_save_list); API_NOP_END @@ -1103,131 +1103,131 @@ a3dp_api_restore_entity_list(PyObject *self, PyObject *args, PyObject *kwargs) PyObject * a3dp_api_set_file_info(PyObject *self, PyObject *args, PyObject *kwargs) { - int input_product_id = 0; - int input_units = 0; - PyObject *input_info = NULL; - - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "info", - (char *) "product_id", - (char *) "units", - NULL - }; - - // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|ii", kwlist, &input_info, &input_product_id, &input_units)) - return NULL; - - // Check if we have a FileInfo object - if (!_PyCheck_FileInfo(input_info)) + int input_product_id = 0; + int input_units = 0; + PyObject *input_info = NULL; + + // List of keyword arguments that this function can take + char *kwlist[] = { - PyErr_SetString(PyExc_TypeError, "Expecting FileInfo object"); - return NULL; - } + (char *) "info", + (char *) "product_id", + (char *) "units", + NULL + }; - // Set up the value of mask - bool _product_id = input_product_id != 0; - bool _units = input_units != 0; + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|ii", kwlist, &input_info, &input_product_id, &input_units)) + return NULL; - unsigned long _mask; - if (_product_id && !_units) - { - _mask = FileIdent; - } - else if (!_product_id && _units) - { - _mask = FileUnits; - } - else - { - _mask = FileUnits | FileIdent; - } + // Check if we have a FileInfo object + if (!_PyCheck_FileInfo(input_info)) + { + PyErr_SetString(PyExc_TypeError, "Expecting FileInfo object"); + return NULL; + } + + // Set up the value of mask + bool _product_id = input_product_id != 0; + bool _units = input_units != 0; + + unsigned long _mask; + if (_product_id && !_units) + { + _mask = FileIdent; + } + else if (!_product_id && _units) + { + _mask = FileUnits; + } + else + { + _mask = FileUnits | FileIdent; + } - API_BEGIN + API_BEGIN - // Convert PyObject to FileInfo - FileInfo *_info = ((a3dp_FileInfo *) input_info)->_acis_obj; + // Convert PyObject to FileInfo + FileInfo *_info = ((a3dp_FileInfo *) input_info)->_acis_obj; - result = api_set_file_info(_mask, *_info); + result = api_set_file_info(_mask, *_info); - API_END + API_END - // Check outcome - if (!check_outcome(result)) - return NULL; - else - Py_RETURN_NONE; + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; } PyObject * a3dp_api_get_file_info(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject *input_info = NULL; + PyObject *input_info = NULL; - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "info", - NULL - }; + // List of keyword arguments that this function can take + char *kwlist[] = + { + (char *) "info", + NULL + }; - // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &input_info)) - return NULL; + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &input_info)) + return NULL; - // Check if we have a FileInfo object - if (_PyCheck_FileInfo(input_info)) - { - PyErr_SetString(PyExc_TypeError, "Expecting FileInfo object"); - return NULL; - } + // Check if we have a FileInfo object + if (_PyCheck_FileInfo(input_info)) + { + PyErr_SetString(PyExc_TypeError, "Expecting FileInfo object"); + return NULL; + } - API_BEGIN + API_BEGIN - // Convert PyObject to FileInfo - FileInfo *_info = ((a3dp_FileInfo *) input_info)->_acis_obj; + // Convert PyObject to FileInfo + FileInfo *_info = ((a3dp_FileInfo *) input_info)->_acis_obj; - result = api_get_file_info(*_info); + result = api_get_file_info(*_info); - API_END + API_END - // Check outcome - if (!check_outcome(result)) - return NULL; - else - Py_RETURN_NONE; + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; } PyObject * a3dp_api_save_version(PyObject *self, PyObject *args, PyObject *kwargs) { - int input_major_version, input_minor_version; + int input_major_version, input_minor_version; - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "major_version", - (char *) "minor_version", - NULL - }; + // List of keyword arguments that this function can take + char *kwlist[] = + { + (char *) "major_version", + (char *) "minor_version", + NULL + }; - // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii", kwlist, &input_major_version, &input_minor_version)) - return NULL; + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii", kwlist, &input_major_version, &input_minor_version)) + return NULL; - API_BEGIN + API_BEGIN - result = api_save_version(input_major_version, input_minor_version); + result = api_save_version(input_major_version, input_minor_version); - API_END + API_END - // Check outcome - if (!check_outcome(result)) - return NULL; - else - Py_RETURN_NONE; + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; } /** @@ -1237,218 +1237,218 @@ a3dp_api_save_version(PyObject *self, PyObject *args, PyObject *kwargs) PyObject * a3dp_api_make_sweep_path(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject *input_pts = NULL, *input_path = NULL; - - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "pts", - (char *) "path", - NULL - }; - - // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &input_pts, &input_path)) - return NULL; - - // Type checks for ACIS objects - if (!_PyCheck_EDGE(input_path)) + PyObject *input_pts = NULL, *input_path = NULL; + + // List of keyword arguments that this function can take + char *kwlist[] = { - PyErr_SetString(PyExc_TypeError, "Second argument (path) must be an EDGE object"); - return NULL; - } + (char *) "pts", + (char *) "path", + NULL + }; - // The first object must be a python sequence containing SPAposition objects - PyObject *seq = PySequence_Fast(input_pts, "First argument (pts) must be a sequence of SPAposition objects, such as a list or a tuple"); + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &input_pts, &input_path)) + return NULL; - Py_ssize_t position_vector_size = PySequence_Fast_GET_SIZE(seq); - if (position_vector_size <= 0) - { - PyErr_SetString(PyExc_ValueError, "Sequence cannot be empty"); - Py_DECREF(seq); - return NULL; - } + // Type checks for ACIS objects + if (!_PyCheck_EDGE(input_path)) + { + PyErr_SetString(PyExc_TypeError, "Second argument (path) must be an EDGE object"); + return NULL; + } + + // The first object must be a python sequence containing SPAposition objects + PyObject *seq = PySequence_Fast(input_pts, "First argument (pts) must be a sequence of SPAposition objects, such as a list or a tuple"); + + Py_ssize_t position_vector_size = PySequence_Fast_GET_SIZE(seq); + if (position_vector_size <= 0) + { + PyErr_SetString(PyExc_ValueError, "Sequence cannot be empty"); + Py_DECREF(seq); + return NULL; + } - // It seems unnecessary to implement a SPAposition container as python itself provides a handful of containers for every purpose - SPAposition_vector _pts; + // It seems unnecessary to implement a SPAposition container as python itself provides a handful of containers for every purpose + SPAposition_vector _pts; - for (Py_ssize_t i = 0; i < position_vector_size; i++) + for (Py_ssize_t i = 0; i < position_vector_size; i++) + { + PyObject *pt_temp; + pt_temp = PySequence_Fast_GET_ITEM(seq, i); + if (!_PyCheck_SPAposition(pt_temp)) { - PyObject *pt_temp; - pt_temp = PySequence_Fast_GET_ITEM(seq, i); - if (!_PyCheck_SPAposition(pt_temp)) - { - PyErr_SetString(PyExc_TypeError, "Sequence must contain SPAposition objects"); - Py_DECREF(seq); - return NULL; - } - _pts.push_back(*((a3dp_SPAposition *) pt_temp)->_acis_obj); + PyErr_SetString(PyExc_TypeError, "Sequence must contain SPAposition objects"); + Py_DECREF(seq); + return NULL; } + _pts.push_back(*((a3dp_SPAposition *) pt_temp)->_acis_obj); + } - API_BEGIN + API_BEGIN - EDGE *&_path = (EDGE *&) ((a3dp_EDGE *) input_path)->base_obj._acis_obj; + EDGE * &_path = (EDGE *&) ((a3dp_EDGE *) input_path)->base_obj._acis_obj; - // Don't use make_sweep_path_options for now - result = api_make_sweep_path(_pts, _path); + // Don't use make_sweep_path_options for now + result = api_make_sweep_path(_pts, _path); - API_END + API_END - // PySequence_Fast returns a new reference - Py_DECREF(seq); + // PySequence_Fast returns a new reference + Py_DECREF(seq); - // Check outcome - if (!check_outcome(result)) - { - // Returning NULL means that we have an error - return NULL; - } - else - { - // Clear SPAposition container - _pts.clear(); - // Returning none means that we have no errors - Py_RETURN_NONE; - } + // Check outcome + if (!check_outcome(result)) + { + // Returning NULL means that we have an error + return NULL; + } + else + { + // Clear SPAposition container + _pts.clear(); + // Returning none means that we have no errors + Py_RETURN_NONE; + } } PyObject * a3dp_api_sweep_with_options(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject *input_arg1 = NULL, *input_arg2 = NULL, *input_arg3 = NULL, *input_arg4 = NULL, *input_arg5 = NULL; - - // List of keyword arguments that this function can take - char *kwlist[] = - { - (char *) "arg1", - (char *) "arg2", - (char *) "arg3", - (char *) "arg4", - (char *) "arg5", - NULL - }; - - // Try to parse input arguments and/or keywords (hold sweep_options for now) - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOOO|O", kwlist, &input_arg1, &input_arg2, &input_arg3, &input_arg4, &input_arg5)) - return NULL; - - /* - * IMPORTANT NOTE: This function wraps all 4 api_sweep_with_options overloads in one single Python function. - * The reason is that Python doesn't allow overloading with same function names but different signatures. - */ - - // In all overloads, first argument is always an ENTITY object - if (!_PyCheck_ENTITY(input_arg1)) + PyObject *input_arg1 = NULL, *input_arg2 = NULL, *input_arg3 = NULL, *input_arg4 = NULL, *input_arg5 = NULL; + + // List of keyword arguments that this function can take + char *kwlist[] = { - PyErr_SetString(PyExc_TypeError, "First argument must be an ENTITY object"); - return NULL; - } + (char *) "arg1", + (char *) "arg2", + (char *) "arg3", + (char *) "arg4", + (char *) "arg5", + NULL + }; - API_BEGIN + // Try to parse input arguments and/or keywords (hold sweep_options for now) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOOO|O", kwlist, &input_arg1, &input_arg2, &input_arg3, &input_arg4, &input_arg5)) + return NULL; - ENTITY *&_ent = (ENTITY *&) ((a3dp_ENTITY *) input_arg1)->_acis_obj; + /* + * IMPORTANT NOTE: This function wraps all 4 api_sweep_with_options overloads in one single Python function. + * The reason is that Python doesn't allow overloading with same function names but different signatures. + */ - // Check if we are using the sweep along the axis overload - if (input_arg5 != NULL) - { - if (!_PyCheck_SPAposition(input_arg2)) - { - PyErr_SetString(PyExc_TypeError, "Second argument must be a SPAposition object"); - return NULL; - } - - if (!_PyCheck_SPAvector(input_arg3)) - { - PyErr_SetString(PyExc_TypeError, "Third argument must be a SPAvector object"); - return NULL; - } - - if (!_PyCheck_sweep_options(input_arg4)) - { - PyErr_SetString(PyExc_TypeError, "Fourth argument must be a sweep_options object"); - return NULL; - } - - if (!_PyCheck_BODY(input_arg5)) - { - PyErr_SetString(PyExc_TypeError, "Fifth argument must be a BODY object"); - return NULL; - } - - SPAposition *&_root = (SPAposition *&) ((a3dp_SPAposition *) input_arg2)->_acis_obj; - SPAvector *&_axis = (SPAvector *&) ((a3dp_SPAvector *) input_arg3)->_acis_obj; - sweep_options *&_opts = (sweep_options *&) ((a3dp_sweep_options *) input_arg4)->_acis_obj; - BODY *&_new_body = (BODY *&) ((a3dp_BODY *) input_arg5)->base_obj._acis_obj; - - // Call ACIS Sweeping API - result = api_sweep_with_options(_ent, *_root, *_axis, _opts, _new_body); + // In all overloads, first argument is always an ENTITY object + if (!_PyCheck_ENTITY(input_arg1)) + { + PyErr_SetString(PyExc_TypeError, "First argument must be an ENTITY object"); + return NULL; + } - } - else - { - // We must be using the other overloads, then the 3rd argument must be a sweep_options object - if (!_PyCheck_sweep_options(input_arg3)) - { - PyErr_SetString(PyExc_TypeError, "Third argument must be a sweep_options object"); - return NULL; - } - - sweep_options *&_opts = (sweep_options *&) ((a3dp_sweep_options *) input_arg3)->_acis_obj; - - // and the 4th argument must be a BODY object - if (!_PyCheck_BODY(input_arg4)) - { - PyErr_SetString(PyExc_TypeError, "Fourth argument must be a BODY object"); - return NULL; - } - - BODY *&_new_body = (BODY *&) ((a3dp_BODY *) input_arg4)->base_obj._acis_obj; - - // Check for sweeping along a given edge or a wire overload - if (_PyCheck_ENTITY(input_arg2)) - { - ENTITY *&_path = (ENTITY *&) ((a3dp_ENTITY *) input_arg2)->_acis_obj; - - // Call ACIS Sweeping API - result = api_sweep_with_options(_ent, _path, _opts, _new_body); - } - else if (PyFloat_Check(input_arg2)) - { - // We must be using sweeping along a specified distance overload - double _distance = PyFloat_AsDouble(input_arg2); - - // Call ACIS Sweeping API - result = api_sweep_with_options(_ent, _distance, _opts, _new_body); - } - else if (_PyCheck_SPAvector(input_arg2)) - { - // We must be using sweeping along a specified vector overload - SPAvector *&_vec = (SPAvector *&) ((a3dp_SPAvector *) input_arg2)->_acis_obj; - - // Call ACIS Sweeping API - result = api_sweep_with_options(_ent, *_vec, _opts, _new_body); - } - else - { - PyErr_SetString(PyExc_TypeError, "Second argument must be an ENTITY, float or SPAvector object"); - return NULL; - } + API_BEGIN - } + ENTITY * &_ent = (ENTITY *&) ((a3dp_ENTITY *) input_arg1)->_acis_obj; - API_END + // Check if we are using the sweep along the axis overload + if (input_arg5 != NULL) + { + if (!_PyCheck_SPAposition(input_arg2)) + { + PyErr_SetString(PyExc_TypeError, "Second argument must be a SPAposition object"); + return NULL; + } + + if (!_PyCheck_SPAvector(input_arg3)) + { + PyErr_SetString(PyExc_TypeError, "Third argument must be a SPAvector object"); + return NULL; + } + + if (!_PyCheck_sweep_options(input_arg4)) + { + PyErr_SetString(PyExc_TypeError, "Fourth argument must be a sweep_options object"); + return NULL; + } + + if (!_PyCheck_BODY(input_arg5)) + { + PyErr_SetString(PyExc_TypeError, "Fifth argument must be a BODY object"); + return NULL; + } + + SPAposition *&_root = (SPAposition *&) ((a3dp_SPAposition *) input_arg2)->_acis_obj; + SPAvector *&_axis = (SPAvector *&) ((a3dp_SPAvector *) input_arg3)->_acis_obj; + sweep_options *&_opts = (sweep_options *&) ((a3dp_sweep_options *) input_arg4)->_acis_obj; + BODY * &_new_body = (BODY *&) ((a3dp_BODY *) input_arg5)->base_obj._acis_obj; + + // Call ACIS Sweeping API + result = api_sweep_with_options(_ent, *_root, *_axis, _opts, _new_body); + + } + else + { + // We must be using the other overloads, then the 3rd argument must be a sweep_options object + if (!_PyCheck_sweep_options(input_arg3)) + { + PyErr_SetString(PyExc_TypeError, "Third argument must be a sweep_options object"); + return NULL; + } + + sweep_options *&_opts = (sweep_options *&) ((a3dp_sweep_options *) input_arg3)->_acis_obj; + + // and the 4th argument must be a BODY object + if (!_PyCheck_BODY(input_arg4)) + { + PyErr_SetString(PyExc_TypeError, "Fourth argument must be a BODY object"); + return NULL; + } + + BODY * &_new_body = (BODY *&) ((a3dp_BODY *) input_arg4)->base_obj._acis_obj; + + // Check for sweeping along a given edge or a wire overload + if (_PyCheck_ENTITY(input_arg2)) + { + ENTITY * &_path = (ENTITY *&) ((a3dp_ENTITY *) input_arg2)->_acis_obj; + + // Call ACIS Sweeping API + result = api_sweep_with_options(_ent, _path, _opts, _new_body); + } + else if (PyFloat_Check(input_arg2)) + { + // We must be using sweeping along a specified distance overload + double _distance = PyFloat_AsDouble(input_arg2); + + // Call ACIS Sweeping API + result = api_sweep_with_options(_ent, _distance, _opts, _new_body); + } + else if (_PyCheck_SPAvector(input_arg2)) + { + // We must be using sweeping along a specified vector overload + SPAvector *&_vec = (SPAvector *&) ((a3dp_SPAvector *) input_arg2)->_acis_obj; + + // Call ACIS Sweeping API + result = api_sweep_with_options(_ent, *_vec, _opts, _new_body); + } + else + { + PyErr_SetString(PyExc_TypeError, "Second argument must be an ENTITY, float or SPAvector object"); + return NULL; + } + + } - // Check outcome - if (!check_outcome(result)) - { - // Returning NULL means that we have an error - return NULL; - } - else - { - // Returning none means that we have no errors - Py_RETURN_NONE; - } + API_END + + // Check outcome + if (!check_outcome(result)) + { + // Returning NULL means that we have an error + return NULL; + } + else + { + // Returning none means that we have no errors + Py_RETURN_NONE; + } } PyObject * @@ -1482,12 +1482,12 @@ a3dp_api_get_faces(PyObject *self, PyObject *args, PyObject *kwargs) API_BEGIN - // Get the ACIS objects from the user input - ENTITY *&_ent = ((a3dp_ENTITY *) input_ent)->_acis_obj; - ENTITY_LIST *&_face_list = ((a3dp_ENTITY_LIST *) input_ent_list)->_acis_obj; + // Get the ACIS objects from the user input + ENTITY * &_ent = ((a3dp_ENTITY *) input_ent)->_acis_obj; + ENTITY_LIST *&_face_list = ((a3dp_ENTITY_LIST *) input_ent_list)->_acis_obj; - // Call ACIS function - result = api_get_faces(_ent, *_face_list); + // Call ACIS function + result = api_get_faces(_ent, *_face_list); API_END @@ -1536,12 +1536,12 @@ a3dp_api_get_edges(PyObject *self, PyObject *args, PyObject *kwargs) API_BEGIN - // Get the ACIS objects from the user input - ENTITY *&_ent = ((a3dp_ENTITY *) input_ent)->_acis_obj; - ENTITY_LIST *&_edge_list = ((a3dp_ENTITY_LIST *) input_ent_list)->_acis_obj; + // Get the ACIS objects from the user input + ENTITY * &_ent = ((a3dp_ENTITY *) input_ent)->_acis_obj; + ENTITY_LIST *&_edge_list = ((a3dp_ENTITY_LIST *) input_ent_list)->_acis_obj; - // Call ACIS function - result = api_get_edges(_ent, *_edge_list); + // Call ACIS function + result = api_get_edges(_ent, *_edge_list); API_END @@ -1579,7 +1579,7 @@ a3dp_api_logging(PyObject *self, PyObject *args, PyObject *kwargs) API_BEGIN - result = api_logging(_on_off); + result = api_logging(_on_off); API_END @@ -1615,7 +1615,7 @@ a3dp_api_body_to_1d(PyObject *self, PyObject *args, PyObject *kwargs) return NULL; } - BODY *&_body = (BODY *&) ((a3dp_BODY *) input_body)->base_obj._acis_obj; + BODY * &_body = (BODY *&) ((a3dp_BODY *) input_body)->base_obj._acis_obj; logical _fix_normals = (input_fix_normals == 0) ? FALSE : TRUE; ENTITY_LIST _ref_faces = *(ENTITY_LIST *) NULL_REF; @@ -1632,7 +1632,7 @@ a3dp_api_body_to_1d(PyObject *self, PyObject *args, PyObject *kwargs) API_BEGIN - result = api_body_to_1d(_body, _fix_normals, _ref_faces); + result = api_body_to_1d(_body, _fix_normals, _ref_faces); API_END @@ -1665,11 +1665,11 @@ a3dp_api_body_to_2d(PyObject *self, PyObject *args, PyObject *kwargs) return NULL; } - BODY *&_body = (BODY *&) ((a3dp_BODY *) input_body)->base_obj._acis_obj; + BODY * &_body = (BODY *&) ((a3dp_BODY *) input_body)->base_obj._acis_obj; API_BEGIN - result = api_body_to_2d(_body); + result = api_body_to_2d(_body); API_END @@ -1702,13 +1702,13 @@ a3dp_api_get_entity_id(PyObject *self, PyObject *args, PyObject *kwargs) return NULL; } - ENTITY *_ent = ((a3dp_ENTITY *) input_ent)->_acis_obj; + ENTITY * _ent = ((a3dp_ENTITY *) input_ent)->_acis_obj; // tag_id_type is a typedef'd int tag_id_type _id; API_BEGIN - result = api_get_entity_id(_ent, _id); + result = api_get_entity_id(_ent, _id); API_END From 7a4487a5a0b26a0e7e801b55ee19ae211266c194 Mon Sep 17 00:00:00 2001 From: "Onur R. Bingol" Date: Sun, 17 Dec 2017 21:46:41 -0600 Subject: [PATCH 12/18] Update all boolean operations API call wrappers with BoolOptions --- src/acis_api.cpp | 76 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 12 deletions(-) diff --git a/src/acis_api.cpp b/src/acis_api.cpp index b5de9ec..91a4f6c 100644 --- a/src/acis_api.cpp +++ b/src/acis_api.cpp @@ -643,13 +643,14 @@ a3dp_api_sheet_from_ff(PyObject *self, PyObject *args, PyObject *kwargs) PyObject * a3dp_api_unite(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject *input_tool = NULL, *input_blank = NULL; + PyObject *input_tool = NULL, *input_blank = NULL, *input_boolopts = NULL; // List of keyword arguments that this function can take char *kwlist[] = { (char *) "tool", (char *) "blank", + (char *) "boolopts", NULL }; @@ -670,14 +671,30 @@ a3dp_api_unite(PyObject *self, PyObject *args, PyObject *kwargs) return NULL; } + if (input_boolopts != NULL) + { + if (!_PyCheck_BoolOptions(input_boolopts)) + { + PyErr_SetString(PyExc_TypeError, "boolopts must be a BoolOptions object"); + return NULL; + } + } + API_BEGIN // Convert PyObject to ACIS objects BODY * &_tool = (BODY *&) ((a3dp_BODY *) input_tool)->base_obj._acis_obj; BODY * &_blank = (BODY *&) ((a3dp_BODY *) input_blank)->base_obj._acis_obj; - // Call ACIS API - result = api_unite(_tool, _blank); + if (input_boolopts) + { + BoolOptions *_boolopts = ((a3dp_BoolOptions *) input_boolopts)->_acis_obj; + result = api_unite(_tool, _blank, _boolopts); + } + else + { + result = api_unite(_tool, _blank); + } API_END @@ -699,18 +716,19 @@ a3dp_api_unite(PyObject *self, PyObject *args, PyObject *kwargs) PyObject * a3dp_api_intersect(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject *input_tool = NULL, *input_blank = NULL; + PyObject *input_tool = NULL, *input_blank = NULL, *input_boolopts = NULL; // List of keyword arguments that this function can take char *kwlist[] = { (char *) "tool", (char *) "blank", + (char *) "boolopts", NULL }; // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &input_tool, &input_blank)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O", kwlist, &input_tool, &input_blank, &input_boolopts)) return NULL; // Type checks for ACIS objects @@ -726,14 +744,30 @@ a3dp_api_intersect(PyObject *self, PyObject *args, PyObject *kwargs) return NULL; } + if (input_boolopts != NULL) + { + if (!_PyCheck_BoolOptions(input_boolopts)) + { + PyErr_SetString(PyExc_TypeError, "boolopts must be a BoolOptions object"); + return NULL; + } + } + API_BEGIN // Convert PyObject to ACIS objects BODY * &_tool = (BODY *&) ((a3dp_BODY *) input_tool)->base_obj._acis_obj; BODY * &_blank = (BODY *&) ((a3dp_BODY *) input_blank)->base_obj._acis_obj; - // Call ACIS API - result = api_intersect(_tool, _blank); + if (input_boolopts) + { + BoolOptions *_boolopts = ((a3dp_BoolOptions *) input_boolopts)->_acis_obj; + result = api_intersect(_tool, _blank, _boolopts); + } + else + { + result = api_intersect(_tool, _blank); + } API_END @@ -784,11 +818,13 @@ a3dp_api_subtract(PyObject *self, PyObject *args, PyObject *kwargs) } if (input_boolopts != NULL) + { if (!_PyCheck_BoolOptions(input_boolopts)) { PyErr_SetString(PyExc_TypeError, "boolopts must be a BoolOptions object"); return NULL; } + } API_BEGIN @@ -806,7 +842,6 @@ a3dp_api_subtract(PyObject *self, PyObject *args, PyObject *kwargs) result = api_subtract(_tool, _blank); } - API_END // Check outcome @@ -827,18 +862,19 @@ a3dp_api_subtract(PyObject *self, PyObject *args, PyObject *kwargs) PyObject * a3dp_api_imprint(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject *input_tool = NULL, *input_blank = NULL; + PyObject *input_tool = NULL, *input_blank = NULL, *input_boolopts = NULL; // List of keyword arguments that this function can take char *kwlist[] = { (char *) "tool", (char *) "blank", + (char *) "boolopts", NULL }; // Try to parse input arguments and/or keywords - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &input_tool, &input_blank)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O", kwlist, &input_tool, &input_blank, &input_boolopts)) return NULL; // Type checks for ACIS objects @@ -854,14 +890,30 @@ a3dp_api_imprint(PyObject *self, PyObject *args, PyObject *kwargs) return NULL; } + if (input_boolopts != NULL) + { + if (!_PyCheck_BoolOptions(input_boolopts)) + { + PyErr_SetString(PyExc_TypeError, "boolopts must be a BoolOptions object"); + return NULL; + } + } + API_BEGIN // Convert PyObject to ACIS objects BODY * &_tool = (BODY *&) ((a3dp_BODY *) input_tool)->base_obj._acis_obj; BODY * &_blank = (BODY *&) ((a3dp_BODY *) input_blank)->base_obj._acis_obj; - // Call ACIS API - result = api_imprint(_tool, _blank); + if (input_boolopts) + { + BoolOptions *_boolopts = ((a3dp_BoolOptions *) input_boolopts)->_acis_obj; + result = api_imprint(_tool, _blank, _boolopts); + } + else + { + result = api_imprint(_tool, _blank); + } API_END From e9ad3e1d29ae39ef84d8bd5668368c7b8e607521 Mon Sep 17 00:00:00 2001 From: "Onur R. Bingol" Date: Sun, 17 Dec 2017 22:00:37 -0600 Subject: [PATCH 13/18] Add SPAboxing_options class wrapper --- src/acis_classes.cpp | 93 ++++++++++++++++++++++++++++++++++++++++++++ src/acis_classes.h | 11 ++++++ src/acis_includes.h | 1 + src/acis_modeler.cpp | 6 +++ 4 files changed, 111 insertions(+) diff --git a/src/acis_classes.cpp b/src/acis_classes.cpp index 7a4d717..ad1e045 100644 --- a/src/acis_classes.cpp +++ b/src/acis_classes.cpp @@ -2376,3 +2376,96 @@ _PyCheck_BoolOptions(PyObject *ob) { return PyObject_TypeCheck(ob, &a3dp_type_BoolOptions); } + + +/** + * SPAboxing_options + */ + +static void +a3dp_SPAboxing_options_dealloc(a3dp_BoolOptions *self) +{ + // Delete ACIS object + ACIS_DELETE self->_acis_obj; + + Py_TYPE(self)->tp_free((PyObject *) self); +} + +static PyObject * +a3dp_SPAboxing_options_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + a3dp_SPAboxing_options *self; + + self = (a3dp_SPAboxing_options *) type->tp_alloc(type, 0); + if (self != NULL) + { + // Just getting rid of the dangling pointer + self->_acis_obj = NULL; + } + + return (PyObject *) self; +} + +static int +a3dp_SPAboxing_options_init(a3dp_SPAboxing_options *self, PyObject *args, PyObject *kwargs) +{ + // Initialize the ACIS object + self->_acis_obj = ACIS_NEW SPAboxing_options(); + + return 0; +} + +PyTypeObject + a3dp_type_SPAboxing_options = + { + PyVarObject_HEAD_INIT(NULL, 0) + "ACIS.SPAboxing_options", /* tp_name */ + sizeof(a3dp_BoolOptions), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor) a3dp_SPAboxing_options_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + "BoolOptions class represents common data and functionality for all boxing options", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc) a3dp_SPAboxing_options_init, /* tp_init */ + 0, /* tp_alloc */ + a3dp_SPAboxing_options_new, /* tp_new */ + }; + +PyObject * +_PyNew_SPAboxing_options() +{ + return PyObject_CallObject((PyObject *) &a3dp_type_SPAboxing_options, NULL); +} + +bool +_PyCheck_SPAboxing_options(PyObject *ob) +{ + return PyObject_TypeCheck(ob, &a3dp_type_SPAboxing_options); +} diff --git a/src/acis_classes.h b/src/acis_classes.h index 4a233c6..0c9ecb7 100644 --- a/src/acis_classes.h +++ b/src/acis_classes.h @@ -96,6 +96,13 @@ typedef struct BoolOptions *_acis_obj; } a3dp_BoolOptions; +// Define BoolOptions +typedef struct +{ + PyObject_HEAD + SPAboxing_options *_acis_obj; +} a3dp_SPAboxing_options; + extern PyTypeObject a3dp_type_SPAposition; extern PyTypeObject a3dp_type_SPAvector; extern PyTypeObject a3dp_type_SPAunit_vector; @@ -107,6 +114,7 @@ extern PyTypeObject a3dp_type_FileInfo; extern PyTypeObject a3dp_type_sweep_options; extern PyTypeObject a3dp_type_make_sweep_path_options; extern PyTypeObject a3dp_type_BoolOptions; +extern PyTypeObject a3dp_type_SPAboxing_options; #ifdef __cplusplus extern "C" { @@ -144,6 +152,9 @@ bool _PyCheck_make_sweep_path_options(PyObject *ob); PyObject *_PyNew_BoolOptions(); bool _PyCheck_BoolOptions(PyObject *ob); +PyObject *_PyNew_SPAboxing_options(); +bool _PyCheck_SPAboxing_options(PyObject *ob); + #ifdef __cplusplus } #endif diff --git a/src/acis_includes.h b/src/acis_includes.h index a86d2b9..d2e7e9b 100644 --- a/src/acis_includes.h +++ b/src/acis_includes.h @@ -32,6 +32,7 @@ #include #include #include +#include #endif // !A3DPY_INCLUDES_H diff --git a/src/acis_modeler.cpp b/src/acis_modeler.cpp index ddee8e4..4d3ff5e 100644 --- a/src/acis_modeler.cpp +++ b/src/acis_modeler.cpp @@ -319,5 +319,11 @@ PyInit_Modeler(void) Py_INCREF(&a3dp_type_BoolOptions); PyModule_AddObject(m, "BoolOptions", (PyObject *) &a3dp_type_BoolOptions); + // SPAboxing_options + if (PyType_Ready(&a3dp_type_SPAboxing_options) < 0) + return NULL; + Py_INCREF(&a3dp_type_SPAboxing_options); + PyModule_AddObject(m, "SPAboxing_options", (PyObject *) &a3dp_type_SPAboxing_options); + return m; } From 99a13515d46b680360acdb08d100422dd6e60c37 Mon Sep 17 00:00:00 2001 From: "Onur R. Bingol" Date: Sun, 17 Dec 2017 22:25:07 -0600 Subject: [PATCH 14/18] Add api_get_entity_box API wrapper --- src/acis_api.cpp | 68 ++++++++++++++++++++++++++++++++++++++++++++ src/acis_api.h | 1 + src/acis_includes.h | 1 + src/acis_modeler.cpp | 1 + 4 files changed, 71 insertions(+) diff --git a/src/acis_api.cpp b/src/acis_api.cpp index 91a4f6c..f91f11e 100644 --- a/src/acis_api.cpp +++ b/src/acis_api.cpp @@ -1770,3 +1770,71 @@ a3dp_api_get_entity_id(PyObject *self, PyObject *args, PyObject *kwargs) else return PyLong_FromLong((long) _id); } + +PyObject * +a3dp_api_get_entity_box(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *input_ent = NULL; + PyObject *input_max_pt = NULL, *input_min_pt = NULL; + PyObject *input_box_options = NULL; + + // List of keyword arguments that this function can take + char *kwlist[] = + { + (char *) "entity", + (char *) "min_pt", + (char *) "max_pt", + (char *) "box_options", + NULL + }; + + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOO|O", kwlist, &input_ent, &input_min_pt, &input_max_pt, &input_box_options)) + return NULL; + + if (!_PyCheck_ENTITY(input_ent)) + { + PyErr_SetString(PyExc_TypeError, "Expecting an ENTITY object"); + return NULL; + } + + if (!_PyCheck_SPAposition(input_max_pt)) + { + PyErr_SetString(PyExc_TypeError, "max_pt should be a SPAposition object"); + return NULL; + } + + if (!_PyCheck_SPAposition(input_min_pt)) + { + PyErr_SetString(PyExc_TypeError, "min_pt should be a SPAposition object"); + return NULL; + } + + if (input_box_options != NULL) + { + if (!_PyCheck_SPAboxing_options(input_box_options)) + { + PyErr_SetString(PyExc_TypeError, "boxing_options should be a SPAboxing_options object"); + return NULL; + } + } + + API_BEGIN + + SPAposition &_min_pt = *((a3dp_SPAposition *) input_min_pt)->_acis_obj; + SPAposition &_max_pt = *((a3dp_SPAposition *) input_max_pt)->_acis_obj; + SPAboxing_options *_box_opts = NULL; + if (input_box_options) + _box_opts = ((a3dp_SPAboxing_options *) input_box_options)->_acis_obj; + ENTITY * _ent = ((a3dp_ENTITY *) input_ent)->_acis_obj; + // Execute ENTITY overload + result = api_get_entity_box(_ent, _min_pt, _min_pt, _box_opts); + + API_END + + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; +} diff --git a/src/acis_api.h b/src/acis_api.h index 74eea6a..5a4964d 100644 --- a/src/acis_api.h +++ b/src/acis_api.h @@ -59,6 +59,7 @@ PyObject *a3dp_api_logging(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_body_to_1d(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_body_to_2d(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_get_entity_id(PyObject *self, PyObject *args, PyObject *kwargs); +PyObject *a3dp_api_get_entity_box(PyObject *self, PyObject *args, PyObject *kwargs); #ifdef __cplusplus } diff --git a/src/acis_includes.h b/src/acis_includes.h index d2e7e9b..a88c1fd 100644 --- a/src/acis_includes.h +++ b/src/acis_includes.h @@ -33,6 +33,7 @@ #include #include #include +#include #endif // !A3DPY_INCLUDES_H diff --git a/src/acis_modeler.cpp b/src/acis_modeler.cpp index 4d3ff5e..1fdc8aa 100644 --- a/src/acis_modeler.cpp +++ b/src/acis_modeler.cpp @@ -65,6 +65,7 @@ static PyMethodDef { "api_body_to_1d", (PyCFunction) a3dp_api_body_to_1d, METH_VARARGS | METH_KEYWORDS, "Converts a double-sided body to a single-sided body" }, { "api_body_to_2d", (PyCFunction) a3dp_api_body_to_2d, METH_VARARGS | METH_KEYWORDS, "Converts single-sided faces to double-sided faces" }, { "api_get_entity_id", (PyCFunction) a3dp_api_get_entity_id, METH_VARARGS | METH_KEYWORDS, "Returns a unique integer identifier for a given ENTITY" }, + { "api_get_entity_box", (PyCFunction) a3dp_api_get_entity_box, METH_VARARGS | METH_KEYWORDS, "Computes a bounding box containing the entity" }, { NULL, NULL, 0, NULL } }; From 9225f3b07eaac518ab079ae5eb80bbc528d6d871 Mon Sep 17 00:00:00 2001 From: "Onur R. Bingol" Date: Sun, 17 Dec 2017 22:44:19 -0600 Subject: [PATCH 15/18] Add api_get_loops and api_closed_wire wrappers --- src/acis_api.cpp | 97 ++++++++++++++++++++++++++++++++++++++++++++ src/acis_api.h | 2 + src/acis_modeler.cpp | 4 +- 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/src/acis_api.cpp b/src/acis_api.cpp index f91f11e..ecb947e 100644 --- a/src/acis_api.cpp +++ b/src/acis_api.cpp @@ -1611,6 +1611,53 @@ a3dp_api_get_edges(PyObject *self, PyObject *args, PyObject *kwargs) } +PyObject * +a3dp_api_get_loops(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *input_ent = NULL, *input_ent_list = NULL; + + // List of keyword arguments that this function can take + char *kwlist[] = + { + (char *) "ent", + (char *) "loop_list", + NULL + }; + + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist, &input_ent, &input_ent_list)) + return NULL; + + if (!_PyCheck_ENTITY(input_ent)) + { + PyErr_SetString(PyExc_TypeError, "Expecting ENTITY object"); + return NULL; + } + + if (!_PyCheck_ENTITY_LIST(input_ent_list)) + { + PyErr_SetString(PyExc_TypeError, "Expecting ENTITY_LIST object"); + return NULL; + } + + API_BEGIN + + // Get the ACIS objects from the user input + ENTITY * _ent = ((a3dp_ENTITY *) input_ent)->_acis_obj; + ENTITY_LIST &_face_list = *((a3dp_ENTITY_LIST *) input_ent_list)->_acis_obj; + + // Call ACIS function + result = api_get_loops(_ent, _face_list); + + API_END + + // Check outcome + if (!check_outcome(result)) + return NULL; + else + Py_RETURN_NONE; +} + PyObject * a3dp_api_logging(PyObject *self, PyObject *args, PyObject *kwargs) { @@ -1838,3 +1885,53 @@ a3dp_api_get_entity_box(PyObject *self, PyObject *args, PyObject *kwargs) else Py_RETURN_NONE; } + +PyObject * +a3dp_api_closed_wire(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *input_body = NULL; + + // List of keyword arguments that this function can take + char *kwlist[] = + { + (char *) "wire_body", + NULL + }; + + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &input_body)) + return NULL; + + bool wire_obj = false; + if (!_PyCheck_BODY(input_body)) + { + if (!_PyCheck_WIRE(input_body)) + { + PyErr_SetString(PyExc_TypeError, "Expecting a WIRE or BODY object"); + return NULL; + } + wire_obj = true; + } + + API_BEGIN + + if (wire_obj) + { + // Execute WIRE overload + WIRE * _body = (WIRE *)((a3dp_WIRE *) input_body)->base_obj._acis_obj; + result = api_closed_wire(_body); + } + else + { + // Execute BODY overload + BODY * _body = (BODY *)((a3dp_BODY *) input_body)->base_obj._acis_obj; + result = api_closed_wire(_body); + } + + API_END + + // Check outcome + if (result.ok()) + Py_RETURN_TRUE; + Py_RETURN_FALSE; +} diff --git a/src/acis_api.h b/src/acis_api.h index 5a4964d..5bf6a0f 100644 --- a/src/acis_api.h +++ b/src/acis_api.h @@ -55,11 +55,13 @@ PyObject *a3dp_api_make_sweep_path(PyObject *self, PyObject *args, PyObject *kwa PyObject *a3dp_api_sweep_with_options(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_get_faces(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_get_edges(PyObject *self, PyObject *args, PyObject *kwargs); +PyObject *a3dp_api_get_loops(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_logging(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_body_to_1d(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_body_to_2d(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_get_entity_id(PyObject *self, PyObject *args, PyObject *kwargs); PyObject *a3dp_api_get_entity_box(PyObject *self, PyObject *args, PyObject *kwargs); +PyObject *a3dp_api_closed_wire(PyObject *self, PyObject *args, PyObject *kwargs); #ifdef __cplusplus } diff --git a/src/acis_modeler.cpp b/src/acis_modeler.cpp index 1fdc8aa..7330018 100644 --- a/src/acis_modeler.cpp +++ b/src/acis_modeler.cpp @@ -40,7 +40,8 @@ static PyMethodDef { "api_sweep_with_options", (PyCFunction) a3dp_api_sweep_with_options, METH_VARARGS | METH_KEYWORDS, "Sweeps the given profile along an edge, a distance, a vector or an axis" }, { "get_owner_transf", (PyCFunction) a3dp_get_owner_transf, METH_VARARGS | METH_KEYWORDS, "Gets a copy of the SPAtransf from the owner of an ENTITY" }, { "api_get_faces", (PyCFunction) a3dp_api_get_faces, METH_VARARGS | METH_KEYWORDS, "Gets all faces related to an entity" }, - { "api_get_edges", (PyCFunction) a3dp_api_get_edges, METH_VARARGS | METH_KEYWORDS, "Gets all the edges related to an entity" }, + { "api_get_edges", (PyCFunction) a3dp_api_get_edges, METH_VARARGS | METH_KEYWORDS, "Gets all edges related to an entity" }, + { "api_get_loops", (PyCFunction) a3dp_api_get_loops, METH_VARARGS | METH_KEYWORDS, "Gets all loops related to an entity" }, { "coordinate_transf", (PyCFunction) a3dp_coordinate_transf, METH_VARARGS | METH_KEYWORDS, "Constructs a coordinate transformation" }, { "make_transf", (PyCFunction) a3dp_make_transf, METH_VARARGS | METH_KEYWORDS, "Constructs a transformation retrieving the needed information from the provided transformation matrix and the scaling vector" }, { "reflect_transf", (PyCFunction) a3dp_reflect_transf, METH_VARARGS | METH_KEYWORDS, "Constructs a transformation corresponding to a reflection through a plane, specified by its normal" }, @@ -66,6 +67,7 @@ static PyMethodDef { "api_body_to_2d", (PyCFunction) a3dp_api_body_to_2d, METH_VARARGS | METH_KEYWORDS, "Converts single-sided faces to double-sided faces" }, { "api_get_entity_id", (PyCFunction) a3dp_api_get_entity_id, METH_VARARGS | METH_KEYWORDS, "Returns a unique integer identifier for a given ENTITY" }, { "api_get_entity_box", (PyCFunction) a3dp_api_get_entity_box, METH_VARARGS | METH_KEYWORDS, "Computes a bounding box containing the entity" }, + { "api_closed_wire", (PyCFunction) a3dp_api_closed_wire, METH_VARARGS | METH_KEYWORDS, "Determines if a wire or a single-wire body is closed" }, { NULL, NULL, 0, NULL } }; From 76972462386b7484ef3a6bbe36bb3224fcca464a Mon Sep 17 00:00:00 2001 From: "Onur R. Bingol" Date: Sun, 17 Dec 2017 22:45:04 -0600 Subject: [PATCH 16/18] Update function reference --- FUNCTION_REFERENCE.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/FUNCTION_REFERENCE.md b/FUNCTION_REFERENCE.md index 86ce8d0..ca9178c 100644 --- a/FUNCTION_REFERENCE.md +++ b/FUNCTION_REFERENCE.md @@ -44,7 +44,9 @@ * get_owner_transf * api_get_faces * api_get_edges +* api_get_loops * api_save_entity_list +* api_restore_entity_list * api_set_file_info * api_get_file_info * api_save_version @@ -55,7 +57,12 @@ * api_boolean_chop_body * api_make_sweep_path * api_sweep_with_options - +* api_logging +* api_get_entity_id +* api_body_to_1d +* api_body_to_2d +* api_get_entity_box (ENTITY overload) +* api_closed_wire ## Classes @@ -86,6 +93,8 @@ * FileInfo * sweep_options * make_sweep_path_options +* BoolOptions +* SPAboxing_options ## Enums From 2a4128382ea99495ebeaf697507f4d90e8d914e1 Mon Sep 17 00:00:00 2001 From: "Onur R. Bingol" Date: Sun, 17 Dec 2017 22:49:29 -0600 Subject: [PATCH 17/18] Add template for get_face_box wrapper --- FUNCTION_REFERENCE.md | 1 + src/acis_api2.cpp | 6 ++++++ src/acis_api2.h | 1 + src/acis_includes.h | 1 + src/acis_modeler.cpp | 1 + 5 files changed, 10 insertions(+) diff --git a/FUNCTION_REFERENCE.md b/FUNCTION_REFERENCE.md index ca9178c..db5557e 100644 --- a/FUNCTION_REFERENCE.md +++ b/FUNCTION_REFERENCE.md @@ -63,6 +63,7 @@ * api_body_to_2d * api_get_entity_box (ENTITY overload) * api_closed_wire +* get_face_box ## Classes diff --git a/src/acis_api2.cpp b/src/acis_api2.cpp index a5ef5e1..48bcbbf 100644 --- a/src/acis_api2.cpp +++ b/src/acis_api2.cpp @@ -75,3 +75,9 @@ a3dp_get_owner_transf(PyObject *self, PyObject *args, PyObject *kwargs) // Return SPAtransf python object return retobj; } + +PyObject * +a3dp_get_face_box(PyObject *self, PyObject *args, PyObject *kwargs) +{ + return NULL; +} diff --git a/src/acis_api2.h b/src/acis_api2.h index fb816fb..9d91187 100644 --- a/src/acis_api2.h +++ b/src/acis_api2.h @@ -29,6 +29,7 @@ extern "C" { PyObject *a3dp_is_modeler_started(PyObject *self); PyObject *a3dp_spa_unlock_products(PyObject *self, PyObject *arg); PyObject *a3dp_get_owner_transf(PyObject *self, PyObject *args, PyObject *kwargs); +PyObject *a3dp_get_face_box(PyObject *self, PyObject *args, PyObject *kwargs); #ifdef __cplusplus } diff --git a/src/acis_includes.h b/src/acis_includes.h index a88c1fd..cee39a7 100644 --- a/src/acis_includes.h +++ b/src/acis_includes.h @@ -34,6 +34,7 @@ #include #include #include +#include #endif // !A3DPY_INCLUDES_H diff --git a/src/acis_modeler.cpp b/src/acis_modeler.cpp index 7330018..2d6d2e0 100644 --- a/src/acis_modeler.cpp +++ b/src/acis_modeler.cpp @@ -68,6 +68,7 @@ static PyMethodDef { "api_get_entity_id", (PyCFunction) a3dp_api_get_entity_id, METH_VARARGS | METH_KEYWORDS, "Returns a unique integer identifier for a given ENTITY" }, { "api_get_entity_box", (PyCFunction) a3dp_api_get_entity_box, METH_VARARGS | METH_KEYWORDS, "Computes a bounding box containing the entity" }, { "api_closed_wire", (PyCFunction) a3dp_api_closed_wire, METH_VARARGS | METH_KEYWORDS, "Determines if a wire or a single-wire body is closed" }, + { "get_face_box", (PyCFunction) a3dp_get_face_box, METH_VARARGS | METH_KEYWORDS, "Returns the bounding box for the given face" }, { NULL, NULL, 0, NULL } }; From 6a95b2187ed3c19f14a457362fe7c09de09ada89 Mon Sep 17 00:00:00 2001 From: "Onur R. Bingol" Date: Mon, 18 Dec 2017 01:16:28 -0600 Subject: [PATCH 18/18] Fix example 2 after module reorganization --- examples/02_boolean_subtract.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/02_boolean_subtract.py b/examples/02_boolean_subtract.py index fec05bc..7ce70ec 100644 --- a/examples/02_boolean_subtract.py +++ b/examples/02_boolean_subtract.py @@ -38,7 +38,7 @@ Modeler.api_apply_transf(cylinder, cylinder_transf) # Subtract frustum from cuboid -Booleans.api_subtract(cylinder, block) +Modeler.api_subtract(cylinder, block) # Assign attributes after generation block.name = "Drilled Cuboid"