diff --git a/.gitignore b/.gitignore index e3e275b..a0f6a4a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ # Ignore everything in the build directory except .gitkeep build/* !build/.gitkeep + +# Ignore all txt files in the examples directory +examples/*.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 7876bf2..2905e23 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,13 @@ cmake_minimum_required( VERSION 2.8 ) project( ACIS_Py3Module CXX ) +# +# Application Configuration +# + +# Set Python version +set( APP_PYTHON_VERSION 3.5 ) + # # CMake setup and quick fixes # @@ -80,7 +87,7 @@ endif() # # Find Python libs -find_package( PythonLibs 3.5 REQUIRED ) +find_package( PythonLibs ${APP_PYTHON_VERSION} REQUIRED ) if( PythonLibs_FOUND ) include_directories( ${PYTHON_INCLUDE_DIRS} ) else() @@ -159,7 +166,7 @@ generate_export_header( Entity ) # Set link targets -target_link_libraries( Entity ${ACIS_LINK_LIBRARIES} ${PYTHON_LIBRARIES} ) +target_link_libraries( Entity ${ACIS_LINK_LIBRARIES} ${PYTHON_LIBRARIES} GeometricAtoms ) # Add the build location to the include directories target_include_directories( Entity PUBLIC ${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR} ) @@ -358,6 +365,51 @@ endif() set_target_properties( Sweeping PROPERTIES PREFIX "" ) +# +# ACIS Python Module - Booleans API +# + +# Set source files +set( ACIS_SOURCES_Booleans + src/acis_booleans.h + src/acis_booleans.cpp + src/utilities.cpp + src/utilities.h + ${PROJECT_BINARY_DIR}/acis_booleans_export.h + ) + +# Generate Python module +add_library( Booleans SHARED ${ACIS_SOURCES_Booleans} ) + +# Generate export header file +generate_export_header( Booleans + BASE_NAME acis_booleans + ) + +# Set link targets +target_link_libraries( Booleans ${ACIS_LINK_LIBRARIES} ${PYTHON_LIBRARIES} Entity ) + +# Add the build location to the include directories +target_include_directories( Booleans PUBLIC ${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR} ) + +# Set required C++ standard +set_property( TARGET Booleans PROPERTY CXX_STANDARD 11 ) +set_property( TARGET Booleans PROPERTY CXX_STANDARD_REQUIRED ON ) + +# Add suffix to debug builds +if( WIN32 ) + set_target_properties( Booleans PROPERTIES DEBUG_POSTFIX "_d" ) +endif() + +# On Windows, Python modules have .pyd filename extension +if( WIN32 AND NOT CYGWIN ) + set_target_properties( Booleans PROPERTIES SUFFIX ".pyd" ) +endif() + +# This is only needed for the python case where a modulename.so is generated +set_target_properties( Booleans PROPERTIES PREFIX "" ) + + # # ACIS Python Module - Query API # @@ -448,7 +500,13 @@ set_target_properties( Modeler PROPERTIES PREFIX "" ) # Install Python modules to APP_INSTALL_DIR install( - TARGETS Modeler Licensing Entity Lists SaveRestore GeometricAtoms Sweeping Query + TARGETS Modeler Licensing Entity Lists SaveRestore GeometricAtoms Sweeping Query Booleans + DESTINATION ${APP_INSTALL_DIR}/${APP_MODULE_NAME} +) + +# Install helper modules +install( + DIRECTORY python/ DESTINATION ${APP_INSTALL_DIR}/${APP_MODULE_NAME} ) diff --git a/FUNCTION_REFERENCE.md b/FUNCTION_REFERENCE.md index 5a75bff..07841b3 100644 --- a/FUNCTION_REFERENCE.md +++ b/FUNCTION_REFERENCE.md @@ -21,12 +21,7 @@ * api_make_torus * api_apply_transf * api_remove_transf -* api_unite -* api_intersect -* api_subtract -* api_imprint * api_sheet_from_ff -* api_boolean_chop_body ## Entity @@ -58,6 +53,8 @@ * SPAmatrix * SPAvector * SPAunit_vector +* SPApar_pos +* SPApar_vec ### Functions @@ -127,3 +124,17 @@ ### Functions * spa_unlock_products + +## Booleans + +### Enums + +* NDBOOL_KEEP + +### Functions + +* api_unite +* api_intersect +* api_subtract +* api_imprint +* api_boolean_chop_body diff --git a/README.md b/README.md index 3dc3f02..6daebdf 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ I would be glad if you cite this repository using the DOI provided as a badge at ## Introduction -This package wraps Spatial Corporation's 3D ACIS Modeler into a Python (v3.5.x) module with minor changes due to how Python's C interface works. _3D ACIS Modeler_ or _ACIS_, in short, is a [solid and geometric modeling kernel](https://en.wikipedia.org/wiki/Geometric_modeling_kernel). Solid modeling kernels are sometimes called as "CAD Engines" too. These systems work behind the scenes and responsible for generation of solid models or surfaces, evaluation of geometric operations on solid models or surfaces, and so. +This package wraps Spatial Corporation's 3D ACIS Modeler into a Python (v3.5.x and v3.6.x) module with minor changes due to how Python's C interface works. _3D ACIS Modeler_ or _ACIS_, in short, is a [solid and geometric modeling kernel](https://en.wikipedia.org/wiki/Geometric_modeling_kernel). Solid modeling kernels are sometimes called as "CAD Engines" too. These systems work behind the scenes and responsible for generation of solid models or surfaces, evaluation of geometric operations on solid models or surfaces, and so. _3D ACIS Modeler_ provides a C++ API and its Scheme extension with variety of additional features. Even though it is used in a variety of commercial and research applications, it doesn't provide a Python interface which would be very useful for integration purposes. This module tries to fulfill the gap up to some point. diff --git a/cmake-modules b/cmake-modules index 2fbdd5b..9205a87 160000 --- a/cmake-modules +++ b/cmake-modules @@ -1 +1 @@ -Subproject commit 2fbdd5bd6d9d9008318d6fc1d0f74f8019021bd6 +Subproject commit 9205a87850f3005dbf511bbd1a6fc0dc863d1267 diff --git a/examples/01_generate_solid_block.py b/examples/01_generate_solid_block.py index ddd10e3..a4d2b3f 100644 --- a/examples/01_generate_solid_block.py +++ b/examples/01_generate_solid_block.py @@ -7,13 +7,14 @@ Please see the LICENSE file for details. """ +from ACIS import utilities as utils from ACIS import Modeler, Licensing, SaveRestore, Entity, Lists, GeometricAtoms # Start ACIS Modeler Modeler.api_start_modeller(0) # Unlock ACIS Modeler components -unlock_key = "Your ACIS Unlock Key here" +unlock_key = utils.read_spa_license_key("license.txt") Licensing.spa_unlock_products(unlock_key) # Generate a simple solid block diff --git a/examples/02_boolean_subtract.py b/examples/02_boolean_subtract.py index f26b287..c1fa636 100644 --- a/examples/02_boolean_subtract.py +++ b/examples/02_boolean_subtract.py @@ -9,13 +9,14 @@ # This example is taken from the book "Rapid Prototyping and Engineering Applications" by Frank W. Liou (Example 5.1) -from ACIS import Modeler, Licensing, SaveRestore, Entity, Lists, GeometricAtoms +from ACIS import utilities as utils +from ACIS import Modeler, Licensing, SaveRestore, Entity, Lists, GeometricAtoms, Booleans # Start ACIS Modeler Modeler.api_start_modeller(0) # Unlock ACIS Modeler components -unlock_key = "Your ACIS Unlock Key here" +unlock_key = utils.read_spa_license_key("license.txt") Licensing.spa_unlock_products(unlock_key) # Make a cuboid @@ -37,7 +38,7 @@ Modeler.api_apply_transf(cylinder, cylinder_transf) # Subtract frustum from cuboid -Modeler.api_subtract(cylinder, block) +Booleans.api_subtract(cylinder, block) # Assign attributes after generation block.name = "Drilled Cuboid" diff --git a/examples/03_sweeping.py b/examples/03_sweeping.py index fbc8ec6..3664f14 100644 --- a/examples/03_sweeping.py +++ b/examples/03_sweeping.py @@ -7,13 +7,14 @@ Please see the LICENSE file for details. """ +from ACIS import utilities as utils from ACIS import Modeler, Licensing, SaveRestore, Entity, Lists, GeometricAtoms, Sweeping, Query # Start ACIS Modeler Modeler.api_start_modeller(0) # Unlock ACIS Modeler components -unlock_key = "Your ACIS Unlock Key here" +unlock_key = utils.read_spa_license_key("license.txt") Licensing.spa_unlock_products(unlock_key) # Make a cuboid diff --git a/examples/04_face_counting.py b/examples/04_face_counting.py new file mode 100644 index 0000000..8f4dec6 --- /dev/null +++ b/examples/04_face_counting.py @@ -0,0 +1,57 @@ +""" + Examples for the 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. +""" + +from ACIS import utilities as utils +from ACIS import Modeler, Licensing, SaveRestore, Entity, Lists, GeometricAtoms, Query + +# Start ACIS Modeler +Modeler.api_start_modeller(0) + +# Unlock ACIS Modeler components +unlock_key = utils.read_spa_license_key("license.txt") +Licensing.spa_unlock_products(unlock_key) + +# Generate a truncated cone +frustum = Entity.BODY() +Modeler.api_make_frustum(50, 20, 30, 10, frustum) + +# Assign attributes after generation +frustum.name = "Truncated Cone" +frustum.id = 1 + +# Loop through the face list and print out the name of the entity type +face_list = Lists.ENTITY_LIST() +Query.api_get_faces(frustum, face_list) + +for f in face_list.array(): + fs = f.geometry() + print(fs.type_name()) + +# Prepare for saving +save_list = Lists.ENTITY_LIST() +save_list.add(frustum) + +# Set file name +filename = "ACIS_Ex04.SAT" + +# ACIS requires FileInfo object to be set before saving SAT files +file_info = SaveRestore.FileInfo() +file_info.set_product_id(filename) +file_info.set_units(1.0) # milimeters + +SaveRestore.api_set_file_info(file_info, product_id=True, units=True) + +## Enable sequence numbers (i.e., pointers) in the SAT file for debugging (optional step) +#Modeler.api_set_int_option("sequence_save_files", 1) + +# Save the model as a SAT file +SaveRestore.api_save_entity_list(filename, True, save_list) + +# Stop ACIS Modeler +Modeler.api_stop_modeller() diff --git a/python/utilities.py b/python/utilities.py new file mode 100644 index 0000000..3bb1a89 --- /dev/null +++ b/python/utilities.py @@ -0,0 +1,33 @@ +""" + Helper Functions for the 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. +""" + +import re + + +def read_spa_license_key(filename=''): + regex_seq = re.compile(r'\s?\"(.*)\"') + + license_text = "" + search_obj = None + + try: + with open(filename, 'r') as fp: + license_code = fp.read() + search_obj = regex_seq.finditer(license_code.strip()) + fp.close() + except IOError: + raise IOError('Cannot open file: ' + filename) + + if search_obj: + for line in search_obj: + license_text = license_text + line.group(1) + else: + raise ValueError('The file "' + filename + '" does not contain the unlock key!') + + return license_text diff --git a/src/acis_booleans.cpp b/src/acis_booleans.cpp new file mode 100644 index 0000000..930c3d8 --- /dev/null +++ b/src/acis_booleans.cpp @@ -0,0 +1,333 @@ +#include "acis_booleans.h" + + +/** + * NDBOOL_KEEP enum + */ + +static PyTypeObject + ACIS_Booleans_type_NDBOOL_KEEP = + { + PyVarObject_HEAD_INIT(NULL, 0) + "ACIS.NDBOOL_KEEP", /* tp_name */ + sizeof(ACIS_Booleans_NDBOOL_KEEP), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* 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 */ + "For a non-destructive Boolean operation, this optional flag may be used to specify the preservation of either or both input bodies", /* tp_doc */ + }; + + +/** + * Booleans API Interface Functions + */ + +static PyObject * +ACIS_api_unite(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *input_tool = NULL, *input_blank = NULL; + + // List of keyword arguments that this function can take + static 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; + + // Type checks for ACIS objects + if (!_ACIS_check_BODY(input_tool)) + { + PyErr_SetString(PyExc_TypeError, "Tool must be a BODY object"); + return NULL; + } + + if (!_ACIS_check_BODY(input_blank)) + { + PyErr_SetString(PyExc_TypeError, "Blank must be a BODY object"); + return NULL; + } + + API_BEGIN + + // Convert PyObject to ACIS objects + BODY *&_tool = (BODY *&) ((ACIS_Entity_BODY *) input_tool)->base_obj._acis_obj; + BODY *&_blank = (BODY *&) ((ACIS_Entity_BODY *) input_blank)->base_obj._acis_obj; + + // Call ACIS API + result = api_unite(_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 + _ACIS_make_null(input_tool); + // Returning none means that we have no errors + Py_RETURN_NONE; + } +} + +static PyObject * +ACIS_api_intersect(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *input_tool = NULL, *input_blank = NULL; + + // List of keyword arguments that this function can take + static 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; + + // Type checks for ACIS objects + if (!_ACIS_check_BODY(input_tool)) + { + PyErr_SetString(PyExc_TypeError, "Tool must be a BODY object"); + return NULL; + } + + if (!_ACIS_check_BODY(input_blank)) + { + PyErr_SetString(PyExc_TypeError, "Blank must be a BODY object"); + return NULL; + } + + API_BEGIN + + // Convert PyObject to ACIS objects + BODY *&_tool = (BODY *&) ((ACIS_Entity_BODY *) input_tool)->base_obj._acis_obj; + BODY *&_blank = (BODY *&) ((ACIS_Entity_BODY *) input_blank)->base_obj._acis_obj; + + // Call ACIS API + result = api_intersect(_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 + _ACIS_make_null(input_tool); + // Returning none means that we have no errors + Py_RETURN_NONE; + } +} + +static PyObject * +ACIS_api_subtract(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *input_tool = NULL, *input_blank = NULL; + + // List of keyword arguments that this function can take + static 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; + + // Type checks for ACIS objects + if (!_ACIS_check_BODY(input_tool)) + { + PyErr_SetString(PyExc_TypeError, "Tool must be a BODY object"); + return NULL; + } + + if (!_ACIS_check_BODY(input_blank)) + { + PyErr_SetString(PyExc_TypeError, "Blank must be a BODY object"); + return NULL; + } + + API_BEGIN + + // Convert PyObject to ACIS objects + BODY *&_tool = (BODY *&) ((ACIS_Entity_BODY *) input_tool)->base_obj._acis_obj; + BODY *&_blank = (BODY *&) ((ACIS_Entity_BODY *) input_blank)->base_obj._acis_obj; + + // Call ACIS API + 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 + _ACIS_make_null(input_tool); + // Returning none means that we have no errors + Py_RETURN_NONE; + } +} + +static PyObject * +ACIS_api_imprint(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *input_tool = NULL, *input_blank = NULL; + + // List of keyword arguments that this function can take + static 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; + + // Type checks for ACIS objects + if (!_ACIS_check_BODY(input_tool)) + { + PyErr_SetString(PyExc_TypeError, "Tool must be a BODY object"); + return NULL; + } + + if (!_ACIS_check_BODY(input_blank)) + { + PyErr_SetString(PyExc_TypeError, "Blank must be a BODY object"); + return NULL; + } + + API_BEGIN + + // Convert PyObject to ACIS objects + BODY *&_tool = (BODY *&) ((ACIS_Entity_BODY *) input_tool)->base_obj._acis_obj; + BODY *&_blank = (BODY *&) ((ACIS_Entity_BODY *) input_blank)->base_obj._acis_obj; + + // Call ACIS API + result = api_imprint(_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 + _ACIS_make_null(input_tool); + // Returning none means that we have no errors + Py_RETURN_NONE; + } +} + +static PyObject * +ACIS_api_boolean_chop_body(PyObject *self, PyObject *args, PyObject *kwargs) +{ + /* TO-DO: Implement api_boolean_chop_body */ + return NULL; +} + +static PyMethodDef + module_methods[] = + { + { "api_unite", (PyCFunction) ACIS_api_unite, METH_VARARGS | METH_KEYWORDS, "Executes a Boolean unite operation" }, + { "api_intersect", (PyCFunction) ACIS_api_intersect, METH_VARARGS | METH_KEYWORDS, "Executes a Boolean intersect operation on two bodies" }, + { "api_subtract", (PyCFunction) ACIS_api_subtract, METH_VARARGS | METH_KEYWORDS, "Executes a Boolean subtract operation" }, + { "api_imprint", (PyCFunction) ACIS_api_imprint, METH_VARARGS | METH_KEYWORDS, "Intersects two bodies and imprints the intersection graph on both bodies" }, + { "api_boolean_chop_body", (PyCFunction) ACIS_api_boolean_chop_body, METH_VARARGS | METH_KEYWORDS, "Executes simultaneous Boolean intersect and subtract operations on two bodies" }, + { NULL, NULL, 0, NULL } + }; + +// Module documentation can be accessible via __doc__ +const char *module_name = "Booleans"; +const char *module_documentation = "Contains 3D ACIS Modeler booleans API related classes and functions"; + +static struct PyModuleDef + ACIS_Booleans_module = + { + PyModuleDef_HEAD_INIT, + module_name, // name of the module + module_documentation, // module documentation, may be NULL + -1, // size of per-interpreter state of the module, or -1 if the module keeps state in global variables. + module_methods + }; + +PyMODINIT_FUNC +PyInit_Booleans(void) +{ + PyObject *m; + + m = PyModule_Create(&ACIS_Booleans_module); + if (m == NULL) + return NULL; + + // Create a dictionary object for NDBOOL_KEEP enum + PyObject *_ndbk_dict; + _ndbk_dict = PyDict_New(); + if (_ndbk_dict != NULL) + { + PyDict_SetItemString(_ndbk_dict, "NDBOOL_KEEP_NEITHER", PyLong_FromLong(0L)); + PyDict_SetItemString(_ndbk_dict, "NDBOOL_KEEP_TOOL", PyLong_FromLong(1L)); + PyDict_SetItemString(_ndbk_dict, "NDBOOL_KEEP_BLANK", PyLong_FromLong(2L)); + PyDict_SetItemString(_ndbk_dict, "NDBOOL_KEEP_BOTH", PyLong_FromLong(3L)); + } + + // sweep_bool_type + ACIS_Booleans_type_NDBOOL_KEEP.tp_dict = _ndbk_dict; + if (PyType_Ready(&ACIS_Booleans_type_NDBOOL_KEEP) < 0) + return NULL; + Py_INCREF(&ACIS_Booleans_type_NDBOOL_KEEP); + PyModule_AddObject(m, "NDBOOL_KEEP", (PyObject *) &ACIS_Booleans_type_NDBOOL_KEEP); + + return m; +} + +PyObject *_ACIS_new_NDBOOL_KEEP() +{ + return PyObject_CallObject((PyObject *) &ACIS_Booleans_type_NDBOOL_KEEP, NULL); +} + +bool _ACIS_check_NDBOOL_KEEP(PyObject *ob) +{ + return Py_TYPE(ob) == &ACIS_Booleans_type_NDBOOL_KEEP; +} \ No newline at end of file diff --git a/src/acis_booleans.h b/src/acis_booleans.h new file mode 100644 index 0000000..85520ca --- /dev/null +++ b/src/acis_booleans.h @@ -0,0 +1,36 @@ +/** + * + * 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 ACIS_BOOLEANS_H +#define ACIS_BOOLEANS_H + +#include +#include + +#include + +#include "acis_entity.h" +#include "acis_geometric_atoms.h" +#include "utilities.h" + +#include "acis_booleans_export.h" + +// Define NDBOOL_KEEP enum +typedef struct { + PyObject_HEAD +} ACIS_Booleans_NDBOOL_KEEP; + +PyObject ACIS_BOOLEANS_EXPORT *_ACIS_new_NDBOOL_KEEP(); + +bool ACIS_BOOLEANS_EXPORT _ACIS_check_NDBOOL_KEEP(PyObject *ob); + + +#endif // !ACIS_BOOLEANS_H diff --git a/src/acis_entity.cpp b/src/acis_entity.cpp index d7bb2a4..677e3cf 100644 --- a/src/acis_entity.cpp +++ b/src/acis_entity.cpp @@ -39,7 +39,7 @@ PyObject * ACIS_Entity_new_ENTITY(PyTypeObject *type, PyObject *args, PyObject *kwargs) { // First check if the modeler has been started - if(!is_modeler_started()) + if (!is_modeler_started()) { PyErr_SetString(PyExc_RuntimeError, "ACIS is not running!"); return NULL; @@ -131,8 +131,8 @@ PyObject * ACIS_Entity_repr_ENTITY(ACIS_Entity_ENTITY *self) { const char *_name = PyUnicode_AsUTF8(self->attrib_name); - int _id = (int)PyLong_AsLong(self->attrib_object_id); - return PyUnicode_FromFormat("ACIS ENTITY object with name '%s' and ID '%i'", _name, _id); + int _id = (int) PyLong_AsLong(self->attrib_object_id); + return PyUnicode_FromFormat("ENTITY object with name '%s' and ID '%i'", _name, _id); } PyObject * @@ -144,7 +144,7 @@ ACIS_Entity_str_ENTITY(ACIS_Entity_ENTITY *self) else acis_obj_status = "Valid"; - return PyUnicode_FromFormat("ACIS ENTITY object (%s)", acis_obj_status); + return PyUnicode_FromFormat("ENTITY object (%s)", acis_obj_status); } PyObject * @@ -187,6 +187,13 @@ ACIS_Entity_method_ENTITY_set_attrib_name(ACIS_Entity_ENTITY *self, PyObject *va return 0; } +PyObject * +ACIS_Entity_method_ENTITY_type_name(PyObject *self) +{ + const char *_retval = ((ACIS_Entity_ENTITY *)self)->_acis_obj->type_name(); + return PyUnicode_FromString(_retval); +} + PyObject * ACIS_Entity_method_ENTITY_get_attrib_obj_id(ACIS_Entity_ENTITY *self, PyObject *value, void *closure) { @@ -239,7 +246,7 @@ static int ACIS_Entity_init_BODY(ACIS_Entity_BODY *self, PyObject *args, PyObject *kwargs) { // Initialize the base class - if (ACIS_Entity_type_ENTITY.tp_init((PyObject *)self, args, kwargs) < 0) + if (ACIS_Entity_type_ENTITY.tp_init((PyObject *) self, args, kwargs) < 0) return -1; return 0; @@ -249,8 +256,8 @@ static PyObject * ACIS_Entity_repr_BODY(ACIS_Entity_BODY *self) { const char *_name = PyUnicode_AsUTF8(self->base_obj.attrib_name); - int _id = (int)PyLong_AsLong(self->base_obj.attrib_object_id); - return PyUnicode_FromFormat("ACIS BODY object with name '%s' and ID '%i'", _name, _id); + int _id = (int) PyLong_AsLong(self->base_obj.attrib_object_id); + return PyUnicode_FromFormat("BODY object with name '%s' and ID '%i'", _name, _id); } static PyObject * @@ -262,7 +269,7 @@ ACIS_Entity_str_BODY(ACIS_Entity_BODY *self) else acis_obj_status = "Valid"; - return PyUnicode_FromFormat("ACIS BODY object (%s)", acis_obj_status); + return PyUnicode_FromFormat("BODY object (%s)", acis_obj_status); } static PyGetSetDef @@ -335,7 +342,7 @@ static int ACIS_Entity_init_FACE(ACIS_Entity_FACE *self, PyObject *args, PyObject *kwargs) { // Initialize the base class - if (ACIS_Entity_type_ENTITY.tp_init((PyObject *)self, args, kwargs) < 0) + if (ACIS_Entity_type_ENTITY.tp_init((PyObject *) self, args, kwargs) < 0) return -1; return 0; @@ -345,8 +352,8 @@ static PyObject * ACIS_Entity_repr_FACE(ACIS_Entity_FACE *self) { const char *_name = PyUnicode_AsUTF8(self->base_obj.attrib_name); - int _id = (int)PyLong_AsLong(self->base_obj.attrib_object_id); - return PyUnicode_FromFormat("ACIS FACE object with name '%s' and ID '%i'", _name, _id); + int _id = (int) PyLong_AsLong(self->base_obj.attrib_object_id); + return PyUnicode_FromFormat("FACE object with name '%s' and ID '%i'", _name, _id); } static PyObject * @@ -358,7 +365,29 @@ ACIS_Entity_str_FACE(ACIS_Entity_FACE *self) else acis_obj_status = "Valid"; - return PyUnicode_FromFormat("ACIS FACE object (%s)", acis_obj_status); + return PyUnicode_FromFormat("FACE object (%s)", acis_obj_status); +} + +static PyObject * +ACIS_Entity_method_FACE_sense(ACIS_Entity_FACE *self) +{ + logical _revbit; + _revbit = ((FACE *) self->base_obj._acis_obj)->sense(); + + // If REVBIT is true or reversed, the directions are opposite (reversed) + if (_revbit) + Py_RETURN_TRUE; + // If REVBIT is false or forward, the directions are the same + Py_RETURN_FALSE; +} + +static PyObject * +ACIS_Entity_method_FACE_geometry(ACIS_Entity_FACE *self) +{ + PyObject *_retobj = _ACIS_new_SURFACE(); + // Store everything as ENTITY + ((ACIS_Entity_SURFACE *) _retobj)->base_obj._acis_obj = (ENTITY *) ((FACE *) self->base_obj._acis_obj)->geometry(); + return _retobj; } static PyGetSetDef @@ -376,6 +405,8 @@ static PyMemberDef static PyMethodDef ACIS_Entity_methods_FACE[] = { + { "sense", (PyCFunction) ACIS_Entity_method_FACE_sense, METH_NOARGS, "Returns the sense of this FACE relative to its SURFACE" }, + { "geometry", (PyCFunction) ACIS_Entity_method_FACE_geometry, METH_NOARGS, "Returns a pointer to the underlying SURFACE defining this FACE" }, { NULL } /* Sentinel */ }; @@ -431,7 +462,7 @@ static int ACIS_Entity_init_EDGE(ACIS_Entity_EDGE *self, PyObject *args, PyObject *kwargs) { // Initialize the base class - if (ACIS_Entity_type_ENTITY.tp_init((PyObject *)self, args, kwargs) < 0) + if (ACIS_Entity_type_ENTITY.tp_init((PyObject *) self, args, kwargs) < 0) return -1; return 0; @@ -441,8 +472,8 @@ static PyObject * ACIS_Entity_repr_EDGE(ACIS_Entity_EDGE *self) { const char *_name = PyUnicode_AsUTF8(self->base_obj.attrib_name); - int _id = (int)PyLong_AsLong(self->base_obj.attrib_object_id); - return PyUnicode_FromFormat("ACIS EDGE object with name '%s' and ID '%i'", _name, _id); + int _id = (int) PyLong_AsLong(self->base_obj.attrib_object_id); + return PyUnicode_FromFormat("EDGE object with name '%s' and ID '%i'", _name, _id); } static PyObject * @@ -454,7 +485,7 @@ ACIS_Entity_str_EDGE(ACIS_Entity_EDGE *self) else acis_obj_status = "Valid"; - return PyUnicode_FromFormat("ACIS EDGE object (%s)", acis_obj_status); + return PyUnicode_FromFormat("EDGE object (%s)", acis_obj_status); } static PyGetSetDef @@ -527,7 +558,7 @@ static int ACIS_Entity_init_WIRE(ACIS_Entity_WIRE *self, PyObject *args, PyObject *kwargs) { // Initialize the base class - if (ACIS_Entity_type_ENTITY.tp_init((PyObject *)self, args, kwargs) < 0) + if (ACIS_Entity_type_ENTITY.tp_init((PyObject *) self, args, kwargs) < 0) return -1; return 0; @@ -537,8 +568,8 @@ static PyObject * ACIS_Entity_repr_WIRE(ACIS_Entity_WIRE *self) { const char *_name = PyUnicode_AsUTF8(self->base_obj.attrib_name); - int _id = (int)PyLong_AsLong(self->base_obj.attrib_object_id); - return PyUnicode_FromFormat("ACIS WIRE object with name '%s' and ID '%i'", _name, _id); + int _id = (int) PyLong_AsLong(self->base_obj.attrib_object_id); + return PyUnicode_FromFormat("WIRE object with name '%s' and ID '%i'", _name, _id); } static PyObject * @@ -550,7 +581,7 @@ ACIS_Entity_str_WIRE(ACIS_Entity_WIRE *self) else acis_obj_status = "Valid"; - return PyUnicode_FromFormat("ACIS WIRE object (%s)", acis_obj_status); + return PyUnicode_FromFormat("WIRE object (%s)", acis_obj_status); } static PyGetSetDef @@ -623,7 +654,7 @@ static int ACIS_Entity_init_LUMP(ACIS_Entity_LUMP *self, PyObject *args, PyObject *kwargs) { // Initialize the base class - if (ACIS_Entity_type_ENTITY.tp_init((PyObject *)self, args, kwargs) < 0) + if (ACIS_Entity_type_ENTITY.tp_init((PyObject *) self, args, kwargs) < 0) return -1; return 0; @@ -633,8 +664,8 @@ static PyObject * ACIS_Entity_repr_LUMP(ACIS_Entity_LUMP *self) { const char *_name = PyUnicode_AsUTF8(self->base_obj.attrib_name); - int _id = (int)PyLong_AsLong(self->base_obj.attrib_object_id); - return PyUnicode_FromFormat("ACIS LUMP object with name '%s' and ID '%i'", _name, _id); + int _id = (int) PyLong_AsLong(self->base_obj.attrib_object_id); + return PyUnicode_FromFormat("LUMP object with name '%s' and ID '%i'", _name, _id); } static PyObject * @@ -646,7 +677,7 @@ ACIS_Entity_str_LUMP(ACIS_Entity_LUMP *self) else acis_obj_status = "Valid"; - return PyUnicode_FromFormat("ACIS LUMP object (%s)", acis_obj_status); + return PyUnicode_FromFormat("LUMP object (%s)", acis_obj_status); } static PyGetSetDef @@ -719,7 +750,7 @@ static int ACIS_Entity_init_SHELL(ACIS_Entity_SHELL *self, PyObject *args, PyObject *kwargs) { // Initialize the base class - if (ACIS_Entity_type_ENTITY.tp_init((PyObject *)self, args, kwargs) < 0) + if (ACIS_Entity_type_ENTITY.tp_init((PyObject *) self, args, kwargs) < 0) return -1; return 0; @@ -729,8 +760,8 @@ static PyObject * ACIS_Entity_repr_SHELL(ACIS_Entity_SHELL *self) { const char *_name = PyUnicode_AsUTF8(self->base_obj.attrib_name); - int _id = (int)PyLong_AsLong(self->base_obj.attrib_object_id); - return PyUnicode_FromFormat("ACIS SHELL object with name '%s' and ID '%i'", _name, _id); + int _id = (int) PyLong_AsLong(self->base_obj.attrib_object_id); + return PyUnicode_FromFormat("SHELL object with name '%s' and ID '%i'", _name, _id); } static PyObject * @@ -742,7 +773,7 @@ ACIS_Entity_str_SHELL(ACIS_Entity_SHELL *self) else acis_obj_status = "Valid"; - return PyUnicode_FromFormat("ACIS SHELL object (%s)", acis_obj_status); + return PyUnicode_FromFormat("SHELL object (%s)", acis_obj_status); } static PyGetSetDef @@ -815,7 +846,7 @@ static int ACIS_Entity_init_SUBSHELL(ACIS_Entity_SUBSHELL *self, PyObject *args, PyObject *kwargs) { // Initialize the base class - if (ACIS_Entity_type_ENTITY.tp_init((PyObject *)self, args, kwargs) < 0) + if (ACIS_Entity_type_ENTITY.tp_init((PyObject *) self, args, kwargs) < 0) return -1; return 0; @@ -825,8 +856,8 @@ static PyObject * ACIS_Entity_repr_SUBSHELL(ACIS_Entity_SUBSHELL *self) { const char *_name = PyUnicode_AsUTF8(self->base_obj.attrib_name); - int _id = (int)PyLong_AsLong(self->base_obj.attrib_object_id); - return PyUnicode_FromFormat("ACIS SUBSHELL object with name '%s' and ID '%i'", _name, _id); + int _id = (int) PyLong_AsLong(self->base_obj.attrib_object_id); + return PyUnicode_FromFormat("SUBSHELL object with name '%s' and ID '%i'", _name, _id); } static PyObject * @@ -838,7 +869,7 @@ ACIS_Entity_str_SUBSHELL(ACIS_Entity_SUBSHELL *self) else acis_obj_status = "Valid"; - return PyUnicode_FromFormat("ACIS SUBSHELL object (%s)", acis_obj_status); + return PyUnicode_FromFormat("SUBSHELL object (%s)", acis_obj_status); } static PyGetSetDef @@ -911,7 +942,7 @@ static int ACIS_Entity_init_COEDGE(ACIS_Entity_COEDGE *self, PyObject *args, PyObject *kwargs) { // Initialize the base class - if (ACIS_Entity_type_ENTITY.tp_init((PyObject *)self, args, kwargs) < 0) + if (ACIS_Entity_type_ENTITY.tp_init((PyObject *) self, args, kwargs) < 0) return -1; return 0; @@ -921,8 +952,8 @@ static PyObject * ACIS_Entity_repr_COEDGE(ACIS_Entity_COEDGE *self) { const char *_name = PyUnicode_AsUTF8(self->base_obj.attrib_name); - int _id = (int)PyLong_AsLong(self->base_obj.attrib_object_id); - return PyUnicode_FromFormat("ACIS COEDGE object with name '%s' and ID '%i'", _name, _id); + int _id = (int) PyLong_AsLong(self->base_obj.attrib_object_id); + return PyUnicode_FromFormat("COEDGE object with name '%s' and ID '%i'", _name, _id); } static PyObject * @@ -934,7 +965,7 @@ ACIS_Entity_str_COEDGE(ACIS_Entity_COEDGE *self) else acis_obj_status = "Valid"; - return PyUnicode_FromFormat("ACIS COEDGE object (%s)", acis_obj_status); + return PyUnicode_FromFormat("COEDGE object (%s)", acis_obj_status); } static PyGetSetDef @@ -1007,7 +1038,7 @@ static int ACIS_Entity_init_LOOP(ACIS_Entity_LOOP *self, PyObject *args, PyObject *kwargs) { // Initialize the base class - if (ACIS_Entity_type_ENTITY.tp_init((PyObject *)self, args, kwargs) < 0) + if (ACIS_Entity_type_ENTITY.tp_init((PyObject *) self, args, kwargs) < 0) return -1; return 0; @@ -1017,8 +1048,8 @@ static PyObject * ACIS_Entity_repr_LOOP(ACIS_Entity_LOOP *self) { const char *_name = PyUnicode_AsUTF8(self->base_obj.attrib_name); - int _id = (int)PyLong_AsLong(self->base_obj.attrib_object_id); - return PyUnicode_FromFormat("ACIS LOOP object with name '%s' and ID '%i'", _name, _id); + int _id = (int) PyLong_AsLong(self->base_obj.attrib_object_id); + return PyUnicode_FromFormat("LOOP object with name '%s' and ID '%i'", _name, _id); } static PyObject * @@ -1030,7 +1061,7 @@ ACIS_Entity_str_LOOP(ACIS_Entity_LOOP *self) else acis_obj_status = "Valid"; - return PyUnicode_FromFormat("ACIS LOOP object (%s)", acis_obj_status); + return PyUnicode_FromFormat("LOOP object (%s)", acis_obj_status); } static PyGetSetDef @@ -1103,7 +1134,7 @@ static int ACIS_Entity_init_VERTEX(ACIS_Entity_VERTEX *self, PyObject *args, PyObject *kwargs) { // Initialize the base class - if (ACIS_Entity_type_ENTITY.tp_init((PyObject *)self, args, kwargs) < 0) + if (ACIS_Entity_type_ENTITY.tp_init((PyObject *) self, args, kwargs) < 0) return -1; return 0; @@ -1113,8 +1144,8 @@ static PyObject * ACIS_Entity_repr_VERTEX(ACIS_Entity_VERTEX *self) { const char *_name = PyUnicode_AsUTF8(self->base_obj.attrib_name); - int _id = (int)PyLong_AsLong(self->base_obj.attrib_object_id); - return PyUnicode_FromFormat("ACIS VERTEX object with name '%s' and ID '%i'", _name, _id); + int _id = (int) PyLong_AsLong(self->base_obj.attrib_object_id); + return PyUnicode_FromFormat("VERTEX object with name '%s' and ID '%i'", _name, _id); } static PyObject * @@ -1126,7 +1157,7 @@ ACIS_Entity_str_VERTEX(ACIS_Entity_VERTEX *self) else acis_obj_status = "Valid"; - return PyUnicode_FromFormat("ACIS VERTEX object (%s)", acis_obj_status); + return PyUnicode_FromFormat("VERTEX object (%s)", acis_obj_status); } static PyGetSetDef @@ -1210,7 +1241,7 @@ ACIS_Entity_repr_SURFACE(ACIS_Entity_SURFACE *self) { const char *_name = PyUnicode_AsUTF8(self->base_obj.attrib_name); int _id = (int) PyLong_AsLong(self->base_obj.attrib_object_id); - return PyUnicode_FromFormat("ACIS SURFACE object with name '%s' and ID '%i'", _name, _id); + return PyUnicode_FromFormat("SURFACE object with name '%s' and ID '%i'", _name, _id); } static PyObject * @@ -1222,7 +1253,57 @@ ACIS_Entity_str_SURFACE(ACIS_Entity_SURFACE *self) else acis_obj_status = "Valid"; - return PyUnicode_FromFormat("ACIS SURFACE object (%s)", acis_obj_status); + return PyUnicode_FromFormat("SURFACE object (%s)", acis_obj_status); +} + +static PyObject * +ACIS_Entity_method_SURFACE_equation(ACIS_Entity_SURFACE *self) +{ + PyObject *_retobj = _ACIS_new_surface(); + *((ACIS_Entity_surface *) _retobj)->_acis_obj = ((SURFACE *)(self->base_obj._acis_obj))->equation(); + return _retobj; +} + +static PyObject * +ACIS_Entity_method_SURFACE_trans_surface(ACIS_Entity_SURFACE *self, PyObject *args, PyObject *kwargs) +{ + PyObject *input_t = NULL, *input_reverse = NULL; + + // List of keyword arguments that this function can take + static char *kwlist[] = + { + (char *) "t", + (char *) "reverse", + NULL + }; + + // Try to parse input arguments and/or keywords + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi", kwlist, &input_t, &input_reverse)) + return NULL; + + SPAtransf _t = *(SPAtransf *) NULL_REF; + if (input_t != NULL) + { + // Validate input + if (!_ACIS_check_SPAtransf(input_t)) + { + PyErr_SetString(PyExc_TypeError, "The first argument (t) must be a SPAtransf object"); + return NULL; + } + + _t = *((ACIS_GeometricAtoms_SPAtransf *) input_t)->_acis_obj; + } + + logical _reverse = FALSE; + if (input_reverse != NULL) + { + long _py_inp_reverse = PyLong_AsLong(input_reverse); + _reverse = (_py_inp_reverse == 0) ? FALSE : TRUE; + } + + PyObject *_retobj = _ACIS_new_surface(); + ((ACIS_Entity_surface *) _retobj)->_acis_obj = ((SURFACE *)(self->base_obj._acis_obj))->trans_surface(_t, _reverse); + return _retobj; } static PyGetSetDef @@ -1240,6 +1321,8 @@ static PyMemberDef static PyMethodDef ACIS_Entity_methods_SURFACE[] = { + { "equation", (PyCFunction) ACIS_Entity_method_SURFACE_equation, METH_NOARGS, "Returns the equation of this SURFACE" }, + { "trans_surface", (PyCFunction) ACIS_Entity_method_SURFACE_trans_surface, METH_VARARGS | METH_KEYWORDS, "Returns the transformed surface" }, { NULL } /* Sentinel */ }; @@ -1306,7 +1389,7 @@ ACIS_Entity_repr_CONE(ACIS_Entity_CONE *self) { const char *_name = PyUnicode_AsUTF8(self->base_obj.attrib_name); int _id = (int) PyLong_AsLong(self->base_obj.attrib_object_id); - return PyUnicode_FromFormat("ACIS CONE object with name '%s' and ID '%i'", _name, _id); + return PyUnicode_FromFormat("CONE object with name '%s' and ID '%i'", _name, _id); } static PyObject * @@ -1318,7 +1401,7 @@ ACIS_Entity_str_CONE(ACIS_Entity_CONE *self) else acis_obj_status = "Valid"; - return PyUnicode_FromFormat("ACIS CONE object (%s)", acis_obj_status); + return PyUnicode_FromFormat("CONE object (%s)", acis_obj_status); } static PyGetSetDef @@ -1402,7 +1485,7 @@ ACIS_Entity_repr_PLANE(ACIS_Entity_PLANE *self) { const char *_name = PyUnicode_AsUTF8(self->base_obj.attrib_name); int _id = (int) PyLong_AsLong(self->base_obj.attrib_object_id); - return PyUnicode_FromFormat("ACIS PLANE object with name '%s' and ID '%i'", _name, _id); + return PyUnicode_FromFormat("PLANE object with name '%s' and ID '%i'", _name, _id); } static PyObject * @@ -1414,7 +1497,7 @@ ACIS_Entity_str_PLANE(ACIS_Entity_PLANE *self) else acis_obj_status = "Valid"; - return PyUnicode_FromFormat("ACIS PLANE object (%s)", acis_obj_status); + return PyUnicode_FromFormat("PLANE object (%s)", acis_obj_status); } static PyGetSetDef @@ -1498,7 +1581,7 @@ ACIS_Entity_repr_SPHERE(ACIS_Entity_SPHERE *self) { const char *_name = PyUnicode_AsUTF8(self->base_obj.attrib_name); int _id = (int) PyLong_AsLong(self->base_obj.attrib_object_id); - return PyUnicode_FromFormat("ACIS SPHERE object with name '%s' and ID '%i'", _name, _id); + return PyUnicode_FromFormat("SPHERE object with name '%s' and ID '%i'", _name, _id); } static PyObject * @@ -1510,7 +1593,7 @@ ACIS_Entity_str_SPHERE(ACIS_Entity_SPHERE *self) else acis_obj_status = "Valid"; - return PyUnicode_FromFormat("ACIS SPHERE object (%s)", acis_obj_status); + return PyUnicode_FromFormat("SPHERE object (%s)", acis_obj_status); } static PyGetSetDef @@ -1594,7 +1677,7 @@ ACIS_Entity_repr_SPLINE(ACIS_Entity_SPLINE *self) { const char *_name = PyUnicode_AsUTF8(self->base_obj.attrib_name); int _id = (int) PyLong_AsLong(self->base_obj.attrib_object_id); - return PyUnicode_FromFormat("ACIS SPLINE object with name '%s' and ID '%i'", _name, _id); + return PyUnicode_FromFormat("SPLINE object with name '%s' and ID '%i'", _name, _id); } static PyObject * @@ -1606,7 +1689,7 @@ ACIS_Entity_str_SPLINE(ACIS_Entity_SPLINE *self) else acis_obj_status = "Valid"; - return PyUnicode_FromFormat("ACIS SPLINE object (%s)", acis_obj_status); + return PyUnicode_FromFormat("SPLINE object (%s)", acis_obj_status); } static PyGetSetDef @@ -1690,7 +1773,7 @@ ACIS_Entity_repr_TORUS(ACIS_Entity_TORUS *self) { const char *_name = PyUnicode_AsUTF8(self->base_obj.attrib_name); int _id = (int) PyLong_AsLong(self->base_obj.attrib_object_id); - return PyUnicode_FromFormat("ACIS TORUS object with name '%s' and ID '%i'", _name, _id); + return PyUnicode_FromFormat("TORUS object with name '%s' and ID '%i'", _name, _id); } static PyObject * @@ -1702,7 +1785,7 @@ ACIS_Entity_str_TORUS(ACIS_Entity_TORUS *self) else acis_obj_status = "Valid"; - return PyUnicode_FromFormat("ACIS TORUS object (%s)", acis_obj_status); + return PyUnicode_FromFormat("TORUS object (%s)", acis_obj_status); } static PyGetSetDef @@ -1767,6 +1850,154 @@ static PyTypeObject }; +/** + * 3D ACIS Modeler - surface wrapper + */ + +static void +ACIS_Entity_dealloc_surface(ACIS_Entity_surface *self) +{ + Py_TYPE(self)->tp_free((PyObject *) self); +} + +static PyObject * +ACIS_Entity_new_surface(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + // First check if the modeler has been started + if (!is_modeler_started()) + { + PyErr_SetString(PyExc_RuntimeError, "ACIS is not running!"); + return NULL; + } + + ACIS_Entity_surface *self; + + self = (ACIS_Entity_surface *) type->tp_alloc(type, 0); + if (self != NULL) + { + // Just getting rid of the dangling pointer + self->_acis_obj = NULL; + } + + return (PyObject *) self; +} + +static int +ACIS_Entity_init_surface(ACIS_Entity_surface *self, PyObject *args, PyObject *kwargs) +{ + return 0; +} + +static PyObject * +ACIS_Entity_method_surface_eval_normal(ACIS_Entity_surface *self, PyObject *arg) +{ + if (!_ACIS_check_SPApar_pos(arg)) + { + PyErr_SetString(PyExc_TypeError, "Expecting a SPApar_pos object"); + return NULL; + } + + Py_INCREF(arg); + + SPApar_pos *&_pos = ((ACIS_GeometricAtoms_SPApar_pos *) arg)->_acis_obj; + + SPAunit_vector _retval = self->_acis_obj->eval_normal(*_pos); + + PyObject *_retobj = _ACIS_new_SPAunit_vector(); + *((ACIS_GeometricAtoms_SPAunit_vector *) _retobj)->_acis_obj = _retval; + + Py_DECREF(arg); + + return _retobj; +} + +static PyObject * +ACIS_Entity_method_surface_eval_position(ACIS_Entity_surface *self, PyObject *arg) +{ + if (!_ACIS_check_SPApar_pos(arg)) + { + PyErr_SetString(PyExc_TypeError, "Expecting a SPApar_pos object"); + return NULL; + } + + Py_INCREF(arg); + + SPApar_pos *&_pos = ((ACIS_GeometricAtoms_SPApar_pos *) arg)->_acis_obj; + + SPAposition _retval = self->_acis_obj->eval_position(*_pos); + + PyObject *_retobj = _ACIS_new_SPAposition(); + *((ACIS_GeometricAtoms_SPAposition *) _retobj)->_acis_obj = _retval; + + Py_DECREF(arg); + + return _retobj; +} + +static PyGetSetDef + ACIS_Entity_getseters_surface[] = + { + { NULL } /* Sentinel */ + }; + +static PyMemberDef + ACIS_Entity_members_surface[] = + { + { NULL } /* Sentinel */ + }; + +static PyMethodDef + ACIS_Entity_methods_surface[] = + { + { "eval_normal", (PyCFunction) ACIS_Entity_method_surface_eval_normal, METH_O, "Finds the normal to a parametric surface at the point with the given parameter position" }, + { "eval_position", (PyCFunction) ACIS_Entity_method_surface_eval_position, METH_O, "Finds the point on a parametric surface with the given parameter position" }, + { NULL } /* Sentinel */ + }; + +static PyTypeObject + ACIS_Entity_type_surface = + { + PyVarObject_HEAD_INIT(NULL, 0) + "ACIS.surface", /* tp_name */ + sizeof(ACIS_Entity_surface), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor) ACIS_Entity_dealloc_surface, /* 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 */ + "ACIS surface class", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + ACIS_Entity_methods_surface, /* tp_methods */ + ACIS_Entity_members_surface, /* tp_members */ + ACIS_Entity_getseters_surface, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc) ACIS_Entity_init_surface, /* tp_init */ + 0, /* tp_alloc */ + ACIS_Entity_new_surface, /* tp_new */ + }; + + /* * Python Module Definitions */ @@ -1794,124 +2025,130 @@ PyInit_Entity(void) if (m == NULL) return NULL; - // Add ENTITY to the Topology module + // Add ENTITY to the module if (PyType_Ready(&ACIS_Entity_type_ENTITY) < 0) return NULL; Py_INCREF(&ACIS_Entity_type_ENTITY); PyModule_AddObject(m, "ENTITY", (PyObject *) &ACIS_Entity_type_ENTITY); - // Add BODY to the Topology module + // Add BODY to the module ACIS_Entity_type_BODY.tp_base = &ACIS_Entity_type_ENTITY; if (PyType_Ready(&ACIS_Entity_type_BODY) < 0) return NULL; Py_INCREF(&ACIS_Entity_type_BODY); PyModule_AddObject(m, "BODY", (PyObject *) &ACIS_Entity_type_BODY); - // Add FACE to the Topology module + // Add FACE to the module ACIS_Entity_type_FACE.tp_base = &ACIS_Entity_type_ENTITY; if (PyType_Ready(&ACIS_Entity_type_FACE) < 0) return NULL; Py_INCREF(&ACIS_Entity_type_FACE); PyModule_AddObject(m, "FACE", (PyObject *) &ACIS_Entity_type_FACE); - // Add EDGE to the Topology module + // Add EDGE to the module ACIS_Entity_type_EDGE.tp_base = &ACIS_Entity_type_ENTITY; if (PyType_Ready(&ACIS_Entity_type_EDGE) < 0) return NULL; Py_INCREF(&ACIS_Entity_type_EDGE); PyModule_AddObject(m, "EDGE", (PyObject *) &ACIS_Entity_type_EDGE); - // Add WIRE to the Topology module + // Add WIRE to the module ACIS_Entity_type_WIRE.tp_base = &ACIS_Entity_type_ENTITY; if (PyType_Ready(&ACIS_Entity_type_WIRE) < 0) return NULL; Py_INCREF(&ACIS_Entity_type_WIRE); PyModule_AddObject(m, "WIRE", (PyObject *) &ACIS_Entity_type_WIRE); - // Add LUMP to the Topology module + // Add LUMP to the module ACIS_Entity_type_LUMP.tp_base = &ACIS_Entity_type_ENTITY; if (PyType_Ready(&ACIS_Entity_type_LUMP) < 0) return NULL; Py_INCREF(&ACIS_Entity_type_LUMP); PyModule_AddObject(m, "LUMP", (PyObject *) &ACIS_Entity_type_LUMP); - // Add SHELL to the Topology module + // Add SHELL to the module ACIS_Entity_type_SHELL.tp_base = &ACIS_Entity_type_ENTITY; if (PyType_Ready(&ACIS_Entity_type_SHELL) < 0) return NULL; Py_INCREF(&ACIS_Entity_type_SHELL); PyModule_AddObject(m, "SHELL", (PyObject *) &ACIS_Entity_type_SHELL); - // Add SUBSHELL to the Topology module + // Add SUBSHELL to the module ACIS_Entity_type_SUBSHELL.tp_base = &ACIS_Entity_type_ENTITY; if (PyType_Ready(&ACIS_Entity_type_SUBSHELL) < 0) return NULL; Py_INCREF(&ACIS_Entity_type_SUBSHELL); PyModule_AddObject(m, "SUBSHELL", (PyObject *) &ACIS_Entity_type_SUBSHELL); - // Add COEDGE to the Topology module + // Add COEDGE to the module ACIS_Entity_type_COEDGE.tp_base = &ACIS_Entity_type_ENTITY; if (PyType_Ready(&ACIS_Entity_type_COEDGE) < 0) return NULL; Py_INCREF(&ACIS_Entity_type_COEDGE); PyModule_AddObject(m, "COEDGE", (PyObject *) &ACIS_Entity_type_COEDGE); - // Add LOOP to the Topology module + // Add LOOP to the module ACIS_Entity_type_LOOP.tp_base = &ACIS_Entity_type_ENTITY; if (PyType_Ready(&ACIS_Entity_type_LOOP) < 0) return NULL; Py_INCREF(&ACIS_Entity_type_LOOP); PyModule_AddObject(m, "LOOP", (PyObject *) &ACIS_Entity_type_LOOP); - // Add VERTEX to the Topology module + // Add VERTEX to the module ACIS_Entity_type_VERTEX.tp_base = &ACIS_Entity_type_ENTITY; if (PyType_Ready(&ACIS_Entity_type_VERTEX) < 0) return NULL; Py_INCREF(&ACIS_Entity_type_VERTEX); PyModule_AddObject(m, "VERTEX", (PyObject *) &ACIS_Entity_type_VERTEX); - // Add SURFACE to the Geometry module + // Add SURFACE to the module ACIS_Entity_type_SURFACE.tp_base = &ACIS_Entity_type_ENTITY; if (PyType_Ready(&ACIS_Entity_type_SURFACE) < 0) return NULL; Py_INCREF(&ACIS_Entity_type_SURFACE); PyModule_AddObject(m, "SURFACE", (PyObject *) &ACIS_Entity_type_SURFACE); - // Add CONE to the Geometry module + // Add CONE to the module ACIS_Entity_type_CONE.tp_base = &ACIS_Entity_type_ENTITY; if (PyType_Ready(&ACIS_Entity_type_CONE) < 0) return NULL; Py_INCREF(&ACIS_Entity_type_CONE); PyModule_AddObject(m, "CONE", (PyObject *) &ACIS_Entity_type_CONE); - // Add PLANE to the Geometry module + // Add PLANE to the module ACIS_Entity_type_PLANE.tp_base = &ACIS_Entity_type_ENTITY; if (PyType_Ready(&ACIS_Entity_type_PLANE) < 0) return NULL; Py_INCREF(&ACIS_Entity_type_PLANE); PyModule_AddObject(m, "PLANE", (PyObject *) &ACIS_Entity_type_PLANE); - // Add SPHERE to the Geometry module + // Add SPHERE to the module ACIS_Entity_type_SPHERE.tp_base = &ACIS_Entity_type_ENTITY; if (PyType_Ready(&ACIS_Entity_type_SPHERE) < 0) return NULL; Py_INCREF(&ACIS_Entity_type_SPHERE); PyModule_AddObject(m, "SPHERE", (PyObject *) &ACIS_Entity_type_SPHERE); - // Add SPLINE to the Geometry module + // Add SPLINE to the module ACIS_Entity_type_SPLINE.tp_base = &ACIS_Entity_type_ENTITY; if (PyType_Ready(&ACIS_Entity_type_SPLINE) < 0) return NULL; Py_INCREF(&ACIS_Entity_type_SPLINE); PyModule_AddObject(m, "SPLINE", (PyObject *) &ACIS_Entity_type_SPLINE); - // Add TORUS to the Geometry module + // Add TORUS to the module ACIS_Entity_type_TORUS.tp_base = &ACIS_Entity_type_ENTITY; if (PyType_Ready(&ACIS_Entity_type_TORUS) < 0) return NULL; Py_INCREF(&ACIS_Entity_type_TORUS); PyModule_AddObject(m, "TORUS", (PyObject *) &ACIS_Entity_type_TORUS); + // Add surface to the module + if (PyType_Ready(&ACIS_Entity_type_surface) < 0) + return NULL; + Py_INCREF(&ACIS_Entity_type_surface); + PyModule_AddObject(m, "surface", (PyObject *) &ACIS_Entity_type_surface); + // Return the module and all included objects return m; } @@ -1923,7 +2160,7 @@ PyObject *_ACIS_new_ENTITY() bool _ACIS_check_ENTITY(PyObject *ob) { - int retval = PyObject_IsInstance(ob, (PyObject *)&ACIS_Entity_type_ENTITY); + int retval = PyObject_IsInstance(ob, (PyObject *) &ACIS_Entity_type_ENTITY); if (retval < 0) { PyErr_SetString(PyExc_TypeError, "Problem with ENTITY type cheking"); @@ -2092,6 +2329,16 @@ bool _ACIS_check_TORUS(PyObject *ob) return Py_TYPE(ob) == &ACIS_Entity_type_TORUS; } +PyObject *_ACIS_new_surface() +{ + return PyObject_CallObject((PyObject *) &ACIS_Entity_type_surface, NULL); +} + +bool _ACIS_check_surface(PyObject *ob) +{ + return Py_TYPE(ob) == &ACIS_Entity_type_surface; +} + void _ACIS_make_null(PyObject *ob) { if (_ACIS_check_ENTITY(ob)) @@ -2099,3 +2346,8 @@ void _ACIS_make_null(PyObject *ob) ((ACIS_Entity_ENTITY *) ob)->_acis_obj = NULL; } } + +void _ACIS_set_entity(PyObject *ob, ENTITY *ent) +{ + ((ACIS_Entity_ENTITY *)ob)->_acis_obj = ent; +} diff --git a/src/acis_entity.h b/src/acis_entity.h index 80459d8..6e33c32 100644 --- a/src/acis_entity.h +++ b/src/acis_entity.h @@ -21,6 +21,10 @@ #include #include #include +#include +#include + +#include "acis_geometric_atoms.h" #include "acis_entity_export.h" @@ -62,6 +66,8 @@ PyObject ACIS_ENTITY_EXPORT *ACIS_Entity_method_ENTITY_get_attrib_obj_id(ACIS_En int ACIS_ENTITY_EXPORT ACIS_Entity_method_ENTITY_set_attrib_obj_id(ACIS_Entity_ENTITY *self, PyObject *value, void *closure); +PyObject ACIS_ENTITY_EXPORT *ACIS_Entity_method_ENTITY_type_name(PyObject *self); + static PyGetSetDef ACIS_Entity_getseters_ENTITY[] = { @@ -79,6 +85,7 @@ static PyMemberDef static PyMethodDef ACIS_Entity_methods_ENTITY[] = { + { "type_name", (PyCFunction) ACIS_Entity_method_ENTITY_type_name, METH_NOARGS, "Returns a name for this ENTITY's type" }, { NULL } /* Sentinel */ }; @@ -291,6 +298,16 @@ PyObject ACIS_ENTITY_EXPORT *_ACIS_new_TORUS(); bool ACIS_ENTITY_EXPORT _ACIS_check_TORUS(PyObject *ob); +// Define surface +typedef struct +{ + surface* _acis_obj; +} ACIS_Entity_surface; + +PyObject ACIS_ENTITY_EXPORT *_ACIS_new_surface(); + +bool ACIS_ENTITY_EXPORT _ACIS_check_surface(PyObject *ob); + // Additional functions @@ -300,6 +317,8 @@ bool ACIS_ENTITY_EXPORT _ACIS_check_TORUS(PyObject *ob); */ void ACIS_ENTITY_EXPORT _ACIS_make_null(PyObject *ob); +void ACIS_ENTITY_EXPORT _ACIS_set_entity(PyObject *ob, ENTITY *ent); + #ifdef __cplusplus } #endif diff --git a/src/acis_geometric_atoms.cpp b/src/acis_geometric_atoms.cpp index 038476a..042a9ce 100644 --- a/src/acis_geometric_atoms.cpp +++ b/src/acis_geometric_atoms.cpp @@ -5,29 +5,13 @@ * SPAposition wrapper */ -static int -ACIS_GeometricAtoms_traverse_SPAposition(ACIS_GeometricAtoms_SPAposition *self, visitproc visit, void *arg) -{ - // Use Py_VISIT macro for PyObject variables - - return 0; -} - -static int -ACIS_GeometricAtoms_clear_SPAposition(ACIS_GeometricAtoms_SPAposition *self) +static void +ACIS_GeometricAtoms_dealloc_SPAposition(ACIS_GeometricAtoms_SPAposition *self) { // Delete ACIS object ACIS_DELETE self->_acis_obj; - // Use Py_CLEAR macro for PyObject variables - - return 0; -} - -static void -ACIS_GeometricAtoms_dealloc_SPAposition(ACIS_GeometricAtoms_SPAposition *self) -{ - ACIS_GeometricAtoms_clear_SPAposition(self); + // Delete the python object Py_TYPE(self)->tp_free((PyObject *) self); } @@ -68,6 +52,26 @@ ACIS_GeometricAtoms_init_SPAposition(ACIS_GeometricAtoms_SPAposition *self, PyOb return 0; } +static PyObject * +ACIS_GeometricAtoms_repr_SPAposition(ACIS_GeometricAtoms_SPAposition *self) +{ + double x = self->_acis_obj->x(); double y = self->_acis_obj->y(); double z = self->_acis_obj->z(); + + char *_x = PyOS_double_to_string(x, 'r', 0, Py_DTSF_ADD_DOT_0, NULL); + if (!_x) + return PyErr_NoMemory(); + + char *_y = PyOS_double_to_string(y, 'r', 0, Py_DTSF_ADD_DOT_0, NULL); + if (!_y) + return PyErr_NoMemory(); + + char *_z = PyOS_double_to_string(z, 'r', 0, Py_DTSF_ADD_DOT_0, NULL); + if (!_z) + return PyErr_NoMemory(); + + return PyUnicode_FromFormat("SPAposition object (%s, %s, %s)", _x, _y, _z); +} + static PyObject * ACIS_GeometricAtoms_method_SPAposition_coordinate(ACIS_GeometricAtoms_SPAposition *self, PyObject *arg) { @@ -325,22 +329,20 @@ static PyTypeObject 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ - 0, /* tp_repr */ + (reprfunc) ACIS_GeometricAtoms_repr_SPAposition, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ - 0, /* tp_str */ + (reprfunc) ACIS_GeometricAtoms_repr_SPAposition, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | - Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_HAVE_GC, /* tp_flags */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ "SPAposition represents position vectors (points) in 3D Cartesian space that are subject to certain vector and transformation operations", /* tp_doc */ - (traverseproc) ACIS_GeometricAtoms_traverse_SPAposition, /* tp_traverse */ - (inquiry) ACIS_GeometricAtoms_clear_SPAposition, /* tp_clear */ + 0, /* tp_traverse */ + 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ @@ -363,29 +365,13 @@ static PyTypeObject * SPAvector wrapper */ -static int -ACIS_GeometricAtoms_traverse_SPAvector(ACIS_GeometricAtoms_SPAvector *self, visitproc visit, void *arg) -{ - // Use Py_VISIT macro for PyObject variables - - return 0; -} - -static int -ACIS_GeometricAtoms_clear_SPAvector(ACIS_GeometricAtoms_SPAvector *self) +static void +ACIS_GeometricAtoms_dealloc_SPAvector(ACIS_GeometricAtoms_SPAvector *self) { // Delete ACIS object ACIS_DELETE self->_acis_obj; - // Use Py_CLEAR macro for PyObject variables - - return 0; -} - -static void -ACIS_GeometricAtoms_dealloc_SPAvector(ACIS_GeometricAtoms_SPAvector *self) -{ - ACIS_GeometricAtoms_clear_SPAvector(self); + // Delete the python object Py_TYPE(self)->tp_free((PyObject *) self); } @@ -426,6 +412,26 @@ ACIS_GeometricAtoms_init_SPAvector(ACIS_GeometricAtoms_SPAvector *self, PyObject return 0; } +static PyObject * +ACIS_GeometricAtoms_repr_SPAvector(ACIS_GeometricAtoms_SPAvector *self) +{ + double x = self->_acis_obj->x(); double y = self->_acis_obj->y(); double z = self->_acis_obj->z(); + + char *_x = PyOS_double_to_string(x, 'r', 0, Py_DTSF_ADD_DOT_0, NULL); + if (!_x) + return PyErr_NoMemory(); + + char *_y = PyOS_double_to_string(y, 'r', 0, Py_DTSF_ADD_DOT_0, NULL); + if (!_y) + return PyErr_NoMemory(); + + char *_z = PyOS_double_to_string(z, 'r', 0, Py_DTSF_ADD_DOT_0, NULL); + if (!_z) + return PyErr_NoMemory(); + + return PyUnicode_FromFormat("SPAvector object (%s, %s, %s)", _x, _y, _z); +} + static PyObject * ACIS_GeometricAtoms_method_SPAvector_component(ACIS_GeometricAtoms_SPAvector *self, PyObject *arg) { @@ -683,22 +689,20 @@ static PyTypeObject 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ - 0, /* tp_repr */ + (reprfunc) ACIS_GeometricAtoms_repr_SPAvector, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ - 0, /* tp_str */ + (reprfunc) ACIS_GeometricAtoms_repr_SPAvector, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | - Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_HAVE_GC, /* tp_flags */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ "SPAvector represents a displacement vector in 3D Cartesian space", /* tp_doc */ - (traverseproc) ACIS_GeometricAtoms_traverse_SPAvector, /* tp_traverse */ - (inquiry) ACIS_GeometricAtoms_clear_SPAvector, /* tp_clear */ + 0, /* tp_traverse */ + 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ @@ -721,29 +725,13 @@ static PyTypeObject * SPAunit_vector wrapper */ -static int -ACIS_GeometricAtoms_traverse_SPAunit_vector(ACIS_GeometricAtoms_SPAunit_vector *self, visitproc visit, void *arg) -{ - // Use Py_VISIT macro for PyObject variables - - return 0; -} - -static int -ACIS_GeometricAtoms_clear_SPAunit_vector(ACIS_GeometricAtoms_SPAunit_vector *self) +static void +ACIS_GeometricAtoms_dealloc_SPAunit_vector(ACIS_GeometricAtoms_SPAunit_vector *self) { // Delete ACIS object ACIS_DELETE self->_acis_obj; - // Use Py_CLEAR macro for PyObject variables - - return 0; -} - -static void -ACIS_GeometricAtoms_dealloc_SPAunit_vector(ACIS_GeometricAtoms_SPAunit_vector *self) -{ - ACIS_GeometricAtoms_clear_SPAunit_vector(self); + // Delete the python object Py_TYPE(self)->tp_free((PyObject *) self); } @@ -784,6 +772,26 @@ ACIS_GeometricAtoms_init_SPAunit_vector(ACIS_GeometricAtoms_SPAunit_vector *self return 0; } +static PyObject * +ACIS_GeometricAtoms_repr_SPAunit_vector(ACIS_GeometricAtoms_SPAunit_vector *self) +{ + double x = self->_acis_obj->x(); double y = self->_acis_obj->y(); double z = self->_acis_obj->z(); + + char *_x = PyOS_double_to_string(x, 'r', 0, Py_DTSF_ADD_DOT_0, NULL); + if (!_x) + return PyErr_NoMemory(); + + char *_y = PyOS_double_to_string(y, 'r', 0, Py_DTSF_ADD_DOT_0, NULL); + if (!_y) + return PyErr_NoMemory(); + + char *_z = PyOS_double_to_string(z, 'r', 0, Py_DTSF_ADD_DOT_0, NULL); + if (!_z) + return PyErr_NoMemory(); + + return PyUnicode_FromFormat("SPAunit_vector object (%s, %s, %s)", _x, _y, _z); +} + static PyObject * ACIS_GeometricAtoms_method_SPAunit_vector_component(ACIS_GeometricAtoms_SPAunit_vector *self, PyObject *arg) { @@ -1041,22 +1049,20 @@ static PyTypeObject 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ - 0, /* tp_repr */ + (reprfunc) ACIS_GeometricAtoms_repr_SPAunit_vector, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ - 0, /* tp_str */ + (reprfunc) ACIS_GeometricAtoms_repr_SPAunit_vector, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | - Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_HAVE_GC, /* tp_flags */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ "SPAunit_vector provides a direction in 3D Cartesian space that has unit length", /* tp_doc */ - (traverseproc) ACIS_GeometricAtoms_traverse_SPAunit_vector, /* tp_traverse */ - (inquiry) ACIS_GeometricAtoms_clear_SPAunit_vector, /* tp_clear */ + 0, /* tp_traverse */ + 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ @@ -1079,29 +1085,13 @@ static PyTypeObject * SPAmatrix wrapper */ -static int -ACIS_GeometricAtoms_traverse_SPAmatrix(ACIS_GeometricAtoms_SPAmatrix *self, visitproc visit, void *arg) -{ - // Use Py_VISIT macro for PyObject variables - - return 0; -} - -static int -ACIS_GeometricAtoms_clear_SPAmatrix(ACIS_GeometricAtoms_SPAmatrix *self) +static void +ACIS_GeometricAtoms_dealloc_SPAmatrix(ACIS_GeometricAtoms_SPAmatrix *self) { // Delete ACIS object ACIS_DELETE self->_acis_obj; - // Use Py_CLEAR macro for PyObject variables - - return 0; -} - -static void -ACIS_GeometricAtoms_dealloc_SPAmatrix(ACIS_GeometricAtoms_SPAmatrix *self) -{ - ACIS_GeometricAtoms_clear_SPAmatrix(self); + // Delete the python object Py_TYPE(self)->tp_free((PyObject *) self); } @@ -1323,12 +1313,10 @@ static PyTypeObject 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | - Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_HAVE_GC, /* tp_flags */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ "SPAmatrix defines a 3x3 affine transformation acting on vectors and positions", /* tp_doc */ - (traverseproc) ACIS_GeometricAtoms_traverse_SPAmatrix, /* tp_traverse */ - (inquiry) ACIS_GeometricAtoms_clear_SPAmatrix, /* tp_clear */ + 0, /* tp_traverse */ + 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ @@ -1351,29 +1339,13 @@ static PyTypeObject * SPAtransf wrapper */ -static int -ACIS_GeometricAtoms_traverse_SPAtransf(ACIS_GeometricAtoms_SPAtransf *self, visitproc visit, void *arg) -{ - // Use Py_VISIT macro for PyObject variables - - return 0; -} - -static int -ACIS_GeometricAtoms_clear_SPAtransf(ACIS_GeometricAtoms_SPAtransf *self) +static void +ACIS_GeometricAtoms_dealloc_SPAtransf(ACIS_GeometricAtoms_SPAtransf *self) { // Delete ACIS object ACIS_DELETE self->_acis_obj; - // Use Py_CLEAR macro for PyObject variables - - return 0; -} - -static void -ACIS_GeometricAtoms_dealloc_SPAtransf(ACIS_GeometricAtoms_SPAtransf *self) -{ - ACIS_GeometricAtoms_clear_SPAtransf(self); + // Delete the python object Py_TYPE(self)->tp_free((PyObject *) self); } @@ -1529,12 +1501,10 @@ static PyTypeObject 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | - Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_HAVE_GC, /* tp_flags */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ "SPAtransf represents a general 3D affine transformation", /* tp_doc */ - (traverseproc) ACIS_GeometricAtoms_traverse_SPAtransf, /* tp_traverse */ - (inquiry) ACIS_GeometricAtoms_clear_SPAtransf, /* tp_clear */ + 0, /* tp_traverse */ + 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ @@ -1553,6 +1523,293 @@ static PyTypeObject }; +/** + * SPApar_pos wrapper + */ + +static void +ACIS_GeometricAtoms_dealloc_SPApar_pos(ACIS_GeometricAtoms_SPApar_pos *self) +{ + // Delete ACIS object + ACIS_DELETE self->_acis_obj; + + // Delete the python object + Py_TYPE(self)->tp_free((PyObject *) self); +} + +static PyObject * +ACIS_GeometricAtoms_new_SPApar_pos(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + ACIS_GeometricAtoms_SPApar_pos *self; + + self = (ACIS_GeometricAtoms_SPApar_pos *) type->tp_alloc(type, 0); + if (self != NULL) + { + // Just getting rid of the dangling pointer + self->_acis_obj = NULL; + } + + return (PyObject *) self; +} + +static int +ACIS_GeometricAtoms_init_SPApar_pos(ACIS_GeometricAtoms_SPApar_pos *self, PyObject *args, PyObject *kwargs) +{ + // Initialize the ACIS object + self->_acis_obj = ACIS_NEW SPApar_pos(); + + return 0; +} + +static PyObject * +ACIS_GeometricAtoms_repr_SPApar_pos(ACIS_GeometricAtoms_SPApar_pos *self) +{ + double u = self->_acis_obj->u; double v = self->_acis_obj->v; + + char *_u = PyOS_double_to_string(u, 'r', 0, Py_DTSF_ADD_DOT_0, NULL); + if (!_u) + return PyErr_NoMemory(); + + char *_v = PyOS_double_to_string(v, 'r', 0, Py_DTSF_ADD_DOT_0, NULL); + if (!_v) + return PyErr_NoMemory(); + + return PyUnicode_FromFormat("SPApar_pos object (%s, %s)", _u, _v); +} + +static PyObject * +ACIS_GeometricAtoms_method_SPApar_pos_u_getter(ACIS_GeometricAtoms_SPApar_pos *self, PyObject *value, void *closure) +{ + return PyFloat_FromDouble(self->_acis_obj->u); +} + +static int +ACIS_GeometricAtoms_method_SPApar_pos_u_setter(ACIS_GeometricAtoms_SPApar_pos *self, PyObject *value, void *closure) +{ + self->_acis_obj->u = PyFloat_AsDouble(value); + return 0; +} + +static PyObject * +ACIS_GeometricAtoms_method_SPApar_pos_v_getter(ACIS_GeometricAtoms_SPApar_pos *self, PyObject *value, void *closure) +{ + return PyFloat_FromDouble(self->_acis_obj->v); +} + +static int +ACIS_GeometricAtoms_method_SPApar_pos_v_setter(ACIS_GeometricAtoms_SPApar_pos *self, PyObject *value, void *closure) +{ + self->_acis_obj->v = PyFloat_AsDouble(value); + return 0; +} + +static PyGetSetDef + ACIS_GeometricAtoms_getseters_SPApar_pos[] = + { + { (char *) "u", (getter) ACIS_GeometricAtoms_method_SPApar_pos_u_getter, (setter) ACIS_GeometricAtoms_method_SPApar_pos_u_setter, (char *) "value of the u parameter", NULL }, + { (char *) "v", (getter) ACIS_GeometricAtoms_method_SPApar_pos_v_getter, (setter) ACIS_GeometricAtoms_method_SPApar_pos_v_setter, (char *) "value of the v parameter", NULL }, + { NULL } /* Sentinel */ + }; + +static PyMemberDef + ACIS_GeometricAtoms_members_SPApar_pos[] = + { + { NULL } /* Sentinel */ + }; + +static PyMethodDef + ACIS_GeometricAtoms_methods_SPApar_pos[] = + { + { NULL } /* Sentinel */ + }; + +static PyTypeObject + ACIS_GeometricAtoms_type_SPApar_pos = + { + PyVarObject_HEAD_INIT(NULL, 0) + "ACIS.SPAtransf", /* tp_name */ + sizeof(ACIS_GeometricAtoms_SPApar_pos), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor) ACIS_GeometricAtoms_dealloc_SPApar_pos, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc) ACIS_GeometricAtoms_repr_SPApar_pos, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + (reprfunc) ACIS_GeometricAtoms_repr_SPApar_pos, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + "SPApar_pos defines a parameter position in the parameter-space of a surface", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + ACIS_GeometricAtoms_methods_SPApar_pos, /* tp_methods */ + ACIS_GeometricAtoms_members_SPApar_pos, /* tp_members */ + ACIS_GeometricAtoms_getseters_SPApar_pos, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc) ACIS_GeometricAtoms_init_SPApar_pos, /* tp_init */ + 0, /* tp_alloc */ + ACIS_GeometricAtoms_new_SPApar_pos, /* tp_new */ + }; + + +/** + * SPApar_vec wrapper + */ + +static void +ACIS_GeometricAtoms_dealloc_SPApar_vec(ACIS_GeometricAtoms_SPApar_vec *self) +{ + // Delete ACIS object + ACIS_DELETE self->_acis_obj; + + // Delete the python object + Py_TYPE(self)->tp_free((PyObject *) self); +} + +static PyObject * +ACIS_GeometricAtoms_new_SPApar_vec(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + ACIS_GeometricAtoms_SPApar_vec *self; + + self = (ACIS_GeometricAtoms_SPApar_vec *) type->tp_alloc(type, 0); + if (self != NULL) + { + // Just getting rid of the dangling pointer + self->_acis_obj = NULL; + } + + return (PyObject *) self; +} + +static int +ACIS_GeometricAtoms_init_SPApar_vec(ACIS_GeometricAtoms_SPApar_vec *self, PyObject *args, PyObject *kwargs) +{ + // Initialize the ACIS object + self->_acis_obj = ACIS_NEW SPApar_vec(); + + return 0; +} + +static PyObject * +ACIS_GeometricAtoms_repr_SPApar_vec(ACIS_GeometricAtoms_SPApar_vec *self) +{ + double du = self->_acis_obj->du; double dv = self->_acis_obj->dv; + + char *_du = PyOS_double_to_string(du, 'r', 0, Py_DTSF_ADD_DOT_0, NULL); + if (!_du) + return PyErr_NoMemory(); + + char *_dv = PyOS_double_to_string(dv, 'r', 0, Py_DTSF_ADD_DOT_0, NULL); + if (!_dv) + return PyErr_NoMemory(); + + return PyUnicode_FromFormat("SPApar_vec object (%s, %s)", _du, _dv); +} + +static PyObject * +ACIS_GeometricAtoms_method_SPApar_vec_du_getter(ACIS_GeometricAtoms_SPApar_vec *self, PyObject *value, void *closure) +{ + return PyFloat_FromDouble(self->_acis_obj->du); +} + +static int +ACIS_GeometricAtoms_method_SPApar_vec_du_setter(ACIS_GeometricAtoms_SPApar_vec *self, PyObject *value, void *closure) +{ + self->_acis_obj->du = PyFloat_AsDouble(value); + return 0; +} + +static PyObject * +ACIS_GeometricAtoms_method_SPApar_vec_dv_getter(ACIS_GeometricAtoms_SPApar_vec *self, PyObject *value, void *closure) +{ + return PyFloat_FromDouble(self->_acis_obj->dv); +} + +static int +ACIS_GeometricAtoms_method_SPApar_vec_dv_setter(ACIS_GeometricAtoms_SPApar_vec *self, PyObject *value, void *closure) +{ + self->_acis_obj->dv = PyFloat_AsDouble(value); + return 0; +} + +static PyGetSetDef + ACIS_GeometricAtoms_getseters_SPApar_vec[] = + { + { (char *) "du", (getter) ACIS_GeometricAtoms_method_SPApar_vec_du_getter, (setter) ACIS_GeometricAtoms_method_SPApar_vec_du_setter, (char *) "value of the u parameter", NULL }, + { (char *) "dv", (getter) ACIS_GeometricAtoms_method_SPApar_vec_dv_getter, (setter) ACIS_GeometricAtoms_method_SPApar_vec_dv_setter, (char *) "value of the v parameter", NULL }, + { NULL } /* Sentinel */ + }; + +static PyMemberDef + ACIS_GeometricAtoms_members_SPApar_vec[] = + { + { NULL } /* Sentinel */ + }; + +static PyMethodDef + ACIS_GeometricAtoms_methods_SPApar_vec[] = + { + { NULL } /* Sentinel */ + }; + +static PyTypeObject + ACIS_GeometricAtoms_type_SPApar_vec = + { + PyVarObject_HEAD_INIT(NULL, 0) + "ACIS.SPAtransf", /* tp_name */ + sizeof(ACIS_GeometricAtoms_SPApar_vec), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor) ACIS_GeometricAtoms_dealloc_SPApar_vec, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc) ACIS_GeometricAtoms_repr_SPApar_vec, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + (reprfunc) ACIS_GeometricAtoms_repr_SPApar_vec, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + "SPApar_vec defines a vector (du, dv) in 2D parameter-space", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + ACIS_GeometricAtoms_methods_SPApar_vec, /* tp_methods */ + ACIS_GeometricAtoms_members_SPApar_vec, /* tp_members */ + ACIS_GeometricAtoms_getseters_SPApar_vec, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc) ACIS_GeometricAtoms_init_SPApar_vec, /* tp_init */ + 0, /* tp_alloc */ + ACIS_GeometricAtoms_new_SPApar_vec, /* tp_new */ + }; + /** * Python module definitions */ @@ -2435,6 +2692,18 @@ PyInit_GeometricAtoms(void) Py_INCREF(&ACIS_GeometricAtoms_type_SPAunit_vector); PyModule_AddObject(m, "SPAunit_vector", (PyObject *) &ACIS_GeometricAtoms_type_SPAunit_vector); + // SPApar_pos + if (PyType_Ready(&ACIS_GeometricAtoms_type_SPApar_pos) < 0) + return NULL; + Py_INCREF(&ACIS_GeometricAtoms_type_SPApar_pos); + PyModule_AddObject(m, "SPApar_pos", (PyObject *) &ACIS_GeometricAtoms_type_SPApar_pos); + + // SPApar_vec + if (PyType_Ready(&ACIS_GeometricAtoms_type_SPApar_vec) < 0) + return NULL; + Py_INCREF(&ACIS_GeometricAtoms_type_SPApar_vec); + PyModule_AddObject(m, "SPApar_vec", (PyObject *) &ACIS_GeometricAtoms_type_SPApar_vec); + return m; } @@ -2487,3 +2756,23 @@ PyObject *_ACIS_new_SPAtransf() { return PyObject_CallObject((PyObject *) &ACIS_GeometricAtoms_type_SPAtransf, NULL); } + +bool _ACIS_check_SPApar_pos(PyObject *ob) +{ + return Py_TYPE(ob) == &ACIS_GeometricAtoms_type_SPApar_pos; +} + +PyObject *_ACIS_new_SPApar_pos() +{ + return PyObject_CallObject((PyObject *) &ACIS_GeometricAtoms_type_SPApar_pos, NULL); +} + +bool _ACIS_check_SPApar_vec(PyObject *ob) +{ + return Py_TYPE(ob) == &ACIS_GeometricAtoms_type_SPApar_vec; +} + +PyObject *_ACIS_new_SPApar_vec() +{ + return PyObject_CallObject((PyObject *) &ACIS_GeometricAtoms_type_SPApar_vec, NULL); +} diff --git a/src/acis_geometric_atoms.h b/src/acis_geometric_atoms.h index f437846..ce4ef8a 100644 --- a/src/acis_geometric_atoms.h +++ b/src/acis_geometric_atoms.h @@ -74,6 +74,17 @@ PyObject ACIS_GEOMETRIC_ATOMS_EXPORT *_ACIS_new_SPAmatrix(); bool ACIS_GEOMETRIC_ATOMS_EXPORT _ACIS_check_SPAmatrix(PyObject *ob); +// Define SPAtransf +typedef struct +{ + PyObject_HEAD + SPAtransf *_acis_obj; +} ACIS_GeometricAtoms_SPAtransf; + +PyObject ACIS_GEOMETRIC_ATOMS_EXPORT *_ACIS_new_SPAtransf(); + +bool ACIS_GEOMETRIC_ATOMS_EXPORT _ACIS_check_SPAtransf(PyObject *ob); + // Define SPApar_pos typedef struct { @@ -81,20 +92,20 @@ typedef struct SPApar_pos *_acis_obj; } ACIS_GeometricAtoms_SPApar_pos; -//PyObject ACIS_GEOMETRIC_ATOMS_EXPORT *_ACIS_new_SPApar_pos(); +PyObject ACIS_GEOMETRIC_ATOMS_EXPORT *_ACIS_new_SPApar_pos(); -//bool ACIS_GEOMETRIC_ATOMS_EXPORT _ACIS_check_SPApar_pos(PyObject *ob); +bool ACIS_GEOMETRIC_ATOMS_EXPORT _ACIS_check_SPApar_pos(PyObject *ob); -// Define SPAtransf +// Define SPApar_vec typedef struct { PyObject_HEAD - SPAtransf *_acis_obj; -} ACIS_GeometricAtoms_SPAtransf; + SPApar_vec *_acis_obj; +} ACIS_GeometricAtoms_SPApar_vec; -PyObject ACIS_GEOMETRIC_ATOMS_EXPORT *_ACIS_new_SPAtransf(); +PyObject ACIS_GEOMETRIC_ATOMS_EXPORT *_ACIS_new_SPApar_vec(); -bool ACIS_GEOMETRIC_ATOMS_EXPORT _ACIS_check_SPAtransf(PyObject *ob); +bool ACIS_GEOMETRIC_ATOMS_EXPORT _ACIS_check_SPApar_vec(PyObject *ob); #ifdef __cplusplus } diff --git a/src/acis_lists.cpp b/src/acis_lists.cpp index 31c1e0c..7166971 100644 --- a/src/acis_lists.cpp +++ b/src/acis_lists.cpp @@ -194,20 +194,20 @@ ACIS_Lists_method_ENTITY_LIST_byte_count(ACIS_Lists_ENTITY_LIST *self) static PyObject * ACIS_Lists_method_ENTITY_LIST_first(ACIS_Lists_ENTITY_LIST *self) { - PyObject *retobj = _ACIS_new_ENTITY(); ENTITY *_elem = self->_acis_obj->first(); - ((ACIS_Entity_ENTITY *) retobj)->_acis_obj = _elem; + PyObject *retobj = __convert_entity(_elem); return retobj; } static PyObject * ACIS_Lists_method_ENTITY_LIST_next(ACIS_Lists_ENTITY_LIST *self) { - PyObject *retobj = _ACIS_new_ENTITY(); + PyObject *retobj; ENTITY *_elem = self->_acis_obj->next(); + if (_elem) { - ((ACIS_Entity_ENTITY *) retobj)->_acis_obj = _elem; + retobj = __convert_entity(_elem); } else { @@ -232,12 +232,12 @@ ACIS_Lists_method_ENTITY_LIST_next_from(ACIS_Lists_ENTITY_LIST *self, PyObject * int _from_index = (int) PyLong_AsLong(arg); Py_DECREF(arg); - PyObject *retobj = _ACIS_new_ENTITY(); + PyObject *retobj; ENTITY *_elem = self->_acis_obj->next_from(_from_index); if (_elem) { - ((ACIS_Entity_ENTITY *) retobj)->_acis_obj = _elem; + retobj = __convert_entity(_elem); } else { @@ -412,3 +412,29 @@ bool _ACIS_check_ENTITY_LIST(PyObject *ob) else return false; } + +PyObject *__convert_entity(ENTITY *ent) +{ + // Find the type name of the entity + const char *_type_name = ent->type_name(); + + // We could use a hashing function here... + PyObject *_retobj; + if (strcmp("body", _type_name) == 0) + { + _retobj = _ACIS_new_BODY(); + _ACIS_set_entity(_retobj, ent); + } + else if (strcmp("face", _type_name) == 0) + { + _retobj = _ACIS_new_FACE(); + _ACIS_set_entity(_retobj, ent); + } + else if (strcmp("surface", _type_name) == 0) + { + _retobj = _ACIS_new_SURFACE(); + _ACIS_set_entity(_retobj, ent); + } + + return _retobj; +} diff --git a/src/acis_lists.h b/src/acis_lists.h index 694bcd0..1838e70 100644 --- a/src/acis_lists.h +++ b/src/acis_lists.h @@ -37,6 +37,8 @@ PyObject ACIS_LISTS_EXPORT *_ACIS_new_ENTITY_LIST(); bool ACIS_LISTS_EXPORT _ACIS_check_ENTITY_LIST(PyObject *ob); +PyObject ACIS_LISTS_EXPORT *__convert_entity(ENTITY *ent); + #ifdef __cplusplus } #endif diff --git a/src/acis_modeler.cpp b/src/acis_modeler.cpp index 672af2f..a93f873 100644 --- a/src/acis_modeler.cpp +++ b/src/acis_modeler.cpp @@ -588,230 +588,6 @@ ACIS_api_remove_transf(PyObject *self, PyObject *args, PyObject *kwargs) Py_RETURN_NONE; } -static PyObject * -ACIS_api_unite(PyObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *input_tool = NULL, *input_blank = NULL; - - // List of keyword arguments that this function can take - static 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; - - // Type checks for ACIS objects - if (!_ACIS_check_BODY(input_tool)) - { - PyErr_SetString(PyExc_TypeError, "Tool must be a BODY object"); - return NULL; - } - - if (!_ACIS_check_BODY(input_blank)) - { - PyErr_SetString(PyExc_TypeError, "Blank must be a BODY object"); - return NULL; - } - - API_BEGIN - - // Convert PyObject to ACIS objects - BODY *&_tool = (BODY *&) ((ACIS_Entity_BODY *) input_tool)->base_obj._acis_obj; - BODY *&_blank = (BODY *&) ((ACIS_Entity_BODY *) input_blank)->base_obj._acis_obj; - - // Call ACIS API - result = api_unite(_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 - _ACIS_make_null(input_tool); - // Returning none means that we have no errors - Py_RETURN_NONE; - } -} - -static PyObject * -ACIS_api_intersect(PyObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *input_tool = NULL, *input_blank = NULL; - - // List of keyword arguments that this function can take - static 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; - - // Type checks for ACIS objects - if (!_ACIS_check_BODY(input_tool)) - { - PyErr_SetString(PyExc_TypeError, "Tool must be a BODY object"); - return NULL; - } - - if (!_ACIS_check_BODY(input_blank)) - { - PyErr_SetString(PyExc_TypeError, "Blank must be a BODY object"); - return NULL; - } - - API_BEGIN - - // Convert PyObject to ACIS objects - BODY *&_tool = (BODY *&) ((ACIS_Entity_BODY *) input_tool)->base_obj._acis_obj; - BODY *&_blank = (BODY *&) ((ACIS_Entity_BODY *) input_blank)->base_obj._acis_obj; - - // Call ACIS API - result = api_intersect(_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 - _ACIS_make_null(input_tool); - // Returning none means that we have no errors - Py_RETURN_NONE; - } -} - -static PyObject * -ACIS_api_subtract(PyObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *input_tool = NULL, *input_blank = NULL; - - // List of keyword arguments that this function can take - static 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; - - // Type checks for ACIS objects - if (!_ACIS_check_BODY(input_tool)) - { - PyErr_SetString(PyExc_TypeError, "Tool must be a BODY object"); - return NULL; - } - - if (!_ACIS_check_BODY(input_blank)) - { - PyErr_SetString(PyExc_TypeError, "Blank must be a BODY object"); - return NULL; - } - - API_BEGIN - - // Convert PyObject to ACIS objects - BODY *&_tool = (BODY *&) ((ACIS_Entity_BODY *) input_tool)->base_obj._acis_obj; - BODY *&_blank = (BODY *&) ((ACIS_Entity_BODY *) input_blank)->base_obj._acis_obj; - - // Call ACIS API - 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 - _ACIS_make_null(input_tool); - // Returning none means that we have no errors - Py_RETURN_NONE; - } -} - -static PyObject * -ACIS_api_imprint(PyObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *input_tool = NULL, *input_blank = NULL; - - // List of keyword arguments that this function can take - static 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; - - // Type checks for ACIS objects - if (!_ACIS_check_BODY(input_tool)) - { - PyErr_SetString(PyExc_TypeError, "Tool must be a BODY object"); - return NULL; - } - - if (!_ACIS_check_BODY(input_blank)) - { - PyErr_SetString(PyExc_TypeError, "Blank must be a BODY object"); - return NULL; - } - - API_BEGIN - - // Convert PyObject to ACIS objects - BODY *&_tool = (BODY *&) ((ACIS_Entity_BODY *) input_tool)->base_obj._acis_obj; - BODY *&_blank = (BODY *&) ((ACIS_Entity_BODY *) input_blank)->base_obj._acis_obj; - - // Call ACIS API - result = api_imprint(_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 - _ACIS_make_null(input_tool); - // Returning none means that we have no errors - Py_RETURN_NONE; - } -} - static PyObject * ACIS_api_sheet_from_ff(PyObject *self, PyObject *args, PyObject *kwargs) { @@ -876,12 +652,7 @@ ACIS_api_sheet_from_ff(PyObject *self, PyObject *args, PyObject *kwargs) } } -static PyObject * -ACIS_api_boolean_chop_body(PyObject *self, PyObject *args, PyObject *kwargs) -{ - /* TO-DO: Implement api_boolean_chop_body */ - return NULL; -} + static PyMethodDef module_methods[] = @@ -903,12 +674,7 @@ static PyMethodDef { "api_make_torus", (PyCFunction) ACIS_api_make_torus, METH_VARARGS | METH_KEYWORDS, "Creates a torus of given major and minor radii centered at the origin" }, { "api_apply_transf", (PyCFunction) ACIS_api_apply_transf, METH_VARARGS | METH_KEYWORDS, "Changes the transform entity attached to a body" }, { "api_remove_transf", (PyCFunction) ACIS_api_remove_transf, METH_VARARGS | METH_KEYWORDS, "Removes (discards) the transformation of a body" }, - { "api_unite", (PyCFunction) ACIS_api_unite, METH_VARARGS | METH_KEYWORDS, "Executes a Boolean unite operation" }, - { "api_intersect", (PyCFunction) ACIS_api_intersect, METH_VARARGS | METH_KEYWORDS, "Executes a Boolean intersect operation on two bodies" }, - { "api_subtract", (PyCFunction) ACIS_api_subtract, METH_VARARGS | METH_KEYWORDS, "Executes a Boolean subtract operation" }, - { "api_imprint", (PyCFunction) ACIS_api_imprint, METH_VARARGS | METH_KEYWORDS, "Intersects two bodies and imprints the intersection graph on both bodies" }, { "api_sheet_from_ff", (PyCFunction) ACIS_api_sheet_from_ff, METH_VARARGS | METH_KEYWORDS, "Creates a sheet body as a copy of a face" }, - { "api_boolean_chop_body", (PyCFunction) ACIS_api_boolean_chop_body, METH_VARARGS | METH_KEYWORDS, "Executes simultaneous Boolean intersect and subtract operations on two bodies" }, { NULL, NULL, 0, NULL } }; diff --git a/src/acis_modeler.h b/src/acis_modeler.h index 338fd13..c2b07aa 100644 --- a/src/acis_modeler.h +++ b/src/acis_modeler.h @@ -17,7 +17,6 @@ #include #include #include -#include #include "acis_entity.h" #include "acis_geometric_atoms.h"