Skip to content
This repository was archived by the owner on May 19, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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
64 changes: 61 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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
#
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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} )
Expand Down Expand Up @@ -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
#
Expand Down Expand Up @@ -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}
)

Expand Down
21 changes: 16 additions & 5 deletions FUNCTION_REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -58,6 +53,8 @@
* SPAmatrix
* SPAvector
* SPAunit_vector
* SPApar_pos
* SPApar_vec

### Functions

Expand Down Expand Up @@ -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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
2 changes: 1 addition & 1 deletion cmake-modules
Submodule cmake-modules updated 2 files
+242 −45 FindACIS.cmake
+9 −1 README.md
3 changes: 2 additions & 1 deletion examples/01_generate_solid_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 4 additions & 3 deletions examples/02_boolean_subtract.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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"
Expand Down
3 changes: 2 additions & 1 deletion examples/03_sweeping.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
57 changes: 57 additions & 0 deletions examples/04_face_counting.py
Original file line number Diff line number Diff line change
@@ -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()
33 changes: 33 additions & 0 deletions python/utilities.py
Original file line number Diff line number Diff line change
@@ -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
Loading