Compare commits

...
16 Commits
Author SHA1 Message Date
f4alt 45bd03651e support assemblies 2026-09-01 13:22:02 -04:00
f4alt 76949e1814 get converter working again with native prt files 2026-09-01 13:22:02 -04:00
f4alt 78afc4908f unified part writer 2026-09-01 13:22:02 -04:00
f4alt ab63f800e3 Revert "snapshot writer for frontend"
This reverts commit e75ddc22963ab5ffb769c2520458126ba5abfb82.
2026-09-01 13:22:02 -04:00
f4alt e6a2c23110 snapshot writer for frontend 2026-09-01 13:22:02 -04:00
f4alt 9c8029f34b experiment with a conversion contract
use a snapshot as a lightweight intermediary from the conversion core to
the creo frontend
2026-09-01 13:22:01 -04:00
f4alt 2c1366d99e first major shift: profile loading
since profile loading is coming from a .g, separate it from the creo
standup
2026-09-01 13:22:01 -04:00
f4alt 4ed030bb2d ignore vs files anywhere in the project 2026-09-01 13:22:01 -04:00
f4alt 149da288f0 add a spawned exe debug fallback
This method _works_ but requires a spawned console to run the converter
- ugly, fragile, and not what we want long term. Adding it here behind a
define for shortterm debugging
2026-09-01 13:22:01 -04:00
f4alt 786b911538 use translation files method 2026-09-01 13:22:01 -04:00
f4alt b46732c0e8 wip 2026-09-01 13:22:01 -04:00
f4alt 633023ab4b Creo expects text/ 2026-09-01 13:22:01 -04:00
f4alt 2b5f76fe69 begin shift from requiring copying files to Creo install
Old mechanism required copying output files into "Program Files/Creo" -
it *works*, but is not preferred (for both users and Creo development
documentation). The better pattern is to have our tool live outside
the Creo system install and pointed to. However, this requires the
BRL-CAD dll's to be runtime loaded (either by quirk or design of Creo).
To stage this we first need to separate the brlcad 'real' work from the
Creo standup. This will allow us to register the frontend with Creo's
tools and runtime-load the brl backend.
2026-09-01 13:22:01 -04:00
f4alt fad1606492 wip: cleanup hardcoded paths 2026-09-01 13:22:00 -04:00
f4alt 1df5693b4f update API calls 2026-09-01 13:22:00 -04:00
f4alt 563a555664 pull in Bill's last wip changes 2026-09-01 13:22:00 -04:00
26 changed files with 7371 additions and 1765 deletions
+3 -3
View File
@@ -3,7 +3,7 @@
/.build*
/*_build*
/*-build*
/out
out/
# Temporary files
*~
@@ -27,9 +27,9 @@
# CMakeSettings.json for Visual Studio going forward)
# https://learn.microsoft.com/en-us/cpp/build/cmake-presets-vs
# https://learn.microsoft.com/en-us/cpp/build/customize-cmake-settings
/.vs
.vs/
.vscode
/CMakeSettings.json
CMakeSettings.json
#Qt Creator
CMakeLists.txt.user
+281 -364
View File
@@ -2,25 +2,35 @@
# Title: CMakeLists.txt #
# Purpose: Configure and generate build files for CREO2BRL project #
# Note: Requires an active Creo Pro/Toolkit license #
# Revised: 3/22/2023 #
# Revised: 2/6/2024 #
#----------------------------------------------------------------------#
brlcad_find_package(REGEX REQUIRED)
# Establish the list of Source files - this is needed
# both for the plugin build and the main BRL-CAD build
set(
CREO2BRL_SOURCES
set(CREO2BRL_SHARED_SOURCES
part_writer.cpp
)
set(CREO2BRL_LEGACY_SOURCES
assembly.cpp
csg.cpp
main.cpp
part.cpp
util.cpp
)
${CREO2BRL_SHARED_SOURCES}
)
set(CREO2BRL_CORE_SOURCES
core.cpp
conversion.cpp
profile.cpp
${CREO2BRL_SHARED_SOURCES}
)
if(NOT DEFINED BRLCAD_BUILDTEST_EXTERNALS)
# Minimum required version of CMake
cmake_minimum_required(VERSION 3.20)
cmake_minimum_required(VERSION 3.22)
message(STATUS "CMake version = ${CMAKE_VERSION}")
# Produce console log of CMake variables
@@ -31,13 +41,13 @@ if(NOT DEFINED BRLCAD_BUILDTEST_EXTERNALS)
#----------------------------------------------------------------------#
# Set CMake project name
set(project_name "CREO2BRL")
set(project_name CREO2BRL)
project(${project_name})
# Set Project Version
string(TIMESTAMP YYYY "%Y")
string(TIMESTAMP MM "%m")
string(TIMESTAMP DD "%d")
string(TIMESTAMP MM "%m")
string(TIMESTAMP DD "%d")
set(project_version "${YYYY}.${MM}.${DD}")
message(STATUS "${project_name} version = ${project_version}")
@@ -46,140 +56,117 @@ if(NOT DEFINED BRLCAD_BUILDTEST_EXTERNALS)
string(TIMESTAMP time %H:%M:%S)
message(STATUS "Current date and time: ${date} ${time}")
#----------------------------------------------------------------------#
# CAUTION: Verify installation settings before running CMake #
#----------------------------------------------------------------------#
# | | | | | | | #
# v v v v v v v #
# Allowed BRL-CAD configuration types
set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "" FORCE)
set(BRLCAD_ROOT_DIR "C:/Workspace/BRL-CAD/Source" CACHE PATH "BRL-CAD root directory")
set(CREO_ROOT_DIR "C:/Program Files/PTC/Creo 8.0.8.0" CACHE PATH "Creo root directory")
option(CREO_EXEC_PLUGIN "Build the spawned executable diagnostic fallback" OFF)
# ^ ^ ^ ^ ^ ^ ^ #
# | | | | | | | #
#----------------------------------------------------------------------#
find_package(BRLCAD CONFIG REQUIRED COMPONENTS bu bn bv bg nmg brep rt wdb)
set(CREO_BRLCAD_LIBS
BRLCAD::rt
BRLCAD::wdb
BRLCAD::brep
BRLCAD::bg
BRLCAD::nmg
BRLCAD::bv
BRLCAD::bn
BRLCAD::bu
)
# BRL-CAD directories
set(BRLCAD_BLD_DIR "${BRLCAD_ROOT_DIR}/Build")
set(BRLCAD_BIN_DIR "${BRLCAD_ROOT_DIR}/Build/Release/bin")
set(BRLCAD_INC_BRL_DIR "${BRLCAD_ROOT_DIR}/Build/Release/include/brlcad")
set(BRLCAD_INC_DIR "${BRLCAD_ROOT_DIR}/Build/Release/include")
set(BRLCAD_INC_NRB_DIR "${BRLCAD_ROOT_DIR}/Build/Release/include/openNURBS")
set(BRLCAD_LIB_DIR "${BRLCAD_ROOT_DIR}/Build/Release/lib")
set(BRLCAD_REL_DIR "${BRLCAD_ROOT_DIR}/Build/Release")
# TARGET_RUNTIME_DLLS does not capture the full BRL-CAD runtime set for this
# plugin build, so stage the required DLLs from the BRL-CAD package bin/.
set(CREO_BRLCAD_RUNTIME_DLL_NAMES
Clipper2
libbg
libbn
libbrep
libbu
libbv
libnmg
librt
libwdb
lmdb
manifold
mmesh
OpenNURBS
regex_brl
z_brl
)
set(CREO_BRLCAD_RUNTIME_DLLS)
foreach(dll_name ${CREO_BRLCAD_RUNTIME_DLL_NAMES})
set(dll_path "${BRLCAD_DIR}/bin/${dll_name}.dll")
if(NOT EXISTS "${dll_path}")
message(FATAL_ERROR "Missing BRL-CAD runtime DLL: ${dll_path}")
endif()
list(APPEND CREO_BRLCAD_RUNTIME_DLLS "${dll_path}")
endforeach()
# Creo platform version
set(CREO_OS_VERSION x86e_win64)
# Must supply CREO_ROOT_DIR (typically /c/Program Files/PTC/Creo <version>/)
set(CREO_ROOT_DIR "" CACHE PATH "Creo installation root")
if(NOT IS_DIRECTORY "${CREO_ROOT_DIR}")
message(FATAL_ERROR "CREO_ROOT_DIR must identify an existing Creo installation")
endif()
# Creo relative paths
set(CREO_DAT_REL "Common Files/protoolkit")
set(CREO_MSG_REL "Common Files/text/usascii")
set(CREO_OBJ_REL "Common Files/${CREO_OS_VERSION}/obj")
set(CREO_PTK_REL "Common Files/protoolkit/${CREO_OS_VERSION}/obj")
set(CREO_RES_REL "Common Files/text/resource")
find_path(CREO_COMMON_DIR NAMES protoolkit PATHS "${CREO_ROOT_DIR}" PATH_SUFFIXES "Common Files" NO_DEFAULT_PATH REQUIRED)
set(CREO_DAT_DIR "${CREO_COMMON_DIR}/protoolkit")
file(GLOB CREO_PTK_OBJ_DIRS LIST_DIRECTORIES true "${CREO_DAT_DIR}/*/obj")
find_library(CREO_PTK_DLL_LIB NAMES protk_dll_NU protk_dll PATHS ${CREO_PTK_OBJ_DIRS} NO_DEFAULT_PATH REQUIRED)
# Creo directories
set(CREO_DAT_DIR "${CREO_ROOT_DIR}/${CREO_DAT_REL}")
set(CREO_MSG_DIR "${CREO_ROOT_DIR}/${CREO_MSG_REL}")
set(CREO_OBJ_DIR "${CREO_ROOT_DIR}/${CREO_OBJ_REL}")
set(CREO_PTK_DIR "${CREO_ROOT_DIR}/${CREO_PTK_REL}")
set(CREO_RES_DIR "${CREO_ROOT_DIR}/${CREO_RES_REL}")
get_filename_component(CREO_PTK_DIR "${CREO_PTK_DLL_LIB}" DIRECTORY)
get_filename_component(CREO_OS_DIR "${CREO_PTK_DIR}" DIRECTORY)
get_filename_component(CREO_OS_VERSION "${CREO_OS_DIR}" NAME)
set(CREO_PTK_INC_DIR "${CREO_DAT_DIR}/includes")
set(CREO_PTK_APP_INC_DIR "${CREO_DAT_DIR}/protk_appls/includes")
# Creo ProToolkit include directories
set(CREO_PTK_INC_DIR "${CREO_ROOT_DIR}/Common Files/protoolkit/includes")
set(CREO_PTK_APP_INC_DIR "${CREO_ROOT_DIR}/Common Files/protoolkit/protk_appls/includes")
# Creo startup file
set(CREO_PSF_TXT "${CREO_ROOT_DIR}/Parametric/bin/parametric.psf")
# Creo ProToolkit Unlocker script
set(CREO_PTK_UNLOCKER "${CREO_ROOT_DIR}/Parametric/bin/protk_unlock.bat")
# Locate Creo libraries
find_file(CREO_PTK_DLL_LIBS NAMES "protk_dll_NU.lib" "protk_dll.lib" PATHS "${CREO_PTK_DIR}")
find_file(CREO_PTK_EXE_LIBS NAMES "protoolkit_NU.lib" "protoolkit.lib" PATHS "${CREO_PTK_DIR}")
foreach(libname "ucore.lib" "udata.lib")
set(unicode_lib "${CREO_PTK_DIR}/${libname}")
if(EXISTS ${unicode_lib})
set(CREO_PTK_DLL_LIBS ${CREO_PTK_DLL_LIBS} ${unicode_lib})
find_library(CREO_PTK_EXE_LIBS NAMES protoolkit_NU protoolkit PATHS "${CREO_PTK_DIR}" NO_DEFAULT_PATH REQUIRED)
find_library(CREO_UCORE_LIB NAMES ucore PATHS "${CREO_PTK_DIR}" NO_DEFAULT_PATH)
find_library(CREO_UDATA_LIB NAMES udata PATHS "${CREO_PTK_DIR}" NO_DEFAULT_PATH)
set(CREO_PTK_DLL_LIBS "${CREO_PTK_DLL_LIB}")
foreach(lib "${CREO_UCORE_LIB}" "${CREO_UDATA_LIB}")
if(lib)
list(APPEND CREO_PTK_DLL_LIBS "${lib}")
endif()
endforeach()
# Verify PATH dependent items
set(
path_dependent_items
BRLCAD_BLD_DIR
BRLCAD_BIN_DIR
BRLCAD_INC_BRL_DIR
BRLCAD_INC_DIR
BRLCAD_INC_NRB_DIR
BRLCAD_LIB_DIR
BRLCAD_REL_DIR
BRLCAD_ROOT_DIR
CREO_DAT_DIR
CREO_MSG_DIR
CREO_OBJ_DIR
CREO_PSF_TXT
CREO_PTK_APP_INC_DIR
CREO_PTK_DIR
CREO_PTK_DLL_LIBS
CREO_PTK_EXE_LIBS
CREO_PTK_INC_DIR
CREO_PTK_UNLOCKER
CREO_RES_DIR
)
find_file(CREO_PSF_TXT NAMES parametric.psf PATHS "${CREO_ROOT_DIR}" PATH_SUFFIXES Parametric/bin NO_DEFAULT_PATH REQUIRED)
get_filename_component(CREO_PARAMETRIC_BIN_DIR "${CREO_PSF_TXT}" DIRECTORY)
find_program(CREO_PTK_UNLOCKER NAMES protk_unlock.bat PATHS "${CREO_PARAMETRIC_BIN_DIR}" NO_DEFAULT_PATH REQUIRED)
# Identify missing PATH dependent items
set(path_fails 0)
foreach(items ${path_dependent_items})
foreach(item ${${items}})
if(NOT EXISTS ${item})
if(NOT path_fails)
message("--")
message("-- #----------------------------------------------------------------------#")
message("-- # ERROR: Unable to locate the following PATH dependent item(s): #")
message("-- #----------------------------------------------------------------------#")
endif()
set(path_fails 1)
message("-- # Missing: ${item}")
endif()
endforeach()
# Verify the Creo directories derived from the discovered installation
foreach(dir CREO_DAT_DIR CREO_PTK_INC_DIR CREO_PTK_APP_INC_DIR)
if(NOT IS_DIRECTORY "${${dir}}")
message(FATAL_ERROR "Unable to locate required Creo directory: ${${dir}}")
endif()
endforeach()
if(path_fails)
message("-- #----------------------------------------------------------------------#")
message("-- # ACTION: All PATH dependent items must be correct before continuing #")
message("-- #----------------------------------------------------------------------#")
message("--")
message(FATAL_ERROR "This is a FATAL error, unable to continue.")
# Build a relocatable bundle in the build tree. CMAKE_INSTALL_PREFIX is
# the expected deployment location used by creo-brl.dat, not a Creo SDK path.
set(CREO_BUNDLE_ROOT "${CMAKE_BINARY_DIR}/Creo")
set(CREO_BUNDLE_DIR "${CREO_BUNDLE_ROOT}/$<CONFIG>")
set(CREO_BUNDLE_BIN_DIR "${CREO_BUNDLE_DIR}/bin")
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${CREO_BUNDLE_DIR}" CACHE PATH "Creo-BRL deployment directory" FORCE)
endif()
# Report the status of all PATH dependent items
message("--")
message("-- #----------------------------------------------------------------------#")
message("-- # STATUS: Summary of PATH dependent items: #")
message("-- #----------------------------------------------------------------------#")
foreach(items ${path_dependent_items})
foreach(item ${${items}})
if(EXISTS ${item})
message("-- # Found: ${item}")
else()
message("-- # Missing: ${item}")
endif()
endforeach()
endforeach()
message("-- #----------------------------------------------------------------------#")
message("--")
# Set install dir as a function of the Creo directory
set(CMAKE_INSTALL_PREFIX ${CREO_ROOT_DIR} CACHE PATH "Installation path" FORCE)
mark_as_advanced(CMAKE_INSTALL_PREFIX)
# Bundle-specific usage and relocation notes.
set(CREO_BUNDLE_README "${CMAKE_CURRENT_BINARY_DIR}/README.bundle.txt")
file(WRITE "${CREO_BUNDLE_README}"
"Creo-BRL plugin bundle\n\n"
"Default deployment location:\n ${CMAKE_INSTALL_PREFIX}\n\n"
"To use this bundle, copy it to the deployment location and point Creo at\n"
"creo-brl.dat using protkdat, creotkdat, toolkit_registry_file, or the\n"
"Auxiliary Applications interface.\n\n"
"If the bundle is moved, update exec_file and text_dir in creo-brl.dat,\n"
"then update the Creo setting that points at creo-brl.dat. No files need\n"
"to be copied into the Creo installation directory.\n"
)
#----------------------------------------------------------------------#
# Establish Creo Specific C++ Compiler Settings #
#----------------------------------------------------------------------#
# Notes: #
# 1) Set these to match those found in Creo file "make_install_cxx" #
# 2) Located here: ..\Common Files\protoolkit\x86e_win64\obj\ #
# 2) Located here: ..\Common Files\protoolkit\<platform>\obj\ #
# 3) CMake handles include files separately (exclude the "-I" flag) #
# 4) Compiler options based upon MSVC runtime libraries: #
# a) /MT --> MultiThreaded #
@@ -187,8 +174,8 @@ if(NOT DEFINED BRLCAD_BUILDTEST_EXTERNALS)
# c) /MTd --> MultiThreadedDebug #
# d) /MDd --> MultiThreadedDebugDLL #
#----------------------------------------------------------------------#
# Set the default runtime library
# Set the default runtime library
set(CMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT "MultiThreaded")
message("-- #----------------------------------------------------------------------#")
@@ -200,68 +187,46 @@ if(NOT DEFINED BRLCAD_BUILDTEST_EXTERNALS)
message("--")
# Convert default flags to lists
string(REPLACE " " ";" c_flag_list "${CMAKE_C_FLAGS}")
string(REPLACE " " ";" c_flag_list "${CMAKE_C_FLAGS}")
string(REPLACE " " ";" cxx_flag_list "${CMAKE_CXX_FLAGS}")
# Remove unwanted default compiler flags
set(
remove_flags
/MD
/MTd
/D_DEBUG
/D
_DEBUG
)
set(remove_flags /MD /MTd /D_DEBUG /D _DEBUG)
foreach(flag ${remove_flags})
list(REMOVE_ITEM c_flag_list ${flag})
list(REMOVE_ITEM c_flag_list ${flag})
list(REMOVE_ITEM cxx_flag_list ${flag})
endforeach()
# Enforce use of the /MT and /EHsc flags
set(c_flag_list ${c_flag_list} /MT /EHsc)
set(c_flag_list ${c_flag_list} /MT /EHsc)
set(cxx_flag_list ${cxx_flag_list} /MT /EHsc)
# Append the Creo specific compiler options
set(cc_mach -DPRO_MACHINE=36 -DPRO_OS=4)
set(cc_flags -DPRO_USE_VAR_ARGS)
set(c_flag_list ${c_flag_list} ${cc_mach} ${cc_flags})
set(cc_mach -DPRO_MACHINE=36 -DPRO_OS=4)
set(cc_flags -DPRO_USE_VAR_ARGS)
set(c_flag_list ${c_flag_list} ${cc_mach} ${cc_flags})
set(cxx_flag_list ${cxx_flag_list} ${cc_mach} ${cc_flags})
# Remove duplicates
list(REMOVE_DUPLICATES c_flag_list)
list(REMOVE_DUPLICATES cxx_flag_list)
# BRL-CAD definitions. This standalone exporter consumes an installed
# BRL-CAD SDK rather than its CMake targets, so import definitions must be
# supplied explicitly here.
set(
brlcad_defs
"-DHAVE_CONFIG_H"
"-DBRLCAD_DLL"
"-DBRLCADBUILD"
"-DBU_DLL_IMPORTS"
"-DBN_DLL_IMPORTS"
"-DBV_DLL_IMPORTS"
"-DNMG_DLL_IMPORTS"
"-DBG_DLL_IMPORTS"
"-DBREP_DLL_IMPORTS"
"-DRT_DLL_IMPORTS"
"-DWDB_DLL_IMPORTS"
"-DTIE_DLL_IMPORTS"
"-DDB5_DLL_IMPORTS"
"-DOPENNURBS_IMPORTS"
)
# BRL-CAD definitions
set(brlcad_defs "-DHAVE_CONFIG_H" "-DBRLCAD_DLL" "-DBRLCADBUILD" "-DBU_DLL_IMPORTS"
"-DBN_DLL_IMPORTS" "-DBV_DLL_IMPORTS" "-DNMG_DLL_IMPORTS" "-DBG_DLL_IMPORTS"
"-DBREP_DLL_IMPORTS" "-DRT_DLL_IMPORTS" "-DWDB_DLL_IMPORTS" "-DTIE_DLL_IMPORTS"
"-DDB5_DLL_IMPORTS" "-DOPENNURBS_IMPORTS")
# Convert these to plain strings
string(REPLACE ";" " " brlcad_defs "${brlcad_defs}")
string(REPLACE ";" " " c_flag_list "${c_flag_list}")
string(REPLACE ";" " " brlcad_defs "${brlcad_defs}")
string(REPLACE ";" " " c_flag_list "${c_flag_list}")
string(REPLACE ";" " " cxx_flag_list "${cxx_flag_list}")
# Settings global to all configurations
set(CMAKE_C_FLAGS "${c_flag_list} ${brlcad_defs}" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS "${cxx_flag_list} ${brlcad_defs}" CACHE STRING "" FORCE)
set(CMAKE_C_FLAGS "${c_flag_list} ${brlcad_defs}" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS "${cxx_flag_list} ${brlcad_defs}" CACHE STRING "" FORCE)
set(CMAKE_SHARED_LINKER_FLAGS "/subsystem:console /machine:amd64" CACHE STRING "" FORCE)
set(CMAKE_EXE_LINKER_FLAGS "/subsystem:console /machine:amd64" CACHE STRING "" FORCE)
set(CMAKE_EXE_LINKER_FLAGS "/subsystem:console /machine:amd64" CACHE STRING "" FORCE)
message("-- #----------------------------------------------------------------------#")
message("-- # Current CMake compiler flags... #")
@@ -273,12 +238,11 @@ if(NOT DEFINED BRLCAD_BUILDTEST_EXTERNALS)
# Assign CMake include directories
include_directories(
${BRLCAD_INC_BRL_DIR}
${BRLCAD_INC_DIR}
${BRLCAD_INC_NRB_DIR}
${CREO_PTK_INC_DIR}
${CREO_PTK_APP_INC_DIR}
)
"${BRLCAD_INCLUDE_DIRS}"
"${CREO_PTK_INC_DIR}"
"${CREO_PTK_APP_INC_DIR}"
"${OPENNURBS_INCLUDE_DIRS}"
)
#----------------------------------------------------------------------#
# When doing development, to avoid the need to unlock DLLs and EXEs #
@@ -294,9 +258,9 @@ if(NOT DEFINED BRLCAD_BUILDTEST_EXTERNALS)
# but will not halt the configure process. #
#----------------------------------------------------------------------#
file(STRINGS ${CREO_PSF_TXT} psf_strs)
file(STRINGS "${CREO_PSF_TXT}" psf_strs)
foreach(pstr ${psf_strs})
if(${pstr} MATCHES ".*CREOPMA_FEATURE_NAME.*")
if("${pstr}" MATCHES ".*CREOPMA_FEATURE_NAME.*")
set(CFN_STR ${pstr})
string(REGEX REPLACE ".*CREOPMA_FEATURE_NAME.*[(]" "" CFN_STR "${CFN_STR}")
string(REGEX REPLACE "[)].*" "" CFN_STR "${CFN_STR}")
@@ -318,136 +282,101 @@ if(NOT DEFINED BRLCAD_BUILDTEST_EXTERNALS)
message("-- # safely ignored as long as the UNLOCK step is performed. #")
message("-- #----------------------------------------------------------------------#")
message("--")
message("-- #----------------------------------------------------------------------#")
message("-- # NOTICE: For installation follow this BUILD sequence #")
message("-- #----------------------------------------------------------------------#")
message("-- # BUILD: #")
message("-- # 1) creo-brl #")
message("-- # 2) unlock #")
message("-- # 3) install #")
message("-- #----------------------------------------------------------------------#")
message("--")
endif()
endif()
endif()
endforeach()
#----------------------------------------------------------------------#
# We will need copies of the BRL-CAD DLLs along with the creo-brl.dll #
# to make a stand-alone package, and we want the dlls in the same #
# directories as our build target dirs for the .exe version to find. #
# We will link against the .lib files so we will build that list at #
# the same time. #
#----------------------------------------------------------------------#
set(
BRLCAD_LIBS
libbg
libbn
libbrep
libbu
libbv
libnmg
librt
libwdb
lmdb
openNURBS
regex_brl
z_brl
)
set(BRLCAD_STATIC_LIBS)
set(brlcadlibs_notinstalled)
foreach(blib ${BRLCAD_LIBS})
configure_file(${BRLCAD_BIN_DIR}/${blib}.dll ${CMAKE_CURRENT_BINARY_DIR}/${blib}.dll COPYONLY)
set(BRLCAD_STATIC_LIBS ${BRLCAD_STATIC_LIBS} "${BRLCAD_LIB_DIR}/${blib}.lib")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${blib}.dll" DESTINATION ${CREO_OBJ_REL})
if(NOT EXISTS "${CREO_OBJ_DIR}/${blib}.dll")
set(brlcadlibs_notinstalled ${brlcadlibs_notinstalled} ${blib}.dll)
endif()
endforeach()
if(brlcadlibs_notinstalled)
message("-- #----------------------------------------------------------------------#")
message("-- # WARNING: The following OBJECT libraries(s) are not installed: #")
message("-- #----------------------------------------------------------------------#")
message("-- #")
message("-- # Location = ${CREO_OBJ_DIR}")
message("-- #")
foreach(item ${brlcadlibs_notinstalled})
message("-- # ${item}")
endforeach()
message("-- #")
message("-- #----------------------------------------------------------------------#")
message("-- # Attempting to load the DLL version of the plugin without these files #")
message("-- # in place will cause the loading process to silently fail. Therefore #")
message("-- # *NO* messages indicating why the loading failed will be generated. #")
message("-- # Be sure to run the INSTALL command after building but before testing #")
message("-- # this CREO2BRL API plugin with Creo. #")
message("-- # #")
message("-- # For additional information see: #")
message("-- # #")
message("-- # https://apps.dtic.mil/sti/pdfs/AD1036571.pdf #")
message("-- # #")
message("-- #----------------------------------------------------------------------#")
message("--")
endif()
#----------------------------------------------------------------------#
# Primary (DLL) version of plugin #
#----------------------------------------------------------------------#
# The build produces a self-contained bundle under: #
# #
# To run the DLL version of this plugin successfully, the files shown #
# below must be pre-installed within the Creo installation: #
# #
# --> C:/Program Files/PTC/Creo ${CREO_VERSION_NUMBER} <-- #
# #
# Files Creo Installation Sub-Directory #
# ------------------------------------------------------------------ #
# BRL-CAD dlls --> Common Files/protoolkit/${WIN_OS_VERSION}/obj #
# creo_brl.dat --> Common Files/protoolkit #
# creo_brl.res --> Common Files/text/resource #
# creo-brl-msg.txt --> Common Files/text/usascii #
# ------------------------------------------------------------------ #
# #
# The simplest thing to do is build a package and install it in the #
# Creo root directory. #
# #
# WARNING: Any attempt run this plugin without the correct DLL files #
# in place will result in silent failure at the loading step. #
# #
# For additional information see: #
# #
# https://apps.dtic.mil/sti/pdfs/AD1036571.pdf #
# ${CMAKE_BINARY_DIR}/Creo/<config>/ #
# bin/ plugin and BRL-CAD runtime DLLs #
# text/ Creo messages and resources #
# config/ default user profile #
# creo-brl.dat #
# README.txt #
# #
# CMAKE_INSTALL_PREFIX defines the expected deployment location #
# embedded in creo-brl.dat. #
#----------------------------------------------------------------------#
# Win32 libraries
set(
WIN_LIBS
#libcmt.lib
kernel32.lib
user32.lib
wsock32.lib
# Win32 libraries (excludes libcmt.lib)
set(WIN_LIBS
advapi32.lib
mpr.lib
winspool.lib
netapi32.lib
psapi.lib
gdi32.lib
shell32.lib
comdlg32.lib
gdi32.lib
kernel32.lib
mpr.lib
netapi32.lib
ole32.lib
psapi.lib
shell32.lib
user32.lib
version.lib
winmm.lib
winspool.lib
ws2_32.lib
)
wsock32.lib
)
add_library(creo-brl-core SHARED ${CREO2BRL_CORE_SOURCES})
set_property(TARGET creo-brl-core APPEND PROPERTY COMPILE_DEFINITIONS BRLCADBUILD HAVE_CONFIG_H)
target_link_libraries(creo-brl-core REGEX::REGEX ${WIN_LIBS} ${CREO_BRLCAD_LIBS})
set_target_properties(creo-brl-core PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CREO_BUNDLE_BIN_DIR}")
add_library(creo-brl SHARED
loader.c
frontend.cpp
snapshot_writer.cpp)
target_link_libraries(creo-brl ${WIN_LIBS} ${CREO_PTK_DLL_LIBS})
set_target_properties(creo-brl PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CREO_BUNDLE_BIN_DIR}")
add_dependencies(creo-brl creo-brl-core)
add_library(creo-brl SHARED ${CREO2BRL_SOURCES})
set_property(TARGET creo-brl APPEND PROPERTY COMPILE_DEFINITIONS BRLCADBUILD HAVE_CONFIG_H)
target_link_libraries(creo-brl ${WIN_LIBS} ${CREO_PTK_DLL_LIBS} ${BRLCAD_STATIC_LIBS} REGEX::REGEX)
install(TARGETS creo-brl RUNTIME DESTINATION ${CREO_OBJ_REL})
set(DAT_STARTUP "dll")
set(DAT_EXEC_FILE "${CREO_OBJ_DIR}/creo-brl.dll")
set(DAT_TEXT_DIR ${CREO_MSG_DIR})
configure_file(creo-brl.dat.in ${CMAKE_CURRENT_BINARY_DIR}/creo-brl.dat @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/creo-brl.dat" DESTINATION ${CREO_PTK_REL})
set(DAT_EXEC_FILE "${CMAKE_INSTALL_PREFIX}/bin/creo-brl.dll")
set(DAT_TEXT_DIR "${CMAKE_INSTALL_PREFIX}/text")
configure_file(creo-brl.dat.in "${CMAKE_CURRENT_BINARY_DIR}/creo-brl.dat" @ONLY)
file(GLOB RESOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/resources/*.res")
add_custom_command(TARGET creo-brl POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E make_directory
"${CREO_BUNDLE_BIN_DIR}"
"${CREO_BUNDLE_DIR}/text/usascii"
"${CREO_BUNDLE_DIR}/text/resource"
"${CREO_BUNDLE_DIR}/config"
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
"${CMAKE_CURRENT_BINARY_DIR}/creo-brl.dat" "${CREO_BUNDLE_DIR}/creo-brl.dat"
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
"${CREO_BUNDLE_README}" "${CREO_BUNDLE_DIR}/README.txt"
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
"${CMAKE_CURRENT_SOURCE_DIR}/resources/creo-brl-msg.txt" "${CREO_BUNDLE_DIR}/text/usascii/creo-brl-msg.txt"
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
"${CMAKE_CURRENT_SOURCE_DIR}/resources/ptc_materials.mtl" "${CREO_BUNDLE_DIR}/text/usascii/ptc_materials.mtl"
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
${RESOURCE_FILES} "${CREO_BUNDLE_DIR}/text/resource"
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
"${CMAKE_CURRENT_SOURCE_DIR}/resources/Creo_to_BRL.g" "${CREO_BUNDLE_DIR}/config/Creo_to_BRL.g"
COMMAND_EXPAND_LISTS
COMMENT "Assembling Creo-BRL bundle in ${CREO_BUNDLE_ROOT}/$<CONFIG>"
)
# Stage the BRL-CAD runtime DLL set alongside the facade and core.
add_custom_command(TARGET creo-brl-core POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
${CREO_BRLCAD_RUNTIME_DLLS} "${CREO_BUNDLE_BIN_DIR}"
COMMAND_EXPAND_LISTS
)
# Keep install/CPack output identical to the build-tree bundle layout.
install(TARGETS creo-brl creo-brl-core RUNTIME DESTINATION bin)
install(FILES ${CREO_BRLCAD_RUNTIME_DLLS} DESTINATION bin)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/creo-brl.dat" DESTINATION .)
install(FILES "${CREO_BUNDLE_README}" DESTINATION . RENAME README.txt)
install(FILES resources/creo-brl-msg.txt resources/ptc_materials.mtl DESTINATION text/usascii)
install(FILES ${RESOURCE_FILES} DESTINATION text/resource)
install(FILES resources/Creo_to_BRL.g DESTINATION config)
#----------------------------------------------------------------------#
# Debugging executable version of plugin - only use this if necessary. #
@@ -456,74 +385,66 @@ if(NOT DEFINED BRLCAD_BUILDTEST_EXTERNALS)
# but the DLL does not. Note that this is also identified as a #
# possible issue in the Creo dev documentation. #
#----------------------------------------------------------------------#
if(DEFINED CREO_EXEC_PLUGIN)
add_executable(creo-brl-exe ${CREO2BRL_SOURCES})
target_link_libraries(creo-brl-exe ${WIN_LIBS} ${CREO_PTK_EXE_LIBS} ${BRLCAD_STATIC_LIBS} REGEX::REGEX)
if(CREO_EXEC_PLUGIN)
add_executable(creo-brl-exe ${CREO2BRL_LEGACY_SOURCES} frontend.cpp)
target_link_libraries(creo-brl-exe REGEX::REGEX ${WIN_LIBS} ${CREO_PTK_EXE_LIBS} ${CREO_UCORE_LIB} ${CREO_UDATA_LIB} ${CREO_BRLCAD_LIBS})
set_target_properties(creo-brl-exe PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CREO_BUNDLE_BIN_DIR}")
set_property(TARGET creo-brl-exe APPEND PROPERTY COMPILE_DEFINITIONS TINYCTHREAD_DLL_IMPORTS CREO_EXEC_PLUGIN)
set(DAT_STARTUP "spawn")
set(DAT_EXEC_FILE "${CMAKE_CURRENT_BINARY_DIR}/creo-brl-exe.exe")
set(DAT_TEXT_DIR ${CREO_MSG_DIR})
set(DAT_EXEC_FILE "${CMAKE_INSTALL_PREFIX}/bin/creo-brl-exe.exe")
set(DAT_TEXT_DIR "${CMAKE_INSTALL_PREFIX}/text")
configure_file(creo-brl.dat.in "${CMAKE_CURRENT_BINARY_DIR}/creo-brl-debug.dat" @ONLY)
set_property(TARGET creo-brl-exe APPEND PROPERTY COMPILE_DEFINITIONS "TINYCTHREAD_DLL_IMPORTS")
endif()
# Install the resource files
file(GLOB RESOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/resources/*.res)
set(rfiles_installed 1)
foreach(rfile ${RESOURCE_FILES})
install(FILES ${rfile} DESTINATION ${CREO_RES_REL})
get_filename_component(rfilename ${rfile} NAME)
if(NOT EXISTS "${CREO_RES_DIR}/${rfilename}")
set(rfiles_installed 0)
endif()
endforeach()
# Install the material translation file
install(FILES resources/ptc_materials.mtl DESTINATION ${CREO_MSG_REL})
# Install the messages file
install(FILES resources/creo-brl-msg.txt DESTINATION ${CREO_MSG_REL})
if(NOT EXISTS "${CREO_MSG_DIR}/creo-brl-msg.txt" OR NOT rfiles_installed)
message("-- #----------------------------------------------------------------------#")
message("-- # WARNING: CREO2BRL resource files are not installed... #")
message("-- #----------------------------------------------------------------------#")
message("-- # Note that even with the EXE version of the plugin, the resource #")
message("-- # files must be present in the correct locations within the CREO #")
message("-- # installation in order to successfully run the plugin. Be sure to #")
message("-- # run the INSTALL target before starting a testing session. #")
message("-- #----------------------------------------------------------------------#")
message("--")
add_custom_command(TARGET creo-brl-exe POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
"${CMAKE_CURRENT_BINARY_DIR}/creo-brl-debug.dat" "${CREO_BUNDLE_DIR}/creo-brl-debug.dat"
)
install(TARGETS creo-brl-exe RUNTIME DESTINATION bin)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/creo-brl-debug.dat" DESTINATION .)
endif()
message("--")
message("-- #----------------------------------------------------------------------#")
message("-- # NOTICE: Creo-BRL bundle #")
message("-- #----------------------------------------------------------------------#")
message("-- # Build output : ${CREO_BUNDLE_ROOT}/<config>")
message("-- # Deploy target: ${CMAKE_INSTALL_PREFIX}")
message("-- # Run UNLOCK after building and before distributing the bundle. #")
message("-- #----------------------------------------------------------------------#")
message("--")
#----------------------------------------------------------------------#
# Create the UNLOCK target #
#----------------------------------------------------------------------#
add_custom_target(
UNLOCK
COMMAND "${CREO_PTK_UNLOCKER}" ${CMAKE_CURRENT_BINARY_DIR}/$(configuration)/creo-brl.dll
DEPENDS creo-brl
if(CREO_EXEC_PLUGIN)
set(CREO_PTK_UNLOCK_EXE_COMMAND
COMMAND "${CMAKE_COMMAND}" -E env "PROCESSOR_ARCHITECTURE=AMD64"
"${CREO_PTK_UNLOCKER}" "$<TARGET_FILE:creo-brl-exe>")
set(CREO_PTK_UNLOCK_EXE_DEPENDENCY creo-brl-exe)
endif()
add_custom_target(UNLOCK
COMMAND "${CMAKE_COMMAND}" -E env "PROCESSOR_ARCHITECTURE=AMD64"
"${CREO_PTK_UNLOCKER}" "$<TARGET_FILE:creo-brl>"
${CREO_PTK_UNLOCK_EXE_COMMAND}
DEPENDS creo-brl creo-brl-core ${CREO_PTK_UNLOCK_EXE_DEPENDENCY}
COMMENT "Unlocking Creo-BRL dll"
)
#----------------------------------------------------------------------#
# Since we need to run "INSTALL" as part of normal development, it is #
# worthwhile to provide an "UNINSTALL" target to automate the cleanup. #
# Provide an UNINSTALL target for users who deploy the bundle with the #
# CMake install target rather than copying the staged directory. #
#----------------------------------------------------------------------#
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE
@ONLY
)
add_custom_target(
UNINSTALL
IMMEDIATE @ONLY)
add_custom_target(UNINSTALL
COMMAND "${CMAKE_COMMAND}" -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
COMMENT "Removing installed CREO2BRL components..."
)
)
set(CPACK_GENERATOR NSIS ZIP)
set(CPACK_GENERATOR ZIP)
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Creo to BRL-CAD exporter for PTC's Creo Parametric")
set(CPACK_PACKAGE_VENDOR "BRL-CAD Development Team")
#TODO CPACK_RESOURCE_FILE_README and CPACK_RESOURCE_FILE_LICENSE)
@@ -532,40 +453,31 @@ if(NOT DEFINED BRLCAD_BUILDTEST_EXTERNALS)
set(CPACK_PACKAGE_VERSION_PATCH ${DD})
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 0)
include(CPack)
else(NOT DEFINED BRLCAD_BUILDTEST_EXTERNALS)
#----------------------------------------------------------------------#
# Start building the EXTERNALS in Creo, Cubit, Unigraphics #
#----------------------------------------------------------------------#
brlcad_find_package(REGEX REQUIRED)
set(
CREO_DIRS
"${CMAKE_CURRENT_BINARY_DIR}/../../../include"
"${CMAKE_CURRENT_SOURCE_DIR}/../../../include"
)
set(CREO_DIRS
"${BRLCAD_BINARY_DIR}/${INCLUDE_DIR}"
"${BRLCAD_SOURCE_DIR}/${INCLUDE_DIR}"
"${OPENNURBS_INCLUDE_DIRS}"
)
BRLCAD_INCLUDE_DIRS(creo-brl "${CREO_DIRS}" PUBLIC)
#----------------------------------------------------------------------#
# The build shims aren't so great at mocking the initialization #
# behavior of the real code. #
#----------------------------------------------------------------------#
check_cxx_flag("Wno-maybe-uninitialized")
CHECK_CXX_FLAG("Wno-maybe-uninitialized")
set(CREO2BRL_SOURCES ${CREO2BRL_SOURCES} shim.cpp)
set(CREO2BRL_SOURCES ${CREO2BRL_LEGACY_SOURCES} shim.cpp)
add_library(creo-brl ${CREO2BRL_SOURCES})
target_include_directories(creo-brl BEFORE PRIVATE ${CREO_DIRS})
set_property(TARGET creo-brl APPEND PROPERTY COMPILE_DEFINITIONS TEST_BUILD BRLCADBUILD HAVE_CONFIG_H)
target_link_libraries(
creo-brl
librt
libwdb
libbrep
libbg
libnmg
libbv
libbn
libbu
REGEX::REGEX
${WINSOCK_LIB}
)
target_link_libraries(creo-brl librt libwdb libbrep libbg libnmg libbv libbn libbu REGEX::REGEX)
set_target_properties(creo-brl PROPERTIES FOLDER "BRL-CAD Executables/Build Only")
if(HIDE_INTERNAL_SYMBOLS)
set_property(TARGET creo-brl APPEND PROPERTY COMPILE_DEFINITIONS "BU_DLL_IMPORTS")
@@ -578,26 +490,31 @@ else(NOT DEFINED BRLCAD_BUILDTEST_EXTERNALS)
set_property(TARGET creo-brl APPEND PROPERTY COMPILE_DEFINITIONS "DB5_DLL_IMPORTS")
set_property(TARGET creo-brl APPEND PROPERTY COMPILE_DEFINITIONS "WDB_DLL_IMPORTS")
set_property(TARGET creo-brl APPEND PROPERTY COMPILE_DEFINITIONS "TIE_DLL_IMPORTS")
set_property(TARGET creo-brl APPEND PROPERTY COMPILE_DEFINITIONS "OPENNURBS_IMPORTS")
endif()
# Distcheck file list
set(
creo_dist_files
set(creo_dist_files
${CREO2BRL_SOURCES}
${CREO2BRL_CORE_SOURCES}
loader.c
frontend.cpp
README.txt
cmake_uninstall.cmake.in
creo-brl.dat.in
creo-brl.h
conversion_snapshot.h
part_writer.h
profile_controls.h
snapshot_writer.cpp
snapshot_writer.h
resources/creo-brl-msg.txt
resources/creo_brl.res
resources/ptc_materials.mtl
shim.h
)
cmakefiles(${creo_dist_files})
cmakefiles(CMakeLists.txt)
# On some platforms distclean has additional cleanup to do
distclean("${CMAKE_BINARY_DIR}/${BIN_DIR}/creo-brl.pdb")
)
CMAKEFILES(${creo_dist_files})
CMAKEFILES(CMakeLists.txt)
endif(NOT DEFINED BRLCAD_BUILDTEST_EXTERNALS)
+67 -45
View File
@@ -2,7 +2,7 @@
* A S S E M B L Y . C P P
* BRL-CAD
*
* Copyright (c) 2017-2026 United States Government as represented by
* Copyright (c) 2017-2024 United States Government as represented by
* the U.S. Army Research Laboratory.
*
* This program is free software; you can redistribute it and/or
@@ -29,7 +29,6 @@
/* Assembly processing container */
struct assem_conv_info {
struct creo_conv_info *cinfo; /* Global state */
ProMdl curr_parent;
struct wmember *wcmb;
};
@@ -94,9 +93,9 @@ find_empty_assemblies(struct creo_conv_info *cinfo)
wchar_t *stable = stable_wchar(cinfo, *d_it);
ProWstringToString(ename, *d_it);
if (!stable)
creo_log(cinfo, MSG_PLAIN, " ASSEM: \"%s\" is empty, but no stable version of name found\n", ename);
creo_log(cinfo, MSG_ASSEM, "\"%s\" is empty, but no stable version of name found\n", ename);
else {
creo_log(cinfo, MSG_PLAIN, " ASSEM: All contents of \"%s\" are empty, skipping...\n", ename);
creo_log(cinfo, MSG_ASSEM, "All contents of \"%s\" are empty, skipping...\n", ename);
cinfo->empty->insert(stable);
steady_state = 0;
}
@@ -134,7 +133,7 @@ is_non_identity(ProMatrix xform)
* particular member (assembly/member)
*/
extern "C" ProError
assembly_entry_matrix(struct creo_conv_info *cinfo, ProMdl parent, ProFeature *feat, mat_t *mat)
assembly_entry_matrix(struct creo_conv_info *cinfo, ProFeature *feat, mat_t *mat)
{
if(!feat || !mat)
return PRO_TK_GENERAL_ERROR;
@@ -142,40 +141,49 @@ assembly_entry_matrix(struct creo_conv_info *cinfo, ProMdl parent, ProFeature *f
ProAsmcomppath comp_path;
ProError err = PRO_TK_GENERAL_ERROR;
ProIdTable id_table;
ProMdlfileType ftype;
ProMatrix xform;
ProMdl parent = cinfo->curr_parent;
ProMdlfileType ftype;
/* Get strings in case we need to log */
wchar_t waname[CREO_NAME_MAX];
char aname[CREO_NAME_MAX];
wchar_t wpname[CREO_NAME_MAX];
char pname[CREO_NAME_MAX];
wchar_t wcname[CREO_NAME_MAX];
char cname[CREO_NAME_MAX];
/* Retrieve the parent (assembly) name */
(void)ProMdlMdlnameGet(parent, wpname);
ProWstringToString(pname, wpname);
lower_case(pname);
/* Retrieve the model name (assembly) name */
(void)ProMdlMdlnameGet(parent, waname);
ProWstringToString(aname, waname);
lower_case(aname);
/* Retrieve the assembly component (part) name */
(void)ProAsmcompMdlMdlnameGet(feat, &ftype, wcname);
ProWstringToString(cname, wcname);
lower_case(cname);
(void)ProAsmcompMdlMdlnameGet(feat, &ftype, wpname);
ProWstringToString(pname, wpname);
lower_case(pname);
/* Find the Creo matrix, obtain the path */
id_table[0] = feat->id;
err = ProAsmcomppathInit(ProMdlToSolid(parent), id_table, 1, &comp_path);
if (err != PRO_TK_NO_ERROR) {
creo_log(cinfo, MSG_PLAIN, "FAILURE: Unknown path from \"%s\" to \"%s\", aborting...\n", pname, cname);
creo_log(cinfo, MSG_FAIL, "Unknown path from \"%s\" to \"%s\", aborting...\n", aname, pname);
return err;
}
/* Accumulate the xform matrix along the path created above */
err = ProAsmcomppathTrfGet(&comp_path, PRO_B_TRUE, xform);
if (err != PRO_TK_NO_ERROR) {
creo_log(cinfo, MSG_PLAIN, "FAILURE: Transformation matrix for \"%s\" failed: \"%s/%s\", aborting...\n", pname, pname, cname);
creo_log(cinfo, MSG_FAIL, "Transformation matrix for \"%s\" failed: \"%s/%s\", aborting...\n", aname, aname, pname);
return err;
}
/* Retain current PTC xform matrix for later use */
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
cinfo->curr_xform[i][j] = xform[i][j];
/* Report the current PTC xform matrix */
/* report_xform(cinfo, pname); */
/*
* Notes:
*
@@ -188,7 +196,7 @@ assembly_entry_matrix(struct creo_conv_info *cinfo, ProMdl parent, ProFeature *f
*
* 2) Substitutes unit conversion factor for Creo
*
* with: m = n = o = cinfo->creo_to_brl_conv
* with: m = n = o = cinfo->main_to_mm
*
*/
if (is_non_identity(xform)) {
@@ -196,7 +204,7 @@ assembly_entry_matrix(struct creo_conv_info *cinfo, ProMdl parent, ProFeature *f
for (int j = 0; j < 4; j++)
for (int i = 0; i < 4; i++) {
if (i == 3 && j < 3)
bu_vls_printf(&mstr, " %.12e", xform[i][j] * cinfo->creo_to_brl_conv);
bu_vls_printf(&mstr, " %.12e", xform[i][j] * cinfo->main_to_mm);
else
bu_vls_printf(&mstr, " %.12e", xform[i][j]);
}
@@ -263,7 +271,7 @@ assembly_write_entry(ProFeature *feat, ProError UNUSED(status), ProAppData app_d
* Get matrix relative to current parent (if any) and create the
* comb entry
*/
err = assembly_entry_matrix(ainfo->cinfo, ainfo->curr_parent, feat, &xform);
err = assembly_entry_matrix(ainfo->cinfo, feat, &xform);
if (err == PRO_TK_NO_ERROR)
(void)mk_addmember(bu_vls_addr(entry_name), &(ainfo->wcmb->l), xform, WMOP_UNION);
else
@@ -275,11 +283,11 @@ assembly_write_entry(ProFeature *feat, ProError UNUSED(status), ProAppData app_d
/** Only run this *after* find_empty_assemblies has been run */
extern "C" ProError
output_assembly(struct creo_conv_info *cinfo, ProMdl model)
output_assembly(struct creo_conv_info *cinfo)
{
ProError err = PRO_TK_GENERAL_ERROR;
ProError err = PRO_TK_GENERAL_ERROR;
ProMassProperty massprops;
ProMdl parent = cinfo->curr_parent;
struct bu_vls *comb_name;
struct bu_vls *obj_name;
@@ -301,20 +309,20 @@ output_assembly(struct creo_conv_info *cinfo, ProMdl model)
/* We'll need to assemble the list of children */
struct wmember wcomb;
BU_LIST_INIT(&wcomb.l);
/* Initial comb setup */
char cname[CREO_NAME_MAX];
(void)ProMdlMdlnameGet(model, wname);
ProWstringToString(cname, wname);
lower_case(cname);
ainfo->curr_parent = model;
ainfo->wcmb = &wcomb;
/* Initial comb setup */
char aname[CREO_NAME_MAX];
(void)ProMdlMdlnameGet(parent, wname);
ProWstringToString(aname, wname);
lower_case(aname);
/* Obtain assembly model units */
(void)creo_model_units(cinfo);
/* Add children */
ProSolidFeatVisit(ProMdlToPart(model), assembly_write_entry, (ProFeatureFilterAction)component_filter, (ProAppData)ainfo);
creo_log(cinfo, MSG_PLAIN, " ASSEM: All children of \"%s\" were visited\n", cname);
ProSolidFeatVisit(ProMdlToPart(parent), assembly_write_entry, (ProFeatureFilterAction)component_filter, (ProAppData)ainfo);
creo_log(cinfo, MSG_ASSEM, "All children of \"%s\" were visited\n", aname);
/* Get BRL-CAD name */
comb_name = get_brlcad_name(cinfo, wname, NULL, N_ASSEM);
@@ -334,15 +342,18 @@ output_assembly(struct creo_conv_info *cinfo, ProMdl model)
bu_avs_add(&cinfo->avs, "ptc_name", bu_vls_addr(obj_name));
ProWVerstamp cstamp;
if (ProMdlVerstampGet(model, &cstamp) == PRO_TK_NO_ERROR) {
if (ProMdlVerstampGet(parent, &cstamp) == PRO_TK_NO_ERROR) {
char *verstr;
if (ProVerstampStringGet(cstamp, &verstr) == PRO_TK_NO_ERROR)
bu_avs_add(&cinfo->avs, "ptc_version_stamp", verstr);
ProVerstampStringFree(&verstr);
}
/* Export user-supplied list of parameters */
param_export(cinfo, model, cname);
/* Set the assembly (parent) as the current model*/
cinfo->curr_model = parent;
/* Export user-supplied list of assembly parameters */
param_export(cinfo, aname);
/*
* Solid mass properties are handled separately in Creo,
@@ -350,32 +361,43 @@ output_assembly(struct creo_conv_info *cinfo, ProMdl model)
*/
struct bu_vls vstr = BU_VLS_INIT_ZERO;
err = ProSolidMassPropertyGet(ProMdlToSolid(model), NULL, &massprops);
err = ProSolidMassPropertyGet(ProMdlToSolid(parent), NULL, &massprops);
if (err == PRO_TK_NO_ERROR) {
if (massprops.volume > 0.0) {
bu_vls_sprintf(&vstr, "%g", massprops.volume);
bu_vls_sprintf(&vstr, "%g %s^3",
massprops.volume,
bu_vls_addr(cinfo->lunits));
bu_avs_add(&cinfo->avs, "volume", bu_vls_addr(&vstr));
bu_vls_free(&vstr);
}
if (massprops.surface_area > 0.0) {
bu_vls_sprintf(&vstr, "%g", massprops.surface_area);
bu_vls_sprintf(&vstr, "%g %s^2",
massprops.surface_area,
bu_vls_addr(cinfo->lunits));
bu_avs_add(&cinfo->avs, "surface_area", bu_vls_addr(&vstr));
bu_vls_free(&vstr);
}
if (massprops.density > 0.0) {
bu_vls_sprintf(&vstr, "%g", massprops.density);
bu_vls_sprintf(&vstr, "%g %s/%s^3",
massprops.density,
bu_vls_addr(cinfo->munits),
bu_vls_addr(cinfo->lunits));
bu_avs_add(&cinfo->avs, "density", bu_vls_addr(&vstr));
bu_vls_free(&vstr);
}
if (massprops.mass > 0.0) {
bu_vls_sprintf(&vstr, "%g", massprops.mass);
bu_vls_sprintf(&vstr, "%g %s",
massprops.mass,
bu_vls_addr(cinfo->munits));
bu_avs_add(&cinfo->avs, "mass", bu_vls_addr(&vstr));
bu_vls_free(&vstr);
}
bu_vls_free(&vstr);
}
/* Write */
db5_update_attributes(dp, &cinfo->avs, cinfo->wdbp->dbip);
creo_log(cinfo, MSG_PLAIN, " ASSEM: Conversion of assembly \"%s\" complete\n", cname);
creo_log(cinfo, MSG_ASSEM, "Conversion of assembly \"%s\" complete\n", aname);
/* Free local container */
BU_PUT(ainfo, struct assem_conv_info);
return PRO_TK_NO_ERROR;
+7 -13
View File
@@ -1,10 +1,7 @@
# Per https://cmake.org/Wiki/CMake_FAQ#Can_I_do_.22make_uninstall.22_with_CMake.3F
if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
message(
WARNING
"Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt. Note: uninstall only works after install has been run."
)
message(WARNING "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt. Note: uninstall only works after install has been run.")
else(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
@@ -12,16 +9,12 @@ else(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
message(STATUS "Uninstalling ${file}")
if(IS_SYMLINK "${file}" OR EXISTS "${file}")
exec_program(
"@CMAKE_COMMAND@"
ARGS
"-E remove \"${file}\""
OUTPUT_VARIABLE
rm_out
RETURN_VALUE
rm_retval
)
"@CMAKE_COMMAND@" ARGS "-E remove \"${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval
)
if(NOT "${rm_retval}" STREQUAL 0)
message(FATAL_ERROR "Problem when removing ${file}")
message(FATAL_ERROR "Problem when removing ${file}")
endif(NOT "${rm_retval}" STREQUAL 0)
else(IS_SYMLINK "${file}" OR EXISTS "${file}")
message(STATUS "File ${file} does not exist.")
@@ -35,3 +28,4 @@ endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8
+1285
View File
File diff suppressed because it is too large Load Diff
+264
View File
@@ -0,0 +1,264 @@
/**
* C O N V E R S I O N _ S N A P S H O T . H
* BRL-CAD
*
* Copyright (c) 2026 United States Government as represented by
* the U.S. Army Research Laboratory.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2.1 as published by the Free Software Foundation.
*/
/**
* @file conversion_snapshot.h
*
* Toolkit-free on-disk request contract between the Creo facade and core.
*
* Snapshot versions store little-endian IEEE 754 values. Every variable-size
* range is an absolute byte range in the snapshot and is length-bounded; no
* record relies on process pointers or null-terminated text.
*/
#ifndef CREO_CONVERSION_SNAPSHOT_H
#define CREO_CONVERSION_SNAPSHOT_H
#include <stdint.h>
#define CREO_BRL_SNAPSHOT_MAGIC_SIZE 8u
#define CREO_BRL_SNAPSHOT_FORMAT_VERSION_V1 1u
#define CREO_BRL_SNAPSHOT_FORMAT_VERSION_V2 2u
#define CREO_BRL_SNAPSHOT_FORMAT_VERSION CREO_BRL_SNAPSHOT_FORMAT_VERSION_V1
#define CREO_BRL_SNAPSHOT_HEADER_V1_SIZE 40u
#define CREO_BRL_SNAPSHOT_RANGE_SIZE 16u
#define CREO_BRL_SNAPSHOT_VECTOR_SIZE 24u
#define CREO_BRL_SNAPSHOT_TRIANGLE_SIZE 12u
#define CREO_BRL_SNAPSHOT_NAMED_VALUE_SIZE 32u
#define CREO_BRL_SNAPSHOT_SETTINGS_V1_SIZE 200u
#define CREO_BRL_SNAPSHOT_PART_V1_SIZE 316u
#define CREO_BRL_SNAPSHOT_SINGLE_PART_V1_SIZE 524u
#define CREO_BRL_SNAPSHOT_MATRIX_SIZE 128u
#define CREO_BRL_SNAPSHOT_ASSEMBLY_MEMBER_V2_SIZE 136u
#define CREO_BRL_SNAPSHOT_ASSEMBLY_V2_SIZE 64u
#define CREO_BRL_SNAPSHOT_SCENE_V2_SIZE 264u
#define CREO_BRL_SNAPSHOT_COORDINATE_COUNT 3u
#define CREO_BRL_SNAPSHOT_TRIANGLE_VERTEX_COUNT 3u
#define CREO_BRL_SNAPSHOT_COLOR_COMPONENT_COUNT 3u
#define CREO_BRL_SNAPSHOT_MATRIX_ELEMENT_COUNT 16u
#define CREO_BRL_SNAPSHOT_MIN_VERTEX_COUNT 3u
#define CREO_BRL_SNAPSHOT_MIN_TRIANGLE_COUNT 1u
static const unsigned char creo_brl_snapshot_magic[CREO_BRL_SNAPSHOT_MAGIC_SIZE] = {
'C', 'R', 'E', 'O', 'B', 'R', 'L', '\0'
};
enum creo_brl_snapshot_payload_type {
CREO_BRL_SNAPSHOT_PAYLOAD_SINGLE_PART = 1u,
CREO_BRL_SNAPSHOT_PAYLOAD_SCENE = 2u
};
enum creo_brl_snapshot_scene_node_type {
CREO_BRL_SNAPSHOT_SCENE_NODE_PART = 1u,
CREO_BRL_SNAPSHOT_SCENE_NODE_ASSEMBLY = 2u
};
enum creo_brl_snapshot_log_type {
CREO_BRL_SNAPSHOT_LOG_NONE = -1,
CREO_BRL_SNAPSHOT_LOG_FAILURE = 0,
CREO_BRL_SNAPSHOT_LOG_SUCCESS = 1,
CREO_BRL_SNAPSHOT_LOG_FAILURE_OR_SUCCESS = 2,
CREO_BRL_SNAPSHOT_LOG_ALL = 3
};
enum creo_brl_snapshot_xform_mode {
CREO_BRL_SNAPSHOT_XFORM_NONE = 0,
CREO_BRL_SNAPSHOT_XFORM_X_TO_Z = 1,
CREO_BRL_SNAPSHOT_XFORM_Y_TO_Z = 2
};
enum creo_brl_snapshot_chord_mode {
CREO_BRL_SNAPSHOT_CHORD_ABSOLUTE = 0,
CREO_BRL_SNAPSHOT_CHORD_RELATIVE = 1
};
enum creo_brl_snapshot_settings_flag {
CREO_BRL_SNAPSHOT_SETTING_ELIMINATE_SMALL_FEATURES = 1u << 0,
CREO_BRL_SNAPSHOT_SETTING_FACETS_ONLY = 1u << 1,
CREO_BRL_SNAPSHOT_SETTING_EXPORT_STL = 1u << 2,
CREO_BRL_SNAPSHOT_SETTING_CHECK_SOLIDITY = 1u << 3,
CREO_BRL_SNAPSHOT_SETTING_CREATE_BOXES = 1u << 4,
CREO_BRL_SNAPSHOT_SETTING_WRITE_NORMALS = 1u << 5
};
#define CREO_BRL_SNAPSHOT_SETTINGS_FLAG_MASK \
(CREO_BRL_SNAPSHOT_SETTING_ELIMINATE_SMALL_FEATURES | \
CREO_BRL_SNAPSHOT_SETTING_FACETS_ONLY | \
CREO_BRL_SNAPSHOT_SETTING_EXPORT_STL | \
CREO_BRL_SNAPSHOT_SETTING_CHECK_SOLIDITY | \
CREO_BRL_SNAPSHOT_SETTING_CREATE_BOXES | \
CREO_BRL_SNAPSHOT_SETTING_WRITE_NORMALS)
enum creo_brl_snapshot_part_flag {
CREO_BRL_SNAPSHOT_PART_HAS_MESH = 1u << 0,
CREO_BRL_SNAPSHOT_PART_HAS_BBOX_FALLBACK = 1u << 1,
CREO_BRL_SNAPSHOT_PART_HAS_NORMALS = 1u << 2,
CREO_BRL_SNAPSHOT_PART_HAS_COLOR = 1u << 3,
CREO_BRL_SNAPSHOT_PART_HAS_MATERIAL = 1u << 4,
CREO_BRL_SNAPSHOT_PART_HAS_MASS_PROPERTIES = 1u << 5
};
#define CREO_BRL_SNAPSHOT_PART_FLAG_MASK \
(CREO_BRL_SNAPSHOT_PART_HAS_MESH | \
CREO_BRL_SNAPSHOT_PART_HAS_BBOX_FALLBACK | \
CREO_BRL_SNAPSHOT_PART_HAS_NORMALS | \
CREO_BRL_SNAPSHOT_PART_HAS_COLOR | \
CREO_BRL_SNAPSHOT_PART_HAS_MATERIAL | \
CREO_BRL_SNAPSHOT_PART_HAS_MASS_PROPERTIES)
#pragma pack(push, 1)
struct creo_brl_snapshot_range {
uint64_t offset;
uint64_t size;
};
struct creo_brl_snapshot_vector {
double coordinates[CREO_BRL_SNAPSHOT_COORDINATE_COUNT];
};
struct creo_brl_snapshot_triangle {
uint32_t vertices[CREO_BRL_SNAPSHOT_TRIANGLE_VERTEX_COUNT];
};
struct creo_brl_snapshot_matrix {
double elements[CREO_BRL_SNAPSHOT_MATRIX_ELEMENT_COUNT];
};
struct creo_brl_snapshot_named_value {
struct creo_brl_snapshot_range name;
struct creo_brl_snapshot_range value;
};
struct creo_brl_snapshot_header {
unsigned char magic[CREO_BRL_SNAPSHOT_MAGIC_SIZE];
uint32_t format_version;
uint32_t header_size;
uint64_t snapshot_size;
uint32_t payload_type;
uint32_t reserved;
uint64_t payload_size;
};
struct creo_brl_snapshot_settings {
uint32_t structure_size;
uint32_t flags;
int32_t xform_mode;
int32_t chord_mode;
int32_t region_id;
int32_t min_luminance;
int32_t max_facets;
int32_t max_steps;
int32_t log_type;
uint32_t reserved;
double max_angle;
double min_angle;
double max_chord;
double min_chord;
double min_edge;
double min_hole;
double min_chamfer;
double min_round;
struct creo_brl_snapshot_range output_path;
struct creo_brl_snapshot_range log_path;
struct creo_brl_snapshot_range material_path;
struct creo_brl_snapshot_range stl_path;
struct creo_brl_snapshot_range rename_parameters;
struct creo_brl_snapshot_range preserve_parameters;
};
struct creo_brl_snapshot_part {
uint32_t structure_size;
uint32_t flags;
int32_t region_id;
uint32_t reserved;
double model_to_mm;
double bbox_diagonal;
double bbox_volume;
double bbox_area;
unsigned char color[CREO_BRL_SNAPSHOT_COLOR_COMPONENT_COUNT];
unsigned char color_is_set;
double density;
double mass;
double volume;
struct creo_brl_snapshot_vector bbox_min;
struct creo_brl_snapshot_vector bbox_max;
struct creo_brl_snapshot_range model_name;
struct creo_brl_snapshot_range model_version;
struct creo_brl_snapshot_range material_name;
struct creo_brl_snapshot_range vertices;
uint64_t vertex_count;
struct creo_brl_snapshot_range triangles;
uint64_t triangle_count;
struct creo_brl_snapshot_range normals;
uint64_t normal_count;
struct creo_brl_snapshot_range normal_indices;
uint64_t normal_index_count;
struct creo_brl_snapshot_range attributes;
uint64_t attribute_count;
struct creo_brl_snapshot_range parameters;
uint64_t parameter_count;
};
struct creo_brl_snapshot_single_part {
uint32_t structure_size;
uint32_t reserved;
struct creo_brl_snapshot_settings settings;
struct creo_brl_snapshot_part part;
};
/*
* V2 scenes reuse the V1 part record for each unique part definition. The
* member matrix is serialized in BRL-CAD mat_t order, with translation
* already converted to millimeters by the facade.
*/
struct creo_brl_snapshot_assembly_member {
uint32_t target_type;
uint32_t target_index;
struct creo_brl_snapshot_matrix matrix;
};
struct creo_brl_snapshot_assembly {
uint32_t structure_size;
uint32_t reserved;
struct creo_brl_snapshot_range model_name;
struct creo_brl_snapshot_range model_version;
struct creo_brl_snapshot_range members;
uint64_t member_count;
};
struct creo_brl_snapshot_scene {
uint32_t structure_size;
uint32_t reserved;
struct creo_brl_snapshot_settings settings;
struct creo_brl_snapshot_range parts;
uint64_t part_count;
struct creo_brl_snapshot_range assemblies;
uint64_t assembly_count;
uint32_t root_type;
uint32_t root_index;
};
#pragma pack(pop)
enum creo_brl_core_convert_result {
CREO_BRL_CORE_CONVERT_SUCCESS = 0,
CREO_BRL_CORE_CONVERT_INVALID_REQUEST = -1,
CREO_BRL_CORE_CONVERT_OPEN_FAILED = -2,
CREO_BRL_CORE_CONVERT_INVALID_SNAPSHOT = -3,
CREO_BRL_CORE_CONVERT_UNSUPPORTED_SNAPSHOT = -4,
CREO_BRL_CORE_CONVERT_NOT_IMPLEMENTED = -5,
CREO_BRL_CORE_CONVERT_OUTPUT_FAILED = -6
};
#endif /* CREO_CONVERSION_SNAPSHOT_H */
+16
View File
@@ -0,0 +1,16 @@
/**
* Toolkit-free lifecycle exports for the runtime-loaded backend.
*/
#include "common.h"
extern "C" __declspec(dllexport) int
creo_brl_core_initialize()
{
return 0;
}
extern "C" __declspec(dllexport) void
creo_brl_core_terminate()
{
}
+147 -85
View File
@@ -2,7 +2,7 @@
* C R E O - B R L . H
* BRL-CAD
*
* Copyright (c) 2017-2026 United States Government as represented by
* Copyright (c) 2017-2024 United States Government as represented by
* the U.S. Army Research Laboratory.
*
* This program is free software; you can redistribute it and/or
@@ -62,6 +62,7 @@ extern "C" {
#include <ProNotify.h>
#include <ProParameter.h>
#include <ProPart.h>
#include <ProSizeConst.h>
#include <ProSkeleton.h>
#include <ProSolid.h>
#include <ProSolidBody.h>
@@ -94,7 +95,11 @@ extern "C" {
#include "raytrace.h"
}
#define CREO_BRL_MSG_FILE "creo-brl-msg.txt"
#define CREO_BRL_MSG_FNAME "creo-brl-msg.txt"
#define CREO_PROFILE_FNAME "Creo_to_BRL.g"
#define CREO_UI_NAME "creo_brl"
#define BRLCAD_DB_FORMAT_LATEST 5
#define LOGGER_TYPE_NONE -1
#define LOGGER_TYPE_FAILURE 0
@@ -106,6 +111,9 @@ extern "C" {
#define XFORM_X_TO_Z 1
#define XFORM_Y_TO_Z 2
#define ABSOLUTE_CHORD 0
#define RELATIVE_CHORD 1
#define NAME_PARAMS 1
#define ATTR_PARAMS 2
@@ -123,17 +131,33 @@ extern "C" {
#define MAX_MATL_NAME 32 /* maximum allowed material name length */
#define MAX_LINE_SIZE 80 /* maximum allowed input line length */
#define MAX_LINE_BUFFER 128 /* maximum allowed input line buffer length */
#define MAX_FILE_RECS 256 /* maximum allowed material record count */
#define MAX_FILE_RECS 512 /* maximum allowed material record count */
#define MAX_UNIQUE_NAMES 65535 /* maximum unique name generation count */
#define MAX_RADIO_BTNS 4 /* maximum number of input panel radio buttons */
/* Log message types */
#define MSG_FAIL 0 /* Failure */
#define MSG_SUCCESS 1 /* Success */
#define MSG_DEBUG 2 /* Debug */
#define MSG_PLAIN 3 /* [unlabeled] */
#define MSG_STATUS 4 /* Status window only */
#define MSG_STATUS 3 /* Status window only */
#define MSG_PLAIN 4 /* [unlabeled] */
#define MSG_ASSEM 5 /* Assem */
#define MSG_COLOR 6 /* Color */
#define MSG_FEAT 7 /* Feat */
#define MSG_FILE 8 /* File */
#define MSG_MASS 9 /* Mass */
#define MSG_MATL 10 /* Matl */
#define MSG_MODEL 11 /* Model */
#define MSG_NAME 12 /* Name */
#define MSG_PARAM 13 /* Param */
#define MSG_PART 14 /* Part */
#define MSG_SOLID 15 /* Solid */
#define MSG_STRING 16 /* String */
#define MSG_TESS 17 /* Tess */
#define MSG_UNITS 18 /* Units */
#define MSG_WARN 19 /* Warning */
#define PRO_FEAT_DELETE_NO_OPTS 0 /* Feature delete options */
#define PRO_FEAT_DELETE_CLIP 1 /* Delete with children */
@@ -174,14 +198,12 @@ struct CharCmp {
}
};
struct WStrCmp {
bool operator()(wchar_t *str1, wchar_t *str2) const {
return (wcscmp(str1, str2) < 0);
}
};
/* structure to hold info about CSG operations for current part */
struct csg_ops {
char op;
@@ -197,71 +219,99 @@ struct empty_parts {
struct creo_conv_info {
struct bu_vls *out_fname; /* output file name */
struct bu_vls *logger_str; /* log file criteria */
struct bu_vls *log_fname; /* log file name */
struct bu_vls *out_fname; /* output file name */
struct bu_vls *log_mode; /* log file mode */
struct bu_vls *log_fname; /* log file name */
struct bu_vls *mtl_fname; /* material file name */
struct bu_vls *stl_fname; /* STL file name */
struct bu_vls *param_rename; /* renaming parameters */
struct bu_vls *param_save; /* preserved parameters */
struct bu_vls *curr_name; /* current part name */
struct bu_vls *comb_name; /* combination name */
struct bu_vls *main_name; /* top-level model name */
struct bu_vls *unitsys; /* unit system */
struct bu_vls *aunits; /* angle units */
struct bu_vls *funits; /* force units */
struct bu_vls *munits; /* mass units */
struct bu_vls *lunits; /* length units */
struct bu_vls *tunits; /* time units */
FILE *fplog; /* log file settings */
int logger_type;
int curr_msg_type;
FILE *fplog; /* log file ptr */
FILE *fpmtl; /* material file ptr */
FILE *fpstl; /* STL file ptr */
FILE *fpmtl; /* material file data */
char mtl_fname[MAXPATHLEN];
char mtl_key[MAX_MATL_NAME + 1];
ProMdl curr_model; /* current model */
ProMdl curr_parent; /* current parent model */
ProMatrix curr_xform; /* current xform matrix */
ProMdl main_model; /* top-level model */
ProMdlType main_type; /* top-level model type */
int curr_log_type; /* current log type */
int curr_msg_type; /* current msg type */
int curr_reg_id; /* current region id */
char mtl_key[MAX_MATL_NAME + 1]; /* material file data */
char mtl_str[MAX_FILE_RECS][MAX_MATL_NAME + 1];
int mtl_id[MAX_FILE_RECS];
int mtl_ids[MAX_FILE_RECS];
int mtl_los[MAX_FILE_RECS];
int mtl_ptr;
int mtl_rec;
int xform_mode; /* coordinate transformation mode */
int reg_id; /* region ident number (incremented with each part) */
int lmin; /* user-established minimum luminance threshold */
/* Conversion control values */
int xform_mode; /* coordinate transformation mode */
int region_counter; /* intial region counter */
int min_luminance; /* min luminance threshold */
int chord_mode; /* chord input mode */
int final_part; /* final part conversion */
/* units - model */
double creo_to_brl_conv; /* inches to mm */
double local_tol; /* tolerance in Creo units */
double local_tol_sq; /* tolerance squared */
/* Units - model */
double main_to_mm; /* convert top-level units to mm */
double part_to_mm; /* convert part units to mm */
double local_tol; /* tolerance in Creo units */
double local_tol_sq; /* tolerance squared */
/* Conversion control settings */
ProBool facets_only; /* flag to indicate no CSG should be done */
ProBool check_solidity; /* flag to control testing BoTs for solidity */
ProBool create_boxes; /* flag indicating that bounding boxes should replace failed parts */
ProBool get_normals; /* flag indicating surface normals should be extracted from geometry */
ProBool elim_small; /* flag indicating that small features are to be eliminated */
/* Conversion control indicators */
ProBool elim_small; /* eliminate small features */
ProBool facets_only; /* facetize everything (no CSG) */
ProBool export_stl; /* export facets to STL file */
ProBool check_solidity; /* check BoTs for solidity */
ProBool create_boxes; /* bounding box replaces failed part */
ProBool write_normals; /* write surface normals */
/* Tessellation settings */
double max_chord; /* max chord height in facetized approximation, mm */
double min_chord; /* min chord height in facetized approximation, mm */
double tol_dist; /* min distance between two distinct vertices, mm */
double max_angle; /* max angle control for tessellation ( 0.0 - 1.0 ) */
double min_angle; /* min angle control for tessellation ( 0.0 - 1.0 ) */
int max_steps; /* max number of tessellation attempts */
int tess_adapt; /* adaptive tessellation settings are in use */
double max_angle; /* max angle control, [rad] */
double min_angle; /* min angle control, [rad] */
double max_chord; /* max chord height, [L] */
double min_chord; /* min chord height, [L] */
double min_edge; /* min edge distance [L] */
int max_facets; /* max facet count */
int max_steps; /* max number attempts */
/* CSG settings */
double min_hole_diameter; /* if > 0.0, all holes features smaller than this will be deleted */
double min_chamfer_dim; /* if > 0.0, all chamfers with both dimensions less */
/* than this value will be deleted */
double min_round_radius; /* if > 0.0, all rounds with radius less than this */
/* value will be deleted */
double min_hole; /* ignores smaller hole diameters */
double min_chamfer; /* ignores smaller chamfer dimensions */
double min_round; /* ignores smaller blend radii */
/* Bounding box results */
double bbox_diag; /* bounding box diagonal, [L] */
double bbox_vol; /* bounding box volume, [L^3] */
double bbox_area; /* bounding box surface area, [L^2] */
double bbox_diag; /* box diagonal, [L] */
double bbox_vol; /* box volume, [L^3] */
double bbox_area; /* box surface area, [L^2] */
/* Tessellation results */
int tess_bbox; /* bounding box replaced failed tessellation */
int tess_count; /* number of tessellation facets */
double tess_chord; /* chord error, mm */
double tess_angle; /* angle error, deg */
int tess_bbox; /* bounding box replaced failed part */
int tess_faces; /* number of facets */
int tess_surfs; /* number of surfaces */
int tess_verts; /* number of vertices */
double tess_area; /* total surface area, [L^2] */
double tess_chord; /* chord height, [L] */
double tess_angle; /* angle control, rad */
/* Conversion Process results */
int asm_count; /* number of assemblies processed */
int asm_total; /* number of assemblies found */
int prt_count; /* number of parts processed */
int prt_total; /* number of parts found */
int rej_count; /* number of parts rejected */
/* ------ Internal ------ */
struct db_i *dbip; /* output database */
@@ -278,26 +328,25 @@ struct creo_conv_info {
std::set<struct bu_vls *, StrCmp> *creo_names; /* set of active creo id strings */
std::vector<char *> *obj_name_params; /* model parameters used to create object names */
std::vector<char *> *obj_attr_params; /* model parameters preserved as object attributes */
int warn_feature_unsuppress; /* flag to determine if we need to warn the user feature unsuppression failed */
int warn_feature_resume; /* flag for user warning when feature resume failed */
};
/* Part processing container */
struct part_conv_info {
struct creo_conv_info *cinfo; /* global state */
int csg_holes_supported;
ProMdl model;
std::vector<int> *suppressed_features; /* list of features to suppress when generating output. */
std::vector<struct directory *> *subtractions; /* objects to subtract from primary shape. */
/* generic feature suppression processing parameters */
/* Generic feature suppression processing parameters */
ProFeature *feat;
ProFeattype type;
double radius;
double diameter;
double distance1;
double distance2;
int got_diameter;
int got_distance1;
double dist1;
double dist2;
int ok_dia;
int ok_dist;
};
/* Generic container used when we need to pass around something in addition to creo_conv_info */
@@ -307,38 +356,52 @@ struct adata {
};
/* assembly */
extern "C" void find_empty_assemblies(struct creo_conv_info *);
extern "C" ProError output_assembly(struct creo_conv_info *, ProMdl model);
extern "C" ProError assembly_entry_matrix(struct creo_conv_info *, ProMdl parent, ProFeature *, mat_t *);
extern "C" void find_empty_assemblies(struct creo_conv_info *); /* find_empty_assemblies */
extern "C" ProError output_assembly(struct creo_conv_info *); /* output_assembly */
extern "C" ProError assembly_entry_matrix(struct creo_conv_info *, ProFeature *, mat_t *); /* assembly_entry_matrix */
/* part */
extern "C" ProError output_part(struct creo_conv_info *, ProMdl model);
extern "C" ProError output_part(struct creo_conv_info *); /* output_part */
/* util */
extern "C" ProError component_filter(ProFeature *, ProAppData *);
extern "C" void creo_log(struct creo_conv_info *, int, const char *, ...);
extern "C" ProError creo_model_units(double *, ProMdl);
extern "C" char * creo_param_name(struct creo_conv_info *, wchar_t *, int);
extern "C" ProError creo_param_val(char **, const char *, ProMdl );
extern "C" int find_matl(struct creo_conv_info *);
/* "C" struct bu_vls * get_brlcad_name (see comments below) */
extern "C" int get_mtl_input(FILE *, char *, int *, int *);
extern "C" void lower_case( char *);
extern "C" ProError param_append(void *, ProError, ProAppData);
extern "C" ProError param_collect(ProModelitem *, ProParameter **);
extern "C" void param_export(struct creo_conv_info *, ProMdl, const char *);
extern "C" ProError param_preserve(struct creo_conv_info *, ProMdl , const char *);
extern "C" ProError params_to_attrs(struct creo_conv_info *, ProMdl, ProParameter *);
extern "C" void parse_param_list(struct creo_conv_info *, const char *, int);
extern "C" ProError PopupMsg(const char *, const char *);
extern "C" ProError regex_key(ProParameter *, ProError, ProAppData );
extern "C" int rgb4lmin(double *, int);
extern "C" void scrub_vls(struct bu_vls *);
extern "C" wchar_t* stable_wchar(struct creo_conv_info *, wchar_t *);
extern "C" void trim(char *);
extern "C" double wstr_to_double(struct creo_conv_info *, wchar_t *);
extern "C" long int wstr_to_long(struct creo_conv_info *, wchar_t *);
extern "C" ProError component_filter(ProFeature *, ProAppData *); /* component_filter */
extern "C" void creo_log(struct creo_conv_info *, int, const char *, ...); /* creo_log */
extern "C" ProError creo_conv_to_mm(double *, ProMdl); /* creo_conv_to_mm */
extern "C" ProError creo_model_units(struct creo_conv_info *); /* creo_model_units */
extern "C" char * creo_param_name(struct creo_conv_info *, wchar_t *, int); /* creo_param_name */
extern "C" ProError creo_param_val(char **, const char *, ProMdl); /* creo_param_val */
extern "C" int find_btn_name(const char *, const char *); /* find_btn_name */
extern "C" int find_matl(struct creo_conv_info *); /* find_matl */
extern "C" int find_control_attr(const char *); /* find_control_attr */
extern "C" int find_btn_label(const char *, const char *); /* find_btn_label */
extern "C" int find_unit_str(const char *); /* find_unit_str */
extern "C" char * get_input_str(int); /* get_input_str */
extern "C" int get_mtl_input(FILE *, char *, int *, int *); /* get_mtl_input */
extern "C" double get_length_conv(const char *); /* get_length_conv */
extern "C" char * get_unit_abbr(int); /* get_unit_abbr */
extern "C" char * get_unit_sys(int); /* get_unit_sys */
extern "C" char * get_username(void); /* get_username */
#if defined(CREO_EXEC_PLUGIN)
extern "C" void load_profile(void); /* load_profile */
#endif
extern "C" void lower_case(char *); /* lower_case */
extern "C" ProError param_append(void *, ProError, ProAppData); /* param_append */
extern "C" ProError param_collect(ProModelitem *, ProParameter **); /* param_collect */
extern "C" void param_export(struct creo_conv_info *, const char *); /* param_export */
extern "C" ProError param_preserve(struct creo_conv_info *, const char *); /* param_preserve */
extern "C" ProError params_to_attrs(struct creo_conv_info *, ProParameter *); /* params_to_attrs */
extern "C" void parent_dir(char *); /* parent_dir */
extern "C" void parse_param_list(struct creo_conv_info *, const char *, int); /* parse_param_list */
extern "C" ProError PopupMsg(const char *, const char *); /* PopupMsg */
extern "C" ProError regex_key(ProParameter *, ProError, ProAppData ); /* regex_key */
extern "C" void report_xform(struct creo_conv_info *, const char *); /* report_xform */
extern "C" int rgb4lmin(double *, int); /* rgb4lmin */
extern "C" void scrub_vls(struct bu_vls *); /* scrub_vls */
extern "C" wchar_t * stable_wchar(struct creo_conv_info *, wchar_t *); /* stable_wchar */
extern "C" void trim(char *); /* trim */
extern "C" char * util_fgets(char *, int, FILE *); /* util_fgets */
extern "C" double wstr_to_double(struct creo_conv_info *, wchar_t *); /* wstr_to_double */
extern "C" long int wstr_to_long(struct creo_conv_info *, wchar_t *); /* wstr_to_long */
/*
* This function is highly important - it is responsible for all name
@@ -357,7 +420,6 @@ extern "C" struct bu_vls *get_brlcad_name(struct creo_conv_info *cinfo, wchar_t
/* CSG */
extern "C" int subtract_hole(struct part_conv_info *pinfo);
#endif /*CREO_BRL_H*/
// Local Variables:
+32 -28
View File
@@ -2,7 +2,7 @@
* C S G . C P P
* BRL-CAD
*
* Copyright (c) 2017-2026 United States Government as represented by
* Copyright (c) 2017-2024 United States Government as represented by
* the U.S. Army Research Laboratory.
*
* This program is free software; you can redistribute it and/or
@@ -172,12 +172,12 @@ tgc_hole_name(struct creo_conv_info *cinfo, wchar_t *wname, const char *suffix)
while (db_lookup(cinfo->wdbp->dbip, bu_vls_addr(hname), LOOKUP_QUIET) != RT_DIR_NULL) {
(void)bu_vls_incr(hname, NULL, "0:0:0:0:-", NULL, NULL);
count++;
creo_log(cinfo, MSG_PLAIN, " NAME: Generating hole name \"%s\"\n", bu_vls_addr(hname));
creo_log(cinfo, MSG_NAME, "Generating hole name \"%s\"\n", bu_vls_addr(hname));
if (count >= MAX_UNIQUE_NAMES) {
bu_vls_free(hname);
BU_PUT(hname, struct bu_vls);
ProWstringToString(pname, wname);
creo_log(cinfo, MSG_PLAIN, " NAME: Hole \"%s\" failed name generation\n", pname);
creo_log(cinfo, MSG_NAME, "Hole \"%s\" failed name generation\n", pname);
return NULL;
}
}
@@ -202,13 +202,17 @@ subtract_hole(struct part_conv_info *pinfo)
ProError err = PRO_TK_GENERAL_ERROR;
ProElement elem_tree;
ProElempath elem_path = NULL;
ProMdl model = pinfo->cinfo->curr_model;
struct creo_conv_info *cinfo = pinfo->cinfo;
struct directory *dp = RT_DIR_NULL;
vect_t a, b, c, d, h;
/* Initialize by converting input value to part units */
double min_hole = pinfo->cinfo->min_hole/pinfo->cinfo->part_to_mm;
if (pinfo->cinfo->facets_only)
return (pinfo->diameter < cinfo->min_hole_diameter) ? 1 : 0;
return (pinfo->diameter < min_hole) ? 1 : 0;
struct hole_info *hinfo;
BU_GET(hinfo, struct hole_info);
@@ -235,21 +239,21 @@ subtract_hole(struct part_conv_info *pinfo)
return 0;
/* Will need parent object name for naming */
(void)ProMdlMdlnameGet(pinfo->model, wname);
(void)ProMdlMdlnameGet(model, wname);
/* Make a replacement hole using CSG */
if (hinfo->hole_type == PRO_HLE_NEW_TYPE_STRAIGHT) {
/* Plain old straight hole */
if (hinfo->diameter < cinfo->min_hole_diameter)
if (hinfo->diameter < min_hole)
return 1;
VSUB2(h, hinfo->end1, hinfo->end2);
bn_vec_ortho(a, h);
VCROSS(b, a, h);
VUNITIZE(b);
VSCALE(hinfo->end2, hinfo->end2, cinfo->creo_to_brl_conv);
VSCALE(a, a, pinfo->radius*cinfo->creo_to_brl_conv);
VSCALE(b, b, pinfo->radius*cinfo->creo_to_brl_conv);
VSCALE(h, h, cinfo->creo_to_brl_conv);
VSCALE(hinfo->end2, hinfo->end2, cinfo->part_to_mm);
VSCALE(a, a, pinfo->radius*cinfo->part_to_mm);
VSCALE(b, b, pinfo->radius*cinfo->part_to_mm);
VSCALE(h, h, cinfo->part_to_mm);
hname = tgc_hole_name(cinfo, wname, "s");
mk_tgc(cinfo->wdbp, bu_vls_addr(hname), hinfo->end2, h, a, b, a, b);
dp = db_lookup(cinfo->wdbp->dbip, bu_vls_addr(hname), LOOKUP_QUIET);
@@ -265,23 +269,23 @@ subtract_hole(struct part_conv_info *pinfo)
double accum_depth = 0.0;
double hole_radius = hinfo->hole_diam / 2.0;
if (hinfo->hole_diam < cinfo->min_hole_diameter)
if (hinfo->hole_diam < min_hole)
return 1;
VSUB2(dir, hinfo->end1, hinfo->end2);
VUNITIZE(dir);
VMOVE(start, hinfo->end2);
VSCALE(start, start, cinfo->creo_to_brl_conv);
VSCALE(start, start, cinfo->part_to_mm);
if (hinfo->add_cbore == PRO_HLE_ADD_CBORE) {
bn_vec_ortho(a, dir);
VCROSS(b, a, dir);
VUNITIZE(b);
cb_radius = hinfo->cb_diam * cinfo->creo_to_brl_conv / 2.0;
cb_radius = hinfo->cb_diam * cinfo->part_to_mm / 2.0;
VSCALE(a, a, cb_radius);
VSCALE(b, b, cb_radius);
VSCALE(h, dir, hinfo->cb_depth * cinfo->creo_to_brl_conv);
VSCALE(h, dir, hinfo->cb_depth * cinfo->part_to_mm);
hname = tgc_hole_name(cinfo, wname, "s");
mk_tgc(cinfo->wdbp, bu_vls_addr(hname), start, h, a, b, a, b);
if ((dp = db_lookup(cinfo->wdbp->dbip, bu_vls_addr(hname), LOOKUP_QUIET)) != RT_DIR_NULL)
@@ -303,11 +307,11 @@ subtract_hole(struct part_conv_info *pinfo)
VUNITIZE(b);
VMOVE(c, a);
VMOVE(d, b);
VSCALE(h, dir, cs_depth * cinfo->creo_to_brl_conv);
VSCALE(a, a, cs_radius * cinfo->creo_to_brl_conv);
VSCALE(b, b, cs_radius * cinfo->creo_to_brl_conv);
VSCALE(c, c, hinfo->hole_diam * cinfo->creo_to_brl_conv / 2.0);
VSCALE(d, d, hinfo->hole_diam * cinfo->creo_to_brl_conv / 2.0);
VSCALE(h, dir, cs_depth * cinfo->part_to_mm);
VSCALE(a, a, cs_radius * cinfo->part_to_mm);
VSCALE(b, b, cs_radius * cinfo->part_to_mm);
VSCALE(c, c, hinfo->hole_diam * cinfo->part_to_mm / 2.0);
VSCALE(d, d, hinfo->hole_diam * cinfo->part_to_mm / 2.0);
hname = tgc_hole_name(cinfo, wname, "s");
mk_tgc(cinfo->wdbp, bu_vls_addr(hname), start, h, a, b, c, d);
if ((dp = db_lookup(cinfo->wdbp->dbip, bu_vls_addr(hname), LOOKUP_QUIET)) != RT_DIR_NULL)
@@ -325,11 +329,11 @@ subtract_hole(struct part_conv_info *pinfo)
VUNITIZE(b);
VMOVE(c, a);
VMOVE(d, b);
VSCALE(a, a, hole_radius * cinfo->creo_to_brl_conv);
VSCALE(b, b, hole_radius * cinfo->creo_to_brl_conv);
VSCALE(c, c, hole_radius * cinfo->creo_to_brl_conv);
VSCALE(d, d, hole_radius * cinfo->creo_to_brl_conv);
VSCALE(h, dir, (hinfo->hole_depth - accum_depth) * cinfo->creo_to_brl_conv);
VSCALE(a, a, hole_radius * cinfo->part_to_mm);
VSCALE(b, b, hole_radius * cinfo->part_to_mm);
VSCALE(c, c, hole_radius * cinfo->part_to_mm);
VSCALE(d, d, hole_radius * cinfo->part_to_mm);
VSCALE(h, dir, (hinfo->hole_depth - accum_depth) * cinfo->part_to_mm);
hname = tgc_hole_name(cinfo, wname, "s");
mk_tgc(cinfo->wdbp, bu_vls_addr(hname), start, h, a, b, c, d);
dp = db_lookup(cinfo->wdbp->dbip, bu_vls_addr(hname), LOOKUP_QUIET);
@@ -350,9 +354,9 @@ subtract_hole(struct part_conv_info *pinfo)
VMOVE(c, a);
VMOVE(d, b);
tip_depth = (hole_radius - MIN_RADIUS) / tan( hinfo->drill_angle * M_PI / 360.0 );
VSCALE(h, dir, tip_depth * cinfo->creo_to_brl_conv);
VSCALE(a, a, hole_radius * cinfo->creo_to_brl_conv);
VSCALE(b, b, hole_radius * cinfo->creo_to_brl_conv);
VSCALE(h, dir, tip_depth * cinfo->part_to_mm);
VSCALE(a, a, hole_radius * cinfo->part_to_mm);
VSCALE(b, b, hole_radius * cinfo->part_to_mm);
VSCALE(c, c, MIN_RADIUS);
VSCALE(d, d, MIN_RADIUS);
hname = tgc_hole_name(cinfo, wname, "s");
@@ -369,7 +373,7 @@ subtract_hole(struct part_conv_info *pinfo)
char pname[CREO_NAME_MAX];
ProWstringToString(pname, wname);
lower_case(pname);
creo_log(cinfo, MSG_PLAIN, "FAILURE: Unable to recognize \"%s\" hole type\n", pname);
creo_log(cinfo, MSG_FAIL, "Unable to recognize \"%s\" hole type\n", pname);
BU_PUT(hinfo, struct hole_info);
return 0;
}
+395
View File
@@ -0,0 +1,395 @@
/**
* F R O N T E N D . C P P
* BRL-CAD
*
* Copyright (c) 2026 United States Government as represented by
* the U.S. Army Research Laboratory.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2.1 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this file; see the file named COPYING for more
* information.
*/
/**
* @file frontend.cpp
*
* Creo-facing dialog/controller routines that must live in the registered
* facade DLL.
*/
#include "common.h"
#include <stdarg.h>
#include <string.h>
#include <windows.h>
#include "creo-brl.h"
#include "conversion_snapshot.h"
#include "snapshot_writer.h"
extern "C" void creo_brl_show_status(const char *message);
extern "C" void creo_brl_core_load_profile_shim(void);
#if defined(CREO_EXEC_PLUGIN)
extern "C" void creo_brl_core_doit_shim(char *dialog, char *component, ProAppData appdata);
#else
extern "C" int creo_brl_core_convert_shim(const char *snapshot_path);
#endif
#if defined(CREO_EXEC_PLUGIN)
static const bool FRONTEND_LOAD_PROFILE_ON_OPEN = true;
#else
static const bool FRONTEND_LOAD_PROFILE_ON_OPEN = true;
#endif
static const wchar_t FRONTEND_SNAPSHOT_PREFIX[] = L"cbr";
static const size_t FRONTEND_SNAPSHOT_UTF8_PATH_SIZE = MAX_PATH * 4;
static void
frontend_status(const char *fmt, ...)
{
va_list ap;
char msg[CREO_MSG_MAX] = {'\0'};
va_start(ap, fmt);
vsprintf_s(msg, sizeof(msg), fmt, ap);
va_end(ap);
creo_brl_show_status(msg);
}
extern "C" void __cdecl
creo_brl_frontend_apply_control(
const char *resource,
const char *type,
const char *value,
const char *UNUSED(default_value))
{
ProError err = PRO_TK_GENERAL_ERROR;
if (!resource || !type || !value) {
frontend_status("FAILURE: Unable to apply an invalid profile control value");
return;
}
if (strcmp(type, "STR") == 0) {
wchar_t text[CREO_NAME_MAX];
ProStringToWstring(text, (char *)value);
err = ProUIInputpanelValueSet(CREO_UI_NAME, (char *)resource, text);
} else if (strcmp(type, "BOX") == 0) {
if (strcmp(value, "on") == 0)
err = ProUICheckbuttonSet(CREO_UI_NAME, (char *)resource);
else
err = ProUICheckbuttonUnset(CREO_UI_NAME, (char *)resource);
} else if (strcmp(type, "RAD") == 0) {
char *selected_name = (char *)value;
err = ProUIRadiogroupSelectednamesSet(CREO_UI_NAME, (char *)resource, 1, &selected_name);
} else {
frontend_status("Unknown control type: %s", type);
return;
}
if (err != PRO_TK_NO_ERROR)
frontend_status("FAILURE: Unable to apply profile value for %s (%d)", resource, err);
}
static void
frontend_load_profile(void)
{
creo_brl_core_load_profile_shim();
}
#if !defined(CREO_EXEC_PLUGIN)
static int
frontend_snapshot_path(wchar_t *wide_path, size_t wide_path_size,
char *utf8_path, size_t utf8_path_size)
{
wchar_t temporary_directory[MAX_PATH] = {L'\0'};
const DWORD directory_length = GetTempPathW(_countof(temporary_directory), temporary_directory);
DWORD file_number = 0;
int utf8_length = 0;
if (!wide_path || !utf8_path || wide_path_size < MAX_PATH || utf8_path_size == 0 ||
directory_length == 0 || directory_length >= _countof(temporary_directory))
return 0;
file_number = GetTempFileNameW(temporary_directory, FRONTEND_SNAPSHOT_PREFIX, 0, wide_path);
if (file_number == 0)
return 0;
utf8_length = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wide_path, -1,
utf8_path, (int)utf8_path_size, NULL, NULL);
if (utf8_length <= 0) {
(void)DeleteFileW(wide_path);
return 0;
}
return 1;
}
static const char *
frontend_capture_failure_message(int result)
{
switch (result) {
case CREO_BRL_SNAPSHOT_CAPTURE_DIALOG_FAILURE:
return "FAILURE: Unable to read the current Creo-BRL dialog settings.";
case CREO_BRL_SNAPSHOT_CAPTURE_NO_ACTIVE_MODEL:
return "FAILURE: No active Creo model is available for conversion.";
case CREO_BRL_SNAPSHOT_CAPTURE_UNSUPPORTED_MODEL:
return "FAILURE: Only active Creo parts and assemblies can be converted.";
case CREO_BRL_SNAPSHOT_CAPTURE_MODEL_FAILURE:
return "FAILURE: Unable to read active model metadata or supported length units.";
case CREO_BRL_SNAPSHOT_CAPTURE_TESSELLATION_FAILURE:
return "FAILURE: Unable to tessellate a model part; enable bounding-box fallback or adjust tessellation controls.";
case CREO_BRL_SNAPSHOT_CAPTURE_WRITE_FAILURE:
return "FAILURE: Unable to create the temporary conversion request.";
default:
return "FAILURE: Unable to capture the current conversion request.";
}
}
static const char *
frontend_core_failure_message(int result)
{
switch (result) {
case CREO_BRL_CORE_CONVERT_OPEN_FAILED:
return "FAILURE: The Creo-BRL runtime core is unavailable.";
case CREO_BRL_CORE_CONVERT_INVALID_SNAPSHOT:
return "FAILURE: The captured conversion request was invalid.";
case CREO_BRL_CORE_CONVERT_UNSUPPORTED_SNAPSHOT:
return "FAILURE: The captured conversion request is unsupported.";
case CREO_BRL_CORE_CONVERT_NOT_IMPLEMENTED:
return "FAILURE: The requested conversion path is not implemented.";
case CREO_BRL_CORE_CONVERT_OUTPUT_FAILED:
return "FAILURE: The BRL-CAD output file could not be written.";
default:
return "FAILURE: The runtime core failed to convert the active model.";
}
}
#endif
/* Activates small feature settings */
extern "C" void
activate_small_feats(char *dialog_name, char *button_name, ProAppData UNUSED(data))
{
ProBoolean state;
if (ProUICheckbuttonGetState(dialog_name, button_name, &state) != PRO_TK_NO_ERROR) {
frontend_status("FAILURE: Unable to obtain check button state: \"Ignore minimum sizes\"");
return;
}
if (state) {
if (ProUIInputpanelEditable(dialog_name, "min_hole") != PRO_TK_NO_ERROR) {
frontend_status("FAILURE: Unable to activate: \"Hole diameter\"");
return;
}
if (ProUIInputpanelEditable(dialog_name, "min_chamfer") != PRO_TK_NO_ERROR) {
frontend_status("FAILURE: Unable to activate: \"Chamfer dimension\"");
return;
}
if (ProUIInputpanelEditable(dialog_name, "min_round") != PRO_TK_NO_ERROR) {
frontend_status("FAILURE: Unable to activate: \"Blend radius\"");
return;
}
} else {
if (ProUIInputpanelReadOnly(dialog_name, "min_hole") != PRO_TK_NO_ERROR) {
frontend_status("FAILURE: Unable to de-activate: \"Hole diameter\"");
return;
}
if (ProUIInputpanelReadOnly(dialog_name, "min_chamfer") != PRO_TK_NO_ERROR) {
frontend_status("FAILURE: Unable to de-activate: \"Chamfer dimension\"");
return;
}
if (ProUIInputpanelReadOnly(dialog_name, "min_round") != PRO_TK_NO_ERROR) {
frontend_status("FAILURE: Unable to de-activate: \"Blend radius\"");
return;
}
}
}
/* Activates export STL setting */
extern "C" void
activate_export_stl(char *dialog_name, char *button_name, ProAppData UNUSED(data))
{
ProBoolean state;
if (ProUICheckbuttonGetState(dialog_name, button_name, &state) != PRO_TK_NO_ERROR) {
frontend_status("FAILURE: Unable to obtain check button state: \"Facetize everything, (no CSG)\"");
return;
}
if (state) {
if (ProUICheckbuttonEnable(dialog_name, "export_stl") != PRO_TK_NO_ERROR) {
frontend_status("FAILURE: Unable to activate: \"Export facets to STL file\"");
return;
}
} else {
if (ProUICheckbuttonDisable(dialog_name, "export_stl") != PRO_TK_NO_ERROR) {
frontend_status("FAILURE: Unable to de-activate: \"Export facets to STL file\"");
return;
}
}
}
/* Exit the converter dialog */
extern "C" void
do_quit(char *UNUSED(dialog), char *UNUSED(compnent), ProAppData UNUSED(appdata))
{
ProUIDialogDestroy(CREO_UI_NAME);
}
static void
frontend_convert(char *dialog, char *component, ProAppData appdata)
{
#if defined(CREO_EXEC_PLUGIN)
creo_brl_core_doit_shim(dialog, component, appdata);
#else
wchar_t snapshot_path_wide[MAX_PATH] = {L'\0'};
char snapshot_path[FRONTEND_SNAPSHOT_UTF8_PATH_SIZE] = {'\0'};
int capture_result = CREO_BRL_SNAPSHOT_CAPTURE_INVALID_REQUEST;
int core_result = CREO_BRL_CORE_CONVERT_INVALID_REQUEST;
(void)dialog;
(void)component;
(void)appdata;
if (!frontend_snapshot_path(snapshot_path_wide, _countof(snapshot_path_wide),
snapshot_path, sizeof(snapshot_path))) {
frontend_status("FAILURE: Unable to create a temporary conversion request path.");
return;
}
frontend_status("Capturing active Creo model for BRL-CAD conversion...");
capture_result = creo_brl_frontend_capture_snapshot(snapshot_path);
if (capture_result != CREO_BRL_SNAPSHOT_CAPTURE_SUCCESS) {
(void)DeleteFileW(snapshot_path_wide);
frontend_status(frontend_capture_failure_message(capture_result));
return;
}
frontend_status("Writing BRL-CAD geometry...");
core_result = creo_brl_core_convert_shim(snapshot_path);
(void)DeleteFileW(snapshot_path_wide);
if (core_result != CREO_BRL_CORE_CONVERT_SUCCESS) {
frontend_status(frontend_core_failure_message(core_result));
return;
}
frontend_status("Creo part conversion completed.");
#endif
}
/* Driver routine for converting Creo to BRL-CAD */
extern "C" int
creo_brl_frontend_command(uiCmdCmdId UNUSED(command), uiCmdValue *UNUSED(p_value), void *UNUSED(p_push_cmd_data))
{
char status[CREO_MSG_MAX] = {'\0'};
int destroy_dialog = 0;
int err;
frontend_status("Launching Creo to BRL-CAD converter...");
if (ProUIDialogCreate(CREO_UI_NAME, CREO_UI_NAME) != PRO_TK_NO_ERROR) {
sprintf_s(status, sizeof(status), "FAILURE: Unable to create dialog box for creo-brl");
goto print_msg;
}
if (FRONTEND_LOAD_PROFILE_ON_OPEN)
frontend_load_profile();
if (ProUICheckbuttonActivateActionSet(CREO_UI_NAME, "elim_small", activate_small_feats, NULL) != PRO_TK_NO_ERROR) {
sprintf_s(status, sizeof(status), "FAILURE: Unable to set action for \"Ignore minimum sizes\" checkbutton");
goto print_msg;
}
if (ProUICheckbuttonActivateActionSet(CREO_UI_NAME, "facets_only", activate_export_stl, NULL) != PRO_TK_NO_ERROR) {
sprintf_s(status, sizeof(status), "FAILURE: Unable to set action for \"Facetize everything, (no CSG)\" checkbutton");
goto print_msg;
}
if (ProUIPushbuttonActivateActionSet(CREO_UI_NAME, "doit", frontend_convert, NULL) != PRO_TK_NO_ERROR) {
sprintf_s(status, sizeof(status), "FAILURE: Unable to set action for \"Convert\" button");
destroy_dialog = 1;
goto print_msg;
}
if (ProUIPushbuttonActivateActionSet(CREO_UI_NAME, "quit", do_quit, NULL) != PRO_TK_NO_ERROR) {
sprintf_s(status, sizeof(status), "FAILURE: Unable to set action for \"Quit\" button");
destroy_dialog = 1;
goto print_msg;
}
ProUIInputpanelMaxlenSet(CREO_UI_NAME, "out_fname", MAXPATHLEN - 1);
ProUIInputpanelMaxlenSet(CREO_UI_NAME, "log_fname", MAXPATHLEN - 1);
ProUIInputpanelMaxlenSet(CREO_UI_NAME, "mtl_fname", MAXPATHLEN - 1);
ProUIInputpanelMaxlenSet(CREO_UI_NAME, "param_rename", MAXPATHLEN - 1);
ProUIInputpanelMaxlenSet(CREO_UI_NAME, "param_save", MAXPATHLEN - 1);
ProMdl model;
if (ProMdlCurrentGet(&model) != PRO_TK_BAD_CONTEXT) {
wchar_t wname[CREO_NAME_MAX];
if (ProMdlMdlnameGet(model, wname) == PRO_TK_NO_ERROR) {
char name[CREO_NAME_MAX] = {'\0'};
char gout[CREO_NAME_MAX] = {'\0'};
char lout[CREO_NAME_MAX] = {'\0'};
wchar_t wout[CREO_NAME_MAX];
char *dot = NULL;
ProWstringToString(name, wname);
CharLowerBuffA(name, (DWORD)strlen(name));
dot = strrchr(name, '.');
if (dot)
*dot = '\0';
sprintf_s(gout, sizeof(gout), "%s.g", name);
ProStringToWstring(wout, gout);
ProUIInputpanelValueSet(CREO_UI_NAME, "out_fname", wout);
sprintf_s(lout, sizeof(lout), "%s_log.txt", name);
ProStringToWstring(wout, lout);
ProUIInputpanelValueSet(CREO_UI_NAME, "log_fname", wout);
}
}
if (ProUIDialogActivate(CREO_UI_NAME, &err) != PRO_TK_NO_ERROR)
sprintf_s(status, sizeof(status), "FAILURE: Unexpected error in creo-brl dialog returned %d", err);
print_msg:
if (status[0] != '\0')
creo_brl_show_status(status);
if (destroy_dialog)
ProUIDialogDestroy(CREO_UI_NAME);
return 0;
}
/**
* This routine determines whether the "creo-brl" menu item in Creo
* should be displayed as available or greyed out
*/
extern "C" uiCmdAccessState
creo_brl_frontend_access(uiCmdAccessMode UNUSED(access_mode))
{
return ACCESS_AVAILABLE;
}
+26
View File
@@ -0,0 +1,26 @@
#ifndef CREO_BRL_FRONTEND_API_H
#define CREO_BRL_FRONTEND_API_H
#ifdef __cplusplus
extern "C" {
#endif
typedef void (__cdecl *creo_brl_status_fn_t)(const char *message);
typedef void (__cdecl *creo_brl_popup_fn_t)(const char *title, const char *message);
typedef void (__cdecl *creo_brl_apply_control_fn_t)(
const char *resource,
const char *type,
const char *value,
const char *default_value);
struct creo_brl_frontend_api {
creo_brl_status_fn_t show_status;
creo_brl_popup_fn_t show_popup;
creo_brl_apply_control_fn_t apply_control;
};
#ifdef __cplusplus
}
#endif
#endif
+483
View File
@@ -0,0 +1,483 @@
/**
* L O A D E R . C
* BRL-CAD
*
* Copyright (c) 2026 United States Government as represented by
* the U.S. Army Research Laboratory.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2.1 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this file; see the file named COPYING for more
* information.
*/
/**
* @file loader.c
*
* Minimal Creo-facing facade that runtime-loads the real converter core.
*/
#include <windows.h>
#include <stdio.h>
#include <wchar.h>
#include <ProArray.h>
#include <ProMenuBar.h>
#include <ProMessage.h>
#include <ProUICmd.h>
#include <ProUIMessage.h>
#include <ProUtil.h>
#include "conversion_snapshot.h"
#include "frontend_api.h"
#define FRONTEND_MSG_FILE "creo-brl-msg.txt"
#define FRONTEND_TITLE_MAX 512
#define FRONTEND_MESSAGE_MAX 4096
#define FACADE_PATH_MAX 32768
#define BUNDLE_CONFIG_PATH L"config"
#define BUNDLE_MATERIAL_PATH L"text\\usascii"
typedef int (__cdecl *creo_brl_core_initialize_fn_t)(void);
typedef int (__cdecl *creo_brl_core_convert_fn_t)(const char *snapshot_path);
typedef void (__cdecl *creo_brl_core_terminate_fn_t)(void);
typedef void (__cdecl *creo_brl_core_load_profile_fn_t)(
const char *profile_directory,
const char *material_directory);
typedef void (__cdecl *creo_brl_core_set_frontend_api_fn_t)(const struct creo_brl_frontend_api *);
static HMODULE core_module = NULL;
static creo_brl_core_initialize_fn_t core_initialize_fn = NULL;
static creo_brl_core_convert_fn_t core_convert_fn = NULL;
static creo_brl_core_terminate_fn_t core_terminate_fn = NULL;
static creo_brl_core_load_profile_fn_t core_load_profile_fn = NULL;
static creo_brl_core_set_frontend_api_fn_t core_set_frontend_api_fn = NULL;
/*
* GetModuleHandleExW(...FROM_ADDRESS...) needs any address that belongs
* to this module. A data symbol avoids a function-pointer cast.
*/
static const char module_anchor = 0;
static void
show_bootstrap_error(const wchar_t *context)
{
DWORD error_code = GetLastError();
wchar_t system_message[1024] = {0};
wchar_t message[2048] = {0};
FormatMessageW(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
error_code,
0,
system_message,
(DWORD)_countof(system_message),
NULL);
swprintf_s(
message,
_countof(message),
L"%ls\n\nWin32 error %lu:\n%ls",
context,
error_code,
system_message[0] ? system_message : L"(no system error text)");
MessageBoxW(
NULL,
message,
L"creo-brl bootstrap failure",
MB_OK | MB_ICONERROR | MB_TOPMOST);
}
static void
show_toolkit_error(const wchar_t *context, int tk_err)
{
wchar_t message[1024] = {0};
swprintf_s(
message,
_countof(message),
L"%ls\n\nCreo Toolkit error %d.",
context,
tk_err);
MessageBoxW(
NULL,
message,
L"creo-brl bootstrap failure",
MB_OK | MB_ICONERROR | MB_TOPMOST);
}
static void __cdecl
show_status_message(const char *message)
{
ProFileName msgfil = {'\0'};
ProStringToWstring(msgfil, (char *)FRONTEND_MSG_FILE);
ProMessageClear();
ProMessageDisplay(msgfil, "USER_INFO", (char *)message);
}
static void __cdecl
show_popup_message(const char *title, const char *message)
{
wchar_t wtitle[FRONTEND_TITLE_MAX];
wchar_t wmsg[FRONTEND_MESSAGE_MAX];
ProUIMessageButton *button = NULL;
ProUIMessageButton bresult;
(void)ProArrayAlloc(1, sizeof(ProUIMessageButton), 1, (ProArray *)&button);
button[0] = PRO_UI_MESSAGE_OK;
ProStringToWstring(wtitle, (char *)title);
ProStringToWstring(wmsg, (char *)message);
ProUIMessageDialogDisplay(PROUIMESSAGE_INFO, wtitle, wmsg, button, PRO_UI_MESSAGE_OK, &bresult);
(void)ProArrayFree((ProArray *)&button);
}
extern void __cdecl creo_brl_frontend_apply_control(
const char *resource,
const char *type,
const char *value,
const char *default_value);
static const struct creo_brl_frontend_api frontend_api = {
show_status_message,
show_popup_message,
creo_brl_frontend_apply_control
};
static int
self_bin_dir(wchar_t *dir, size_t dir_len)
{
HMODULE self = NULL;
DWORD length = 0;
wchar_t *last_slash = NULL;
if (!dir || dir_len == 0)
return 0;
if (!GetModuleHandleExW(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
(LPCWSTR)&module_anchor,
&self)) {
return 0;
}
length = GetModuleFileNameW(self, dir, (DWORD)dir_len);
if (length == 0 || length >= dir_len)
return 0;
last_slash = wcsrchr(dir, L'\\');
if (!last_slash)
return 0;
*last_slash = L'\0';
return 1;
}
static int
bundle_subdirectory(wchar_t *path, size_t path_len, const wchar_t *relative_path)
{
wchar_t *last_slash = NULL;
size_t bundle_length = 0;
if (!path || path_len == 0 || !relative_path)
return 0;
if (!self_bin_dir(path, path_len))
return 0;
last_slash = wcsrchr(path, L'\\');
if (!last_slash)
return 0;
*last_slash = L'\0';
bundle_length = wcslen(path);
return swprintf_s(
path + bundle_length,
path_len - bundle_length,
L"\\%ls",
relative_path) >= 0;
}
static int
wide_path_to_string(const wchar_t *wide_path, char *path, size_t path_len)
{
if (!wide_path || !path || path_len == 0)
return 0;
return WideCharToMultiByte(
CP_ACP,
WC_NO_BEST_FIT_CHARS,
wide_path,
-1,
path,
(int)path_len,
NULL,
NULL) != 0;
}
static void
clear_core_state(void)
{
core_initialize_fn = NULL;
core_convert_fn = NULL;
core_terminate_fn = NULL;
core_load_profile_fn = NULL;
core_set_frontend_api_fn = NULL;
core_module = NULL;
}
static void
unload_core(void)
{
HMODULE module_to_free = core_module;
creo_brl_core_terminate_fn_t terminate_to_call = core_terminate_fn;
clear_core_state();
if (terminate_to_call)
terminate_to_call();
if (module_to_free)
FreeLibrary(module_to_free);
}
extern int creo_brl_frontend_command(uiCmdCmdId command, uiCmdValue *p_value, void *p_push_cmd_data);
extern uiCmdAccessState creo_brl_frontend_access(uiCmdAccessMode access_mode);
void
creo_brl_show_status(const char *message)
{
show_status_message(message);
}
void
creo_brl_core_load_profile_shim(void)
{
wchar_t profile_directory_wide[FACADE_PATH_MAX] = {0};
wchar_t material_directory_wide[FACADE_PATH_MAX] = {0};
char profile_directory[FACADE_PATH_MAX] = {0};
char material_directory[FACADE_PATH_MAX] = {0};
if (!core_load_profile_fn)
return;
if (!bundle_subdirectory(
profile_directory_wide,
_countof(profile_directory_wide),
BUNDLE_CONFIG_PATH) ||
!bundle_subdirectory(
material_directory_wide,
_countof(material_directory_wide),
BUNDLE_MATERIAL_PATH) ||
!wide_path_to_string(
profile_directory_wide,
profile_directory,
sizeof(profile_directory)) ||
!wide_path_to_string(
material_directory_wide,
material_directory,
sizeof(material_directory))) {
show_status_message("Unable to determine the Creo-BRL bundle configuration paths.");
core_load_profile_fn(NULL, NULL);
return;
}
core_load_profile_fn(profile_directory, material_directory);
}
int
creo_brl_core_convert_shim(const char *snapshot_path)
{
if (!core_convert_fn)
return CREO_BRL_CORE_CONVERT_OPEN_FAILED;
return core_convert_fn(snapshot_path);
}
__declspec(dllexport) int
user_initialize(void)
{
int expected_wchar_size = 0;
int tk_err = 0;
wchar_t bin_dir[FACADE_PATH_MAX] = {0};
wchar_t core_path[FACADE_PATH_MAX] = {0};
FARPROC proc = NULL;
int core_result = -1;
uiCmdCmdId cmd_id = 0;
ProError err = PRO_TK_GENERAL_ERROR;
ProFileName msgfil = {'\0'};
if (core_module) {
MessageBoxW(
NULL,
L"user_initialize was called while creo-brl-core.dll was already loaded.",
L"creo-brl bootstrap failure",
MB_OK | MB_ICONERROR | MB_TOPMOST);
return -1;
}
err = ProUITranslationFilesEnable();
if (err != PRO_TK_NO_ERROR) {
show_toolkit_error(L"ProUITranslationFilesEnable failed.", err);
return -1;
}
/* Keep one direct Toolkit call in the Creo-facing entry point. */
tk_err = ProWcharSizeVerify((int)sizeof(wchar_t), &expected_wchar_size);
if (tk_err != 0 || expected_wchar_size != (int)sizeof(wchar_t)) {
wchar_t message[512] = {0};
swprintf_s(
message,
_countof(message),
L"Facade ProWcharSizeVerify failed.\nerr=%d expected=%d actual=%zu",
tk_err,
expected_wchar_size,
sizeof(wchar_t));
MessageBoxW(
NULL,
message,
L"creo-brl bootstrap failure",
MB_OK | MB_ICONERROR | MB_TOPMOST);
return -1;
}
if (!self_bin_dir(bin_dir, _countof(bin_dir))) {
show_bootstrap_error(L"Unable to determine the creo-brl.dll directory.");
return -1;
}
if (swprintf_s(
core_path,
_countof(core_path),
L"%ls\\creo-brl-core.dll",
bin_dir) < 0) {
MessageBoxW(
NULL,
L"Unable to construct the creo-brl-core.dll path.",
L"creo-brl bootstrap failure",
MB_OK | MB_ICONERROR | MB_TOPMOST);
return -1;
}
/*
* Keep DLL search changes scoped to this load operation so we do not
* alter Creo's process-wide loader policy.
*/
core_module = LoadLibraryExW(
core_path,
NULL,
LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR |
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
if (!core_module) {
show_bootstrap_error(L"LoadLibraryExW(creo-brl-core.dll) failed.");
clear_core_state();
return -1;
}
proc = GetProcAddress(core_module, "creo_brl_core_initialize");
if (!proc) {
show_bootstrap_error(L"GetProcAddress(creo_brl_core_initialize) failed.");
unload_core();
return -1;
}
core_initialize_fn = (creo_brl_core_initialize_fn_t)proc;
proc = GetProcAddress(core_module, "creo_brl_core_convert");
if (!proc) {
show_bootstrap_error(L"GetProcAddress(creo_brl_core_convert) failed.");
unload_core();
return -1;
}
core_convert_fn = (creo_brl_core_convert_fn_t)proc;
proc = GetProcAddress(core_module, "creo_brl_core_terminate");
if (!proc) {
show_bootstrap_error(L"GetProcAddress(creo_brl_core_terminate) failed.");
unload_core();
return -1;
}
core_terminate_fn = (creo_brl_core_terminate_fn_t)proc;
proc = GetProcAddress(core_module, "creo_brl_core_set_frontend_api");
if (!proc) {
show_bootstrap_error(L"GetProcAddress(creo_brl_core_set_frontend_api) failed.");
unload_core();
return -1;
}
core_set_frontend_api_fn = (creo_brl_core_set_frontend_api_fn_t)proc;
proc = GetProcAddress(core_module, "creo_brl_core_load_profile");
if (!proc) {
show_bootstrap_error(L"GetProcAddress(creo_brl_core_load_profile) failed.");
unload_core();
return -1;
}
core_load_profile_fn = (creo_brl_core_load_profile_fn_t)proc;
core_set_frontend_api_fn(&frontend_api);
core_result = core_initialize_fn();
if (core_result != 0) {
unload_core();
return core_result;
}
err = ProCmdActionAdd(
"CREO-BRL",
creo_brl_frontend_command,
uiProe2ndImmediate,
creo_brl_frontend_access,
PRO_B_FALSE,
PRO_B_FALSE,
&cmd_id);
if (err != PRO_TK_NO_ERROR) {
show_toolkit_error(L"ProCmdActionAdd failed.", err);
unload_core();
return -1;
}
ProStringToWstring(msgfil, "creo-brl-msg.txt");
err = ProMenubarmenuPushbuttonAdd(
"Tools",
"CREO-BRL",
"CREO-BRL",
"CREO-BRL-HELP",
NULL,
PRO_B_TRUE,
cmd_id,
msgfil);
if (err != PRO_TK_NO_ERROR) {
/*
* The command may already be registered with Creo at this point.
* Keep the core loaded so any surviving facade shim remains valid.
*/
show_toolkit_error(L"ProMenubarmenuPushbuttonAdd failed.", err);
return -1;
}
return 0;
}
__declspec(dllexport) void
user_terminate(void)
{
ProMessageClear();
unload_core();
}
+753 -469
View File
File diff suppressed because it is too large Load Diff
+1048 -406
View File
File diff suppressed because it is too large Load Diff
+27
View File
@@ -0,0 +1,27 @@
#include "common.h"
#include "part_writer.h"
#include "wdb.h"
extern "C" int
creo_brl_write_bot(struct rt_wdb *writer,
const char *name,
int write_normals,
size_t vertex_count,
size_t face_count,
fastf_t *vertices,
int *faces,
size_t normal_count,
fastf_t *normals,
int *face_normals)
{
if (write_normals)
return mk_bot_w_normals(writer, name, RT_BOT_SOLID, RT_BOT_CCW, 0,
vertex_count, face_count, vertices, faces,
NULL, NULL, normal_count, normals, face_normals);
return mk_bot(writer, name, RT_BOT_SOLID, RT_BOT_CCW, 0,
vertex_count, face_count, vertices, faces, NULL, NULL);
}
+19
View File
@@ -0,0 +1,19 @@
#ifndef CREO_PART_WRITER_H
#define CREO_PART_WRITER_H
#include <stddef.h>
#include "raytrace.h"
extern "C" int creo_brl_write_bot(struct rt_wdb *writer,
const char *name,
int write_normals,
size_t vertex_count,
size_t face_count,
fastf_t *vertices,
int *faces,
size_t normal_count,
fastf_t *normals,
int *face_normals);
#endif /* CREO_PART_WRITER_H */
+260
View File
@@ -0,0 +1,260 @@
/**
* P R O F I L E . C P P
* BRL-CAD
*
* Copyright (c) 2026 United States Government as represented by
* the U.S. Army Research Laboratory.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2.1 as published by the Free Software Foundation.
*/
/**
* @file profile.cpp
*
* Toolkit-free BRL-CAD profile parsing for the runtime-loaded backend.
*/
#include "common.h"
#include <stdarg.h>
#include <stdio.h>
extern "C" {
#include "bu.h"
#include "raytrace.h"
#include "wdb.h"
}
#include "frontend_api.h"
#include "profile_controls.h"
#define PROFILE_MESSAGE_MAX 4096
static struct creo_brl_frontend_api frontend_api = {0};
static void profile_status(const char *format, ...);
static const char *profile_input_value(int index);
static int profile_radio_button_index(const char *resource, const char *value);
static void apply_profile_value(const char *resource, const char *type, const char *value, const char *default_value);
static void load_profile_defaults(const char *material_directory);
extern "C" __declspec(dllexport) void
creo_brl_core_set_frontend_api(const struct creo_brl_frontend_api *api)
{
if (api) {
frontend_api = *api;
return;
}
frontend_api.show_status = NULL;
frontend_api.show_popup = NULL;
frontend_api.apply_control = NULL;
}
static void
profile_status(const char *format, ...)
{
char message[PROFILE_MESSAGE_MAX] = {'\0'};
va_list arguments;
va_start(arguments, format);
vsprintf_s(message, sizeof(message), format, arguments);
va_end(arguments);
if (frontend_api.show_status)
frontend_api.show_status(message);
}
static const char *
profile_input_value(int index)
{
for (const struct creo_profile_input *input = creo_profile_inputs; input->value; input++) {
if (input->index == index)
return input->value;
}
return NULL;
}
static int
profile_radio_button_index(const char *resource, const char *value)
{
if (!value)
return -1;
for (const struct creo_profile_control *control = creo_profile_controls; control->resource; control++) {
if (bu_strcmp(resource, control->resource) != 0)
continue;
for (size_t index = 0; index < CREO_PROFILE_RADIO_BUTTON_MAX; index++) {
const char *candidate = profile_input_value(control->input_indices[index]);
if (candidate && bu_strcmp(candidate, value) == 0)
return (int)index;
}
}
return -1;
}
static int
is_material_file_control(const struct creo_profile_control *control)
{
return bu_strcmp(control->resource, creo_profile_material_resource) == 0;
}
static const char *
profile_default_value(const struct creo_profile_control *control, const char *material_directory, struct bu_vls *material_path)
{
const char *default_value = profile_input_value(control->input_indices[0]);
if (!is_material_file_control(control) || !material_directory || !material_directory[0])
return default_value;
bu_vls_sprintf(material_path, "%s\\%s", material_directory, creo_profile_bundle_material_file_name);
return bu_vls_cstr(material_path);
}
static void
apply_profile_value(const char *resource, const char *type, const char *value, const char *default_value)
{
const char *value_to_apply = value;
if (bu_strcmp(type, "RAD") == 0) {
if (profile_radio_button_index(resource, value) <= 0)
value_to_apply = default_value;
} else if (bu_strcmp(type, "STR") != 0 && bu_strcmp(type, "BOX") != 0) {
profile_status("Unknown control type: %s", type);
return;
}
if (!frontend_api.apply_control) {
profile_status("Unable to apply profile value for %s: no frontend is available", resource);
return;
}
frontend_api.apply_control(resource, type, value_to_apply, default_value);
}
static void
load_profile_defaults(const char *material_directory)
{
struct bu_vls material_path = BU_VLS_INIT_ZERO;
for (const struct creo_profile_control *control = creo_profile_controls; control->attribute; control++) {
const char *default_value = profile_default_value(control, material_directory, &material_path);
apply_profile_value(control->resource, control->type, default_value, default_value);
}
bu_vls_free(&material_path);
}
static struct bu_vls *
profile_path(const char *profile_directory)
{
struct bu_vls *path = NULL;
if (!profile_directory || !profile_directory[0]) {
profile_status("Unable to determine the bundle profile directory");
return NULL;
}
BU_GET(path, struct bu_vls);
bu_vls_init(path);
bu_vls_sprintf(path, "%s\\%s", profile_directory, creo_profile_file_name);
if (!bu_file_exists(bu_vls_cstr(path), NULL)) {
profile_status("Unable to locate bundle profile \"%s\"", bu_vls_addr(path));
bu_vls_free(path);
BU_PUT(path, struct bu_vls);
return NULL;
}
profile_status("Bundle profile is \"%s\"", bu_vls_addr(path));
return path;
}
static void
load_profile_from_directory(const char *profile_directory, const char *material_directory)
{
struct bu_attribute_value_set attributes;
struct bu_vls *profile = profile_path(profile_directory);
struct bu_vls material_path = BU_VLS_INIT_ZERO;
struct db_i *database = NULL;
struct directory *global_directory = NULL;
if (!profile) {
profile_status("Unable to locate user profile");
load_profile_defaults(material_directory);
return;
}
profile_status("User profile is \"%s\"", bu_vls_addr(profile));
database = db_open(bu_vls_cstr(profile), DB_OPEN_READONLY);
if (database == DBI_NULL) {
profile_status("\"db_open\" failed to open the user profile");
load_profile_defaults(material_directory);
goto cleanup;
}
RT_CK_DBI(database);
if (db_dirbuild(database) < 0) {
profile_status("\"db_dirbuild\" failed to build \"%s\"", bu_vls_addr(profile));
load_profile_defaults(material_directory);
goto cleanup;
}
global_directory = db_lookup(database, DB5_GLOBAL_OBJECT_NAME, LOOKUP_QUIET);
if (global_directory == RT_DIR_NULL) {
profile_status("Failed to find the _GLOBAL profile record");
load_profile_defaults(material_directory);
goto cleanup;
}
if (db5_get_attributes(database, &attributes, global_directory)) {
profile_status("Failed to find any _GLOBAL attributes");
bu_avs_free(&attributes);
load_profile_defaults(material_directory);
goto cleanup;
}
if (attributes.count) {
for (const struct creo_profile_control *control = creo_profile_controls; control->attribute; control++) {
const char *default_value = profile_default_value(control, material_directory, &material_path);
const char *value = bu_avs_get(&attributes, control->attribute);
if (value && is_material_file_control(control) && material_directory && material_directory[0] &&
bu_strcmp(value, creo_profile_legacy_material_file_path) == 0)
value = default_value;
apply_profile_value(control->resource, control->type, value ? value : default_value, default_value);
}
bu_avs_free(&attributes);
}
cleanup:
if (database)
db_close(database);
bu_vls_free(&material_path);
bu_vls_free(profile);
BU_PUT(profile, struct bu_vls);
}
extern "C" __declspec(dllexport) void
creo_brl_core_load_profile(const char *profile_directory, const char *material_directory)
{
load_profile_from_directory(profile_directory, material_directory);
}
+88
View File
@@ -0,0 +1,88 @@
/**
* P R O F I L E _ C O N T R O L S . H
* BRL-CAD
*
* Copyright (c) 2026 United States Government as represented by
* the U.S. Army Research Laboratory.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2.1 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
#ifndef CREO_PROFILE_CONTROLS_H
#define CREO_PROFILE_CONTROLS_H
#define CREO_PROFILE_RADIO_BUTTON_MAX 4
static const char creo_profile_file_name[] = "Creo_to_BRL.g";
static const char creo_profile_material_resource[] = "mtl_fname";
static const char creo_profile_legacy_material_file_path[] = "./ptc_materials.mtl";
static const char creo_profile_bundle_material_file_name[] = "ptc_materials.mtl";
struct creo_profile_input {
const char *value;
int index;
};
struct creo_profile_control {
const char *attribute;
const char *resource;
const char *type;
int input_indices[CREO_PROFILE_RADIO_BUTTON_MAX];
int index;
};
static const struct creo_profile_input creo_profile_inputs[] = {
{"./ptc_materials.mtl", 1},
{"0.0", 2},
{"0.3", 3},
{"0.5", 4},
{"1.0", 5},
{"1000", 6},
{"30", 7},
{"all/(debug)", 8},
{"failure", 9},
{"failure/success", 10},
{"millimeter", 11},
{"nomenclature", 12},
{"nomenclature,part_number,ptc_material_name", 13},
{"none", 14},
{"off", 15},
{"on", 16},
{"percent", 17},
{"success", 18},
{"x_to_z", 19},
{"y_to_z", 20},
{NULL, -1}
};
static const struct creo_profile_control creo_profile_controls[] = {
{"process_log_criteria", "log_file_type", "RAD", {8, 9, 18, 10}, 1},
{"material_file_name", "mtl_fname", "STR", {1, -1, -1, -1}, 2},
{"create_object_names", "param_rename", "STR", {12, -1, -1, -1}, 3},
{"preserved_attributes", "param_save", "STR", {13, -1, -1, -1}, 4},
{"coordinate_transformation", "transform", "RAD", {14, 19, 20, -1}, 5},
{"initial_region_counter", "region_counter", "STR", {6, -1, -1, -1}, 6},
{"minimum_luminance", "min_luminance", "STR", {7, -1, -1, -1}, 7},
{"chord_mode", "chord_mode", "RAD", {17, 11, -1, -1}, 8},
{"maximum_chord_height", "max_chord", "STR", {3, -1, -1, -1}, 9},
{"minimum_angle_control", "min_angle", "STR", {4, -1, -1, -1}, 10},
{"eliminate_small_features", "elim_small", "BOX", {15, -1, -1, -1}, 11},
{"minimum_hole_diameter", "min_hole", "STR", {2, -1, -1, -1}, 12},
{"minimum_chamfer_dimension", "min_chamfer", "STR", {2, -1, -1, -1}, 13},
{"minimum_blend_radius", "min_round", "STR", {2, -1, -1, -1}, 14},
{"facetize_everything", "facets_only", "BOX", {16, -1, -1, -1}, 15},
{"export_facets_to_stl", "export_stl", "BOX", {15, -1, -1, -1}, 16},
{"reject_failed_bots", "check_solidity", "BOX", {15, -1, -1, -1}, 17},
{"box_replaces_failed_part", "create_boxes", "BOX", {15, -1, -1, -1}, 18},
{"write_surface_normals", "write_normals", "BOX", {15, -1, -1, -1}, 19},
{NULL, NULL, NULL, {-1, -1, -1, -1}, -1}
};
#endif /* CREO_PROFILE_CONTROLS_H */
Binary file not shown.
+163 -175
View File
@@ -2,7 +2,7 @@
!* Title: creo_brl.res
!* Purpose: Dialog box resource file for Creo to BRL-CAD Converter
!* Version: Created for use with Creo version 7.0.9.0
!* Date: 3/22/2023
!* Date: 2/5/2024
!*
!* Notes:
!* 1) Refer to: ..\src\external\Creo\main.cpp for more information
@@ -44,8 +44,8 @@
(SubLayout transform_controls)
(Separator separator2)
(SubLayout process_controls)
(SubLayout small_feature_controls)
(SubLayout tessellation_controls)
(SubLayout small_feature_controls)
(SubLayout surface_controls)
(Separator separator3)
(SubLayout action_buttons)
@@ -83,10 +83,10 @@
(Grid (Rows 1) (Cols 1 1)
(Grid (Rows 1 1) (Cols 1)
process_controls
tessellation_controls
small_feature_controls
)
(Grid (Rows 1 1) (Cols 1)
small_feature_controls
tessellation_controls
surface_controls
)
)
@@ -104,7 +104,7 @@
(Label out_fname_l)
(InputPanel out_fname)
(Label log_file_type_l)
(RadioGroup log_file_type_rg)
(RadioGroup log_file_type)
(Label log_fname_l)
(InputPanel log_fname)
(Label mtl_fname_l)
@@ -132,19 +132,19 @@
(log_file_type_l.Label "Process log criteria:")
(log_file_type_l.LeftOffset 4)
(log_file_type_l.RightOffset 0)
(log_file_type_rg.Alignment 0)
(log_file_type_rg.AttachLeft True)
(log_file_type_rg.Labels "Failure"
(log_file_type.Alignment 0)
(log_file_type.AttachLeft True)
(log_file_type.Labels "Failure"
"Success"
"Failure or Success"
"All (Debug)")
(log_file_type_rg.Names "Failure"
"Success"
"Failure/Success"
"All/(Debug)")
(log_file_type_rg.LeftOffset 0)
(log_file_type_rg.Orientation False)
(log_file_type_rg.RightOffset 4)
(log_file_type.Names "failure"
"success"
"failure/success"
"all/(debug)")
(log_file_type.LeftOffset 0)
(log_file_type.Orientation False)
(log_file_type.RightOffset 4)
(log_fname_l.AttachRight True)
(log_fname_l.Label "Process log file name:")
(log_fname_l.LeftOffset 4)
@@ -162,7 +162,7 @@
(mtl_fname.HelpText "Enter a file name here for the material translation file (optional)")
(mtl_fname.LeftOffset 0)
(mtl_fname.RightOffset 4)
(mtl_fname.Value "./ptc_materials.mtl")
(mtl_fname.Value "")
(empty_label.AttachRight True)
(empty_label.Label "")
(parameter_label.AttachLeft True)
@@ -176,7 +176,7 @@
(param_rename.HelpText "Enter a comma-separated list of Creo parameters which create BRL-CAD object names (optional)")
(param_rename.LeftOffset 0)
(param_rename.RightOffset 4)
(param_rename.Value "nomenclature")
(param_rename.Value "")
(param_save_l.AttachRight True)
(param_save_l.Label "Preserve as attributes:")
(param_save_l.LeftOffset 4)
@@ -185,7 +185,7 @@
(param_save.HelpText "Enter a comma-separated list of Creo parameters to preserve in the BRL-CAD .g file (optional)")
(param_save.LeftOffset 0)
(param_save.RightOffset 4)
(param_save.Value "nomenclature,part_name")
(param_save.Value "")
(.AttachTop True)
(.BottomOffset 4)
(.Decorated False)
@@ -195,7 +195,7 @@
out_fname_l
out_fname
log_file_type_l
log_file_type_rg
log_file_type
log_fname_l
log_fname
mtl_fname_l
@@ -214,32 +214,32 @@
(Layout transform_controls
(Components
(Label transform_l)
(RadioGroup transform_rg)
(RadioGroup transform)
)
(Resources
(transform_l.AttachRight True)
(transform_l.Label "Coordinate Transformation:")
(transform_l.LeftOffset 4)
(transform_l.RightOffset 4)
(transform_rg.Alignment 0)
(transform_rg.AttachLeft True)
(transform_rg.Labels "None"
"x to z"
"y to z")
(transform_rg.Names "none"
"x_to_z"
"y_to_z")
(transform_rg.LeftOffset 0)
(transform_rg.Orientation False)
(transform_rg.RightOffset 4)
(transform.Alignment 0)
(transform.AttachLeft True)
(transform.Labels "None "
"y -> z"
"x -> z")
(transform.Names "none"
"y_to_z"
"x_to_z")
(transform.LeftOffset 0)
(transform.Orientation False)
(transform.RightOffset 4)
(.AttachTop True)
(.BottomOffset 2)
(.Decorated False)
(.TopOffset 2)
(.Layout
(Grid (Rows 1 ) (Cols 1 1)
(Grid (Rows 1) (Cols 1 1)
transform_l
transform_rg
transform
)
)
)
@@ -255,24 +255,28 @@
(Resources
(region_counter_l.AttachRight True)
(region_counter_l.Label "Initial region counter:")
(region_counter_l.LeftOffset 16)
(region_counter_l.LeftOffset 2)
(region_counter_l.RightOffset 0)
(region_counter_l.TopOffset 22)
(region_counter.AttachLeft True)
(region_counter.HelpText "Enter desired value for initial region counter")
(region_counter.HelpText "Enter desired value for intial region counter")
(region_counter.InputType 2)
(region_counter.LeftOffset 0)
(region_counter.RightOffset 2)
(region_counter.Value "1000")
(region_counter.TopOffset 22)
(region_counter.Value "")
(min_luminance_l.AttachRight True)
(min_luminance_l.Label "Min luminance, %:")
(min_luminance_l.LeftOffset 2)
(min_luminance_l.RightOffset 0)
(min_luminance_l.TopOffset 2)
(min_luminance.AttachLeft True)
(min_luminance.HelpText "Enter desired minimum luminance threshold [0 to 100] percent")
(min_luminance.InputType 2)
(min_luminance.LeftOffset 0)
(min_luminance.RightOffset 2)
(min_luminance.Value "30")
(min_luminance.TopOffset 2)
(min_luminance.Value "")
(.Alignment 0)
(.AttachLeft True)
(.AttachTop True)
@@ -280,7 +284,7 @@
(.Label "Process Controls")
(.LeftOffset 10)
(.RightOffset 2)
(.TopOffset 0)
(.TopOffset 2)
(.Layout
(Grid (Rows 1 1) (Cols 1 1)
region_counter_l
@@ -292,109 +296,20 @@
)
)
(Layout tessellation_controls
(Components
(Label max_chord_l)
(InputPanel max_chord)
(Label min_chord_l)
(InputPanel min_chord)
(Label max_angle_l)
(InputPanel max_angle)
(Label min_angle_l)
(InputPanel min_angle)
(Label max_steps_l)
(InputPanel max_steps)
)
(Resources
(max_chord_l.AttachRight True)
(max_chord_l.Label "Max chord height, mm:")
(max_chord_l.LeftOffset 2)
(max_chord_l.RightOffset 0)
(max_chord.AttachLeft True)
(max_chord.HelpText "Enter maximum chord height for tessellation of curved surfaces")
(max_chord.InputType 3)
(max_chord.LeftOffset 0)
(max_chord.RightOffset 2)
(max_chord.Value "0.0")
(min_chord_l.AttachRight True)
(min_chord_l.Label "Min chord height, mm:")
(min_chord_l.LeftOffset 2)
(min_chord_l.RightOffset 0)
(min_chord.AttachLeft True)
(min_chord.HelpText "Enter minimum chord height for tessellation of curved surfaces")
(min_chord.InputType 3)
(min_chord.LeftOffset 0)
(min_chord.RightOffset 2)
(min_chord.Value "0.0")
(max_angle_l.AttachRight True)
(max_angle_l.Label "Max angle control:")
(max_angle_l.LeftOffset 2)
(max_angle_l.RightOffset 0)
(max_angle.AttachLeft True)
(max_angle.HelpText "Larger values here produce finer tessellations [0.0 to 1.0]")
(max_angle.InputType 3)
(max_angle.LeftOffset 0)
(max_angle.RightOffset 2)
(max_angle.Value "1.0")
(min_angle_l.AttachRight True)
(min_angle_l.Label "Min angle control:")
(min_angle_l.LeftOffset 2)
(min_angle_l.RightOffset 0)
(min_angle.AttachLeft True)
(min_angle.HelpText "Larger values here produce finer tessellations [0.0 to 1.0]")
(min_angle.InputType 3)
(min_angle.LeftOffset 0)
(min_angle.RightOffset 2)
(min_angle.Value "0.1")
(max_steps_l.AttachRight True)
(max_steps_l.Label "Maximum number of steps:")
(max_steps_l.LeftOffset 2)
(max_steps_l.RightOffset 0)
(max_steps.AttachLeft True)
(max_steps.HelpText "Enter maximum number of tessellation attempts")
(max_steps.InputType 2)
(max_steps.LeftOffset 0)
(max_steps.RightOffset 2)
(max_steps.Value "50")
(.Alignment 0)
(.AttachLeft True)
(.AttachTop True)
(.Decorated True)
(.Label "Tessellation Controls")
(.LeftOffset 10)
(.RightOffset 2)
(.TopOffset 1)
(.Layout
(Grid (Rows 1 1 1 1 1) (Cols 1 1)
max_chord_l
max_chord
min_chord_l
min_chord
max_angle_l
max_angle
min_angle_l
min_angle
max_steps_l
max_steps
)
)
)
)
(Layout small_feature_controls
(Components
(CheckButton elim_small)
(Label min_hole_l)
(InputPanel min_hole)
(Label min_chamfer_l)
(InputPanel min_chamfer)
(Label min_round_l)
(InputPanel min_round)
(CheckButton elim_small)
(Label min_hole_l)
(InputPanel min_hole)
(Label min_chamfer_l)
(InputPanel min_chamfer)
(Label min_round_l)
(InputPanel min_round)
)
(Resources
(elim_small.AttachRight True)
(elim_small.AttachTop True)
(elim_small.BottomOffset 0)
(elim_small.BottomOffset 2)
(elim_small.HelpText "Select this to ignore holes, rounds, and chamfers smaller than the specified minimums")
(elim_small.Label "Ignore minimum sizes")
(elim_small.RightOffset 10)
@@ -404,9 +319,9 @@
(min_hole_l.AttachTop True)
(min_hole_l.BottomOffset 0)
(min_hole_l.Label "Hole diameter, mm:")
(min_hole_l.LeftOffset 2)
(min_hole_l.LeftOffset 9)
(min_hole_l.RightOffset 0)
(min_hole_l.TopOffset 2)
(min_hole_l.TopOffset 4)
(min_hole.AttachLeft True)
(min_hole.AttachTop True)
(min_hole.BottomOffset 0)
@@ -416,14 +331,14 @@
(min_hole.LeftOffset 0)
(min_hole.RightOffset 2)
(min_hole.TopOffset 0)
(min_hole.Value "0.0")
(min_hole.Value "")
(min_chamfer_l.AttachRight True)
(min_chamfer_l.AttachTop True)
(min_chamfer_l.BottomOffset 0)
(min_chamfer_l.Label "Chamfer dimension, mm:")
(min_chamfer_l.LeftOffset 2)
(min_chamfer_l.LeftOffset 9)
(min_chamfer_l.RightOffset 0)
(min_chamfer_l.TopOffset 0)
(min_chamfer_l.TopOffset 4)
(min_chamfer.AttachLeft True)
(min_chamfer.AttachTop True)
(min_chamfer.BottomOffset 0)
@@ -432,15 +347,15 @@
(min_chamfer.InputType 3)
(min_chamfer.LeftOffset 0)
(min_chamfer.RightOffset 2)
(min_chamfer.TopOffset 0)
(min_chamfer.Value "0.0")
(min_chamfer.TopOffset 2)
(min_chamfer.Value "")
(min_round_l.AttachRight True)
(min_round_l.AttachTop True)
(min_round_l.BottomOffset 0)
(min_round_l.Label "Blend radius, mm:")
(min_round_l.LeftOffset 2)
(min_round_l.LeftOffset 9)
(min_round_l.RightOffset 0)
(min_round_l.TopOffset 0)
(min_round_l.TopOffset 4)
(min_round.AttachLeft True)
(min_round.AttachTop True)
(min_round.BottomOffset 0)
@@ -449,16 +364,16 @@
(min_round.InputType 3)
(min_round.LeftOffset 0)
(min_round.RightOffset 2)
(min_round.TopOffset 0)
(min_round.Value "0.0")
(min_round.TopOffset 2)
(min_round.Value "")
(.Alignment 0)
(.AttachLeft True)
(.AttachTop True)
(.Decorated True)
(.Label "Small Feature Controls")
(.LeftOffset 2)
(.RightOffset 10)
(.TopOffset 0)
(.LeftOffset 10)
(.RightOffset 2)
(.TopOffset 2)
(.Layout
(Grid (Rows 1 1) (Cols 1)
elim_small
@@ -475,50 +390,122 @@
)
)
(Layout tessellation_controls
(Components
(Label chord_mode_l)
(RadioGroup chord_mode)
(Label max_chord_l)
(InputPanel max_chord)
(Label min_angle_l)
(InputPanel min_angle)
)
(Resources
(chord_mode_l.AttachRight True)
(chord_mode_l.Label "Chord mode:")
(chord_mode_l.LeftOffset 7)
(chord_mode_l.RightOffset 0)
(chord_mode.Alignment 0)
(chord_mode.AttachLeft True)
(chord_mode.Labels "%"
"mm")
(chord_mode.Names "percent"
"millimeter")
(chord_mode.HelpText "Select input mode for maximum chord height, relative [0 to 100] percent or absolute [millimeters]")
(chord_mode.LeftOffset 32)
(chord_mode.Orientation False)
(max_chord_l.AttachRight True)
(max_chord_l.Label "Max chord height:")
(max_chord_l.LeftOffset 7)
(max_chord_l.RightOffset 0)
(max_chord.AttachLeft True)
(max_chord.HelpText "Enter maximum chord height value, smaller values produce finer tessellations")
(max_chord.InputType 3)
(max_chord.LeftOffset 0)
(max_chord.RightOffset 2)
(max_chord.Value "")
(min_angle_l.AttachRight True)
(min_angle_l.BottomOffset 0)
(min_angle_l.Label "Min angle control:")
(min_angle_l.LeftOffset 7)
(min_angle_l.RightOffset 0)
(min_angle.AttachLeft True)
(min_angle.BottomOffset 0)
(min_angle.HelpText "Enter minimum angle control value, larger values produce finer tessellations [0 to 1] radians")
(min_angle.InputType 3)
(min_angle.LeftOffset 0)
(min_angle.RightOffset 2)
(min_angle.Value "")
(.Alignment 0)
(.AttachLeft True)
(.AttachTop True)
(.Decorated True)
(.Label "Tessellation Controls")
(.LeftOffset 2)
(.RightOffset 10)
(.TopOffset 2)
(.Layout
(Grid (Rows 1 1 1) (Cols 1 1)
chord_mode_l
chord_mode
max_chord_l
max_chord
min_angle_l
min_angle
)
)
)
)
(Layout surface_controls
(Components
(CheckButton facets_only)
(CheckButton export_stl)
(CheckButton check_solidity)
(CheckButton create_boxes)
(CheckButton get_normals)
(CheckButton write_normals)
)
(Resources
(facets_only.AttachLeft True)
(facets_only.AttachTop True)
(facets_only.BottomOffset 0)
(facets_only.TopOffset 0)
(facets_only.HelpText "Select this to produce a faceted approximation for each region with no CSG")
(facets_only.Label "Facetize everything, (no CSG)")
(facets_only.LeftOffset 0)
(facets_only.RightOffset 88)
(facets_only.Set True)
(facets_only.LeftOffset 7)
(facets_only.Set False)
(facets_only.TopOffset 0)
(export_stl.AttachLeft True)
(export_stl.AttachTop True)
(export_stl.BottomOffset 0)
(export_stl.HelpText "Select this to export faceted approximation to an STL file")
(export_stl.Label "Export facets to STL file")
(export_stl.LeftOffset 7)
(export_stl.Set False)
(export_stl.TopOffset 0)
(check_solidity.AttachLeft True)
(check_solidity.AttachTop True)
(check_solidity.BottomOffset 0)
(check_solidity.HelpText "Select this to reject BoTs that fail the solidity test (no unmated edges)")
(check_solidity.Label "Reject BoTs that fail solidity")
(check_solidity.LeftOffset 0)
(check_solidity.RightOffset 88)
(check_solidity.Set True)
(check_solidity.TopOffset 1)
(check_solidity.LeftOffset 7)
(check_solidity.Set False)
(check_solidity.TopOffset 0)
(create_boxes.AttachLeft True)
(create_boxes.AttachTop True)
(create_boxes.BottomOffset 0)
(create_boxes.HelpText "Select this to create a bounding box solid from the Creo part upon part tessellation failure")
(create_boxes.Label "Bounding box replaces failed part")
(create_boxes.LeftOffset 0)
(create_boxes.RightOffset 88)
(create_boxes.Set True)
(create_boxes.TopOffset 1)
(get_normals.AttachLeft True)
(get_normals.AttachTop True)
(get_normals.BottomOffset 0)
(get_normals.HelpText "Select this to save surface normals in BoTs (raytracing looks smoother)")
(get_normals.Label "Write surface normals")
(get_normals.LeftOffset 0)
(get_normals.RightOffset 88)
(get_normals.Set False)
(get_normals.TopOffset 1)
(create_boxes.Label "Replace failed parts with bounding box")
(create_boxes.LeftOffset 7)
(create_boxes.RightOffset 23)
(create_boxes.Set False)
(create_boxes.TopOffset 0)
(write_normals.AttachLeft True)
(write_normals.AttachTop True)
(write_normals.HelpText "Select this to save surface normals in BoTs (raytracing looks smoother)")
(write_normals.Label "Write surface normals")
(write_normals.LeftOffset 7)
(write_normals.Set False)
(write_normals.TopOffset 0)
(.Alignment 0)
(.AttachLeft True)
(.AttachTop True)
@@ -526,13 +513,14 @@
(.Label "Surface Controls")
(.LeftOffset 2)
(.RightOffset 10)
(.TopOffset 1)
(.TopOffset 2)
(.Layout
(Grid (Rows 1 1 1 1) (Cols 1)
(Grid (Rows 1 1 1 1 1) (Cols 1)
facets_only
export_stl
check_solidity
create_boxes
get_normals
write_normals
)
)
)
@@ -545,7 +533,7 @@
)
(Resources
(doit.AttachRight True)
(doit.HelpText "Start converting the currently displayed object")
(doit.HelpText "Convert the currently displayed object")
(doit.Label "Convert")
(quit.AttachLeft True)
(quit.HelpText "Close this window")
+1 -1
View File
@@ -52,7 +52,7 @@
# The conditional suppression of attributes is intended to permit BRL-CAD
# users to quickly identify Creo parts which contain what the user may deem
# to be an unwanted Creo material assignment. Resolving disparities with
# the material assigned in the upstream Creo part model is a desirable
# the material assigned in the upstream Creo part model is a desireable
# "best practice" in the conversion of CAD models from Creo to BRL-CAD in
# an effort to enhance process automation.
#
+17 -8
View File
@@ -2,7 +2,7 @@
* S H I M . C P P
* BRL-CAD
*
* Published in 2023 by the United States Government.
* Published in 2024 by the United States Government.
* This work is in the public domain.
*
*/
@@ -21,7 +21,7 @@
/* Functions */
extern "C" int ProArrayAlloc(int,int,int,void**) {return 0;}
extern "C" int ProArrayFree(void**) {return 0;}
extern "C" int ProArrayObjectAdd(ProArray *, int, int, void*) {return 0;}
extern "C" int ProArrayObjectAdd(ProArray*,int,int,void*) {return 0;}
extern "C" int ProArraySizeGet(ProArray,int*) {return 0;}
extern "C" int ProAsmcompMdlGet(ProFeature*,void**) {return 0;}
extern "C" int ProAsmcompMdlMdlnameGet(ProFeature*,int*,wchar_t*) {return 0;}
@@ -32,6 +32,7 @@ extern "C" int ProBsplinesrfdataGet(void**,int[2],double**,double**,double**,Pro
extern "C" int ProCmdActionAdd(const char*,int(*)(int,int*,void*),int,int(*)(int),int,int,int*) {return 0;}
extern "C" int ProDimensionTypeGet(void**,int*) {return 0;}
extern "C" int ProDimensionValueGet(void**,double *) {return 0;}
extern "C" int ProDirectoryCurrentGet(void*) {return 0;}
extern "C" int ProElementDoubleGet(void*,void*,double*) {return 0;}
extern "C" int ProElementFree(void**) {return 0;}
extern "C" int ProElementIdGet(void*,int*) {return 0;}
@@ -39,6 +40,7 @@ extern "C" int ProElementIntegerGet(void*,void*,int*) {return 0;}
extern "C" int ProElementValueGet(void*,void**) {return 0;}
extern "C" int ProElementValuetypeGet(void*,int*) {return 0;}
extern "C" int ProElemtreeElementVisit(void*,void*,int (*)(void*,void*,void*,void*),int (*)(void*,void*,void*,void*),void*) {return 0;}
extern "C" int ProFeatureChildrenGet(void*,int**,int*) {return 0;}
extern "C" int ProFeatureDimensionVisit(ProFeature *,int (*)(void* *,int ,void*),int (*)(void**,void*),void*) {return 0;}
extern "C" int ProFeatureElemtreeCreate(ProFeature *,void**) {return 0;}
extern "C" int ProFeatureElemtreeExtract(ProFeature *,void*,int,void**) {return 0;}
@@ -63,7 +65,7 @@ extern "C" int ProMessageDisplay(wchar_t *,const char *,const char *) {return 0;
extern "C" int ProParameterInit(void *,wchar_t *,void *) {return 0;}
extern "C" int ProParameterValueGet(ProParameter *,void *) {return 0;}
extern "C" int ProParameterValueWithUnitsGet(ProParameter *,void *,void *) {return 0;}
extern "C" int ProParameterVisit (void **, void*, int (*)(ProParameter*,int,void*),void *) {return 0;}
extern "C" int ProParameterVisit(void **, void*, int (*)(ProParameter*, int, void*), void *) {return 0;}
extern "C" int ProParamvalueTypeGet(void **,void *) {return 0;}
extern "C" int ProParamvalueValueGet(void **,int,void *) {return 0;}
extern "C" int ProPartDensityGet(void*,double*) {return 0;}
@@ -75,9 +77,14 @@ extern "C" int ProSolidMassPropertyGet(void*,void*,ProMassProperty*) {return 0;}
extern "C" int ProSolidOutlineGet(void*, Pro3dPnt*) {return 0;}
extern "C" int ProStringVerstampGet(void*, void**) {return 0;}
extern "C" int ProStringarrayFree(char**,int) {return 0;}
extern "C" int ProSurfaceAreaEval(void*,double*) {return 0;}
extern "C" int ProSurfaceSideAppearancepropsGet(void**,int,ProSurfaceAppearanceProps*) {return 0;}
extern "C" int ProUICheckbuttonActivateActionSet(const char*,const char*,void(*)(char*,char*,void*),void*) {return 0;}
extern "C" int ProUICheckbuttonDisable(const char*,const char*) {return 0;}
extern "C" int ProUICheckbuttonEnable(const char*,const char*) {return 0;}
extern "C" int ProUICheckbuttonGetState(const char*,const char*,int*) {return 0;}
extern "C" int ProUICheckbuttonSet(const char*,const char*) {return 0;}
extern "C" int ProUICheckbuttonUnset(const char*,const char*) {return 0;}
extern "C" int ProUIDialogActivate(const char*, int*) {return 0;}
extern "C" int ProUIDialogCreate(const char *,const char *) {return 0;}
extern "C" int ProUIDialogDestroy(const char *) {return 0;}
@@ -88,9 +95,11 @@ extern "C" int ProUIInputpanelValueSet(const char *,const char *,wchar_t*) {retu
extern "C" int ProUILabelTextSet(const char *,const char *,wchar_t *) {return 0;}
extern "C" int ProUIPushbuttonActivateActionSet(const char *,const char *,void (*)(char*,char *,void*),void*) {return 0;}
extern "C" int ProUIRadiogroupSelectednamesGet(const char*,const char*,int*,char***) {return 0;}
extern "C" int ProUIRadiogroupSelectednamesSet(const char*,const char*,int ,char** ) {return 0;}
extern "C" int ProUITextareaValueSet(const char *,const char *,wchar_t*) {return 0;}
extern "C" int ProUnitConversionCalculate(void**,void**,ProUnitConversion*) {return 0;}
extern "C" int ProUnitsystemUnitGet(void**,int,void**) {return 0;}
extern "C" int ProUnitConversionCalculate(ProUnititem*,ProUnititem*,ProUnitConversion*) {return 0;}
extern "C" int ProUnitsystemTypeGet(void**,ProUnitsystemType*) {return 0;}
extern "C" int ProUnitsystemUnitGet(void**,int,ProUnititem*) {return 0;}
extern "C" int ProUtilCollectParameters(void**,void**) {return 0;}
extern "C" int ProValueDataGet(void*,ProValueData*) {return 0;}
extern "C" int ProVerstampEqual(void*, void*) {return 0;}
@@ -105,15 +114,15 @@ extern "C" void ProContourTraversalGet(void*,int*) {}
extern "C" void ProMdlIsSkeleton(void*, int*) {}
extern "C" void ProMessageClear() {}
extern "C" void ProPartTessellationFree(ProSurfaceTessellationData**) {}
extern "C" void ProStringToWstring(wchar_t*,const char*) {}
extern "C" void ProStringToWstring(wchar_t*, char*) {}
extern "C" void ProSurfaceContourVisit(void*,int(*)(void*,int,void*),int(*)(void*,void*), void*) {}
extern "C" void ProSurfaceIdGet(void*,int*) {}
extern "C" void ProSurfaceToNURBS(void*,void***) {}
extern "C" void ProSurfacedataGet(void*,int*,double*,double*,int*,void**,int*) {}
extern "C" void ProUIInputpanelMaxlenSet(const char*,const char*,int) {}
extern "C" void ProUIMessageDialogDisplay(int,const wchar_t *,const wchar_t *,ProUIMessageButton*,int,ProUIMessageButton*) {}
extern "C" void ProUnitInit(void*,const wchar_t *,void**) {}
extern "C" void ProWstringToString(char*,wchar_t*) {}
extern "C" void ProUnitInit(void*,const wchar_t *,ProUnititem*) {}
extern "C" void ProWstringToString(char*, wchar_t*) {}
extern "C" void** PRO_CURVE_DATA(void*) {return NULL;}
// Local Variables:
+51 -31
View File
@@ -2,7 +2,7 @@
* S H I M . H
* BRL-CAD
*
* Published in 2023 by the United States Government.
* Published in 2024 by the United States Government.
* This work is in the public domain.
*
*/
@@ -84,26 +84,34 @@
#define PRO_MDLFILE_PART 62
#define PRO_MDL_ASSEMBLY 63
#define PRO_MDL_PART 64
#define PRO_PARAM_STRING 65
#define PRO_SRF_B_SPL 66
#define PRO_SURF_ORIENT_IN 67
#define PRO_TK_BAD_CONTEXT 68
#define PRO_TK_BAD_INPUTS 69
#define PRO_TK_CONTINUE 70
#define PRO_TK_GENERAL_ERROR 71
#define PRO_TK_NO_ERROR 72
#define PRO_TK_NOT_EXIST 73
#define PRO_TK_SUPP_PARENTS 74
#define PRO_UI_MESSAGE_OK 75
#define PRO_UNITTYPE_LENGTH 76
#define PRO_VALUE_UNUSED 77
#define uiProe2ndImmediate 78
#define PRO_PARAM_INTEGER 79
#define PRO_PARAM_BOOLEAN 80
#define PRO_PARAM_DOUBLE 81
#define PRO_VALUE_TYPE_INT 82
#define PRO_VALUE_TYPE_DOUBLE 83
#define PRO_FEAT_EXTRACT_NO_OPTS 84
#define PRO_NAME_SIZE 65
#define PRO_PARAM_STRING 66
#define PRO_SRF_B_SPL 67
#define PRO_SURF_ORIENT_IN 68
#define PRO_TK_BAD_CONTEXT 69
#define PRO_TK_BAD_INPUTS 70
#define PRO_TK_CONTINUE 71
#define PRO_TK_GENERAL_ERROR 72
#define PRO_TK_INCOMPLETE_TESS 73
#define PRO_TK_NO_ERROR 74
#define PRO_TK_NOT_EXIST 75
#define PRO_TK_NOT_VALID 76
#define PRO_TK_SUPP_PARENTS 77
#define PRO_UI_MESSAGE_OK 78
#define PRO_UNITSYSTEM_MLT 79
#define PRO_UNITTYPE_ANGLE 80
#define PRO_UNITTYPE_FORCE 81
#define PRO_UNITTYPE_MASS 82
#define PRO_UNITTYPE_LENGTH 83
#define PRO_UNITTYPE_TIME 84
#define PRO_VALUE_UNUSED 85
#define uiProe2ndImmediate 86
#define PRO_PARAM_INTEGER 87
#define PRO_PARAM_BOOLEAN 88
#define PRO_PARAM_DOUBLE 89
#define PRO_VALUE_TYPE_INT 90
#define PRO_VALUE_TYPE_DOUBLE 91
#define PRO_FEAT_EXTRACT_NO_OPTS 92
/* Eight definitions sourced from ProObjects.h */
#define ProMdlToSolid(mdl) ((ProSolid) mdl)
@@ -134,6 +142,7 @@ typedef int ProSrftype;
typedef int ProSurfaceOrient;
typedef int ProType;
typedef int ProUIMessageButton;
typedef int ProUnitsystemType;
typedef int ProValueDataType;
typedef int uiCmdAccessMode;
typedef int uiCmdAccessState;
@@ -160,12 +169,13 @@ typedef void* ProSolidBody;
typedef void* ProSurface;
typedef void* ProSurfacedata;
typedef void* ProSurfaceshapedata;
typedef void* ProUnititem;
typedef void* ProUnitsystem;
typedef void* ProValue;
typedef void* ProWVerstamp;
typedef wchar_t ProFileName[1];
typedef wchar_t ProLine[1];
typedef wchar_t ProName[1];
typedef wchar_t ProPath[1];
/*
* Definitions where we need to provide internal structure
@@ -176,26 +186,27 @@ typedef double ProVector[3];
typedef double ProUvParam[2];
typedef double ProMatrix[4][4];
typedef int ProIdTable[2];
typedef int __internal_facetset[3];
typedef int facet_set[3];
typedef struct pf {int id;} ProFeature;
typedef struct pmatl {wchar_t *matl_name;} ProMaterial;
typedef struct pmassp {double volume; double surface_area; double density; double mass;} ProMassProperty;
typedef struct proparam {wchar_t *id;} ProParameter;
typedef struct prouc {double scale;} ProUnitConversion;
typedef struct psap {double color_rgb[3];double transparency;double shininess;double diffuse;double highlite;} ProSurfaceAppearanceProps;
typedef struct pst {int n_facets;__internal_facetset *facets;point_t *vertices;point_t *normals;} ProSurfaceTessellationData;
typedef struct pstd {ProSurface surface;int n_vertices;point_t *vertices;point_t *normals;int n_facets;facet_set *facets;} ProSurfaceTessellationData;
typedef struct puitm {ProMdl owner; ProName name;} ProUnititem;
typedef struct pvdi {int i; int d;} __internal_ProValueData;
typedef struct pvdm {__internal_ProValueData v;} ProValueData;
/* Function types */
typedef int (*ProFeatureFilterAction)(ProFeature*,void*);
typedef int (*uiCmdCmdActFn)(int,int*,void*);
typedef int (*ProParameterAction)(ProParameter*,int,void*);
typedef int (*uiCmdCmdActFn)(int,int*,void*);
/* Functions */
extern "C" int ProArrayAlloc(int,int,int,void**);
extern "C" int ProArrayFree(void**);
extern "C" int ProArrayObjectAdd(ProArray *, int, int, void*);
extern "C" int ProArrayObjectAdd(ProArray*,int,int,void*);
extern "C" int ProArraySizeGet(ProArray,int*);
extern "C" int ProAsmcompMdlGet(ProFeature*,void**);
extern "C" int ProAsmcompMdlMdlnameGet(ProFeature*,int*,wchar_t*);
@@ -206,6 +217,7 @@ extern "C" int ProBsplinesrfdataGet(void**,int[2],double**,double**,double**,Pro
extern "C" int ProCmdActionAdd(const char*,int(*)(int,int*,void*),int,int(*)(int),int,int,int*);
extern "C" int ProDimensionTypeGet(void**,int*);
extern "C" int ProDimensionValueGet(void**,double *);
extern "C" int ProDirectoryCurrentGet(void*);
extern "C" int ProElementDoubleGet(void*,void*,double*);
extern "C" int ProElementFree(void**);
extern "C" int ProElementIdGet(void*,int*);
@@ -213,6 +225,7 @@ extern "C" int ProElementIntegerGet(void*,void*,int*);
extern "C" int ProElementValueGet(void*,void**);
extern "C" int ProElementValuetypeGet(void*,int*);
extern "C" int ProElemtreeElementVisit(void*,void*,int (*)(void*,void*,void*,void*),int (*)(void*,void*,void*,void*),void*);
extern "C" int ProFeatureChildrenGet(void*,int**,int*);
extern "C" int ProFeatureDimensionVisit(ProFeature *,int (*)(void* *,int ,void*),int (*)(void**,void*),void*);
extern "C" int ProFeatureElemtreeCreate(ProFeature *,void**);
extern "C" int ProFeatureElemtreeExtract(ProFeature *,void*,int,void**);
@@ -237,7 +250,7 @@ extern "C" int ProMessageDisplay(wchar_t *,const char *,const char *);
extern "C" int ProParameterInit(void *,wchar_t *,void *);
extern "C" int ProParameterValueGet(ProParameter *,void *);
extern "C" int ProParameterValueWithUnitsGet(ProParameter *,void *,void *);
extern "C" int ProParameterVisit (void **, void*,int (*)(ProParameter*,int,void*),void *);
extern "C" int ProParameterVisit(void **, void*, int (*)(ProParameter*, int, void*), void *);
extern "C" int ProParamvalueTypeGet(void **,void *);
extern "C" int ProParamvalueValueGet(void **,int,void *);
extern "C" int ProPartDensityGet(void*,double*);
@@ -250,8 +263,13 @@ extern "C" int ProSolidOutlineGet(void*, Pro3dPnt*);
extern "C" int ProStringVerstampGet(void*, void**);
extern "C" int ProStringarrayFree(char**,int);
extern "C" int ProSurfaceSideAppearancepropsGet(void**,int,ProSurfaceAppearanceProps*);
extern "C" int ProSurfaceAreaEval(void*,double*);
extern "C" int ProUICheckbuttonActivateActionSet(const char*,const char*,void(*)(char*,char*,void*),void*);
extern "C" int ProUICheckbuttonDisable(const char*,const char*);
extern "C" int ProUICheckbuttonEnable(const char*,const char*);
extern "C" int ProUICheckbuttonGetState(const char*,const char*,int*);
extern "C" int ProUICheckbuttonSet(const char*,const char*);
extern "C" int ProUICheckbuttonUnset(const char*,const char*);
extern "C" int ProUIDialogActivate(const char*, int*);
extern "C" int ProUIDialogCreate(const char *,const char *);
extern "C" int ProUIDialogDestroy(const char *);
@@ -262,9 +280,11 @@ extern "C" int ProUIInputpanelValueSet(const char *,const char *,wchar_t*);
extern "C" int ProUILabelTextSet(const char *,const char *,wchar_t *);
extern "C" int ProUIPushbuttonActivateActionSet(const char *,const char *,void (*)(char*,char *,void*),void*);
extern "C" int ProUIRadiogroupSelectednamesGet(const char*,const char*,int*,char***);
extern "C" int ProUIRadiogroupSelectednamesSet(const char*,const char*,int ,char** );
extern "C" int ProUITextareaValueSet(const char *,const char *,wchar_t*);
extern "C" int ProUnitConversionCalculate(void**,void**,ProUnitConversion*);
extern "C" int ProUnitsystemUnitGet(void**,int,void**);
extern "C" int ProUnitConversionCalculate(ProUnititem*,ProUnititem*,ProUnitConversion*);
extern "C" int ProUnitsystemTypeGet(void**,ProUnitsystemType*);
extern "C" int ProUnitsystemUnitGet(void**,int,ProUnititem*);
extern "C" int ProUtilCollectParameters(void**,void**);
extern "C" int ProValueDataGet(void*,ProValueData*);
extern "C" int ProVerstampEqual(void*, void*);
@@ -279,14 +299,14 @@ extern "C" void ProContourTraversalGet(void*,int*);
extern "C" void ProMdlIsSkeleton(void*, int*);
extern "C" void ProMessageClear();
extern "C" void ProPartTessellationFree(ProSurfaceTessellationData**);
extern "C" void ProStringToWstring(wchar_t*,const char*);
extern "C" void ProStringToWstring(wchar_t*, char*);
extern "C" void ProSurfaceContourVisit(void*,int(*)(void*,int,void*),int(*)(void*,void*), void*);
extern "C" void ProSurfaceIdGet(void*,int*);
extern "C" void ProSurfaceToNURBS(void*,void***);
extern "C" void ProSurfacedataGet(void*,int*,double*,double*,int*,void**,int*);
extern "C" void ProUIInputpanelMaxlenSet(const char*,const char*,int);
extern "C" void ProUIMessageDialogDisplay(int,const wchar_t *,const wchar_t *,ProUIMessageButton*,int,ProUIMessageButton*);
extern "C" void ProUnitInit(void*,const wchar_t *,void**);
extern "C" void ProUnitInit(void*,const wchar_t *,ProUnititem*);
extern "C" void ProWstringToString(char*,wchar_t*);
extern "C" void** PRO_CURVE_DATA(void*);
+967
View File
@@ -0,0 +1,967 @@
/**
* S N A P S H O T _ W R I T E R . C P P
* BRL-CAD
*
* Copyright (c) 2026 United States Government as represented by
* the U.S. Army Research Laboratory.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2.1 as published by the Free Software Foundation.
*/
/**
* @file snapshot_writer.cpp
*
* Creo Toolkit capture for neutral conversion requests.
*/
#include "common.h"
#include <cmath>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include "creo-brl.h"
#include "conversion_snapshot.h"
#include "snapshot_writer.h"
struct snapshot_settings_strings {
std::string output_path;
std::string log_path;
std::string material_path;
std::string rename_parameters;
std::string preserve_parameters;
};
struct snapshot_part_strings {
std::string model_name;
std::string model_version;
std::string material_name;
};
struct snapshot_part_capture {
struct creo_brl_snapshot_part part;
struct snapshot_part_strings strings;
std::vector<struct creo_brl_snapshot_vector> vertices;
std::vector<struct creo_brl_snapshot_triangle> triangles;
std::vector<struct creo_brl_snapshot_vector> normals;
std::vector<uint32_t> normal_indices;
};
struct snapshot_assembly_capture {
struct creo_brl_snapshot_assembly assembly;
std::string model_name;
std::string model_version;
std::vector<struct creo_brl_snapshot_assembly_member> members;
};
struct snapshot_scene_capture {
struct creo_brl_snapshot_settings settings;
struct snapshot_settings_strings settings_strings;
std::vector<struct snapshot_part_capture> parts;
std::vector<struct snapshot_assembly_capture> assemblies;
};
/* The legacy converter keeps this tolerance internal; the dialog has no min_edge control. */
static const double CREO_BRL_DEFAULT_MIN_EDGE_MM = 0.000254;
static_assert(sizeof(struct creo_brl_snapshot_header) == CREO_BRL_SNAPSHOT_HEADER_V1_SIZE,
"Snapshot header layout changed");
static_assert(sizeof(struct creo_brl_snapshot_settings) == CREO_BRL_SNAPSHOT_SETTINGS_V1_SIZE,
"Snapshot settings layout changed");
static_assert(sizeof(struct creo_brl_snapshot_part) == CREO_BRL_SNAPSHOT_PART_V1_SIZE,
"Snapshot part layout changed");
static_assert(sizeof(struct creo_brl_snapshot_assembly_member) ==
CREO_BRL_SNAPSHOT_ASSEMBLY_MEMBER_V2_SIZE,
"Snapshot assembly member layout changed");
static_assert(sizeof(struct creo_brl_snapshot_assembly) == CREO_BRL_SNAPSHOT_ASSEMBLY_V2_SIZE,
"Snapshot assembly layout changed");
static_assert(sizeof(struct creo_brl_snapshot_scene) == CREO_BRL_SNAPSHOT_SCENE_V2_SIZE,
"Snapshot scene layout changed");
static int
wide_to_utf8(const wchar_t *wide_text, std::string *text)
{
int size = 0;
if (!wide_text || !text)
return 0;
size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wide_text, -1, NULL, 0, NULL, NULL);
if (size <= 0)
return 0;
text->resize((size_t)size);
if (WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wide_text, -1,
&(*text)[0], size, NULL, NULL) != size)
return 0;
text->resize((size_t)size - 1);
return 1;
}
static int
dialog_text(const char *name, std::string *text)
{
wchar_t *wide_text = NULL;
const ProError err = ProUIInputpanelValueGet(CREO_UI_NAME, (char *)name, &wide_text);
const int converted = err == PRO_TK_NO_ERROR && wide_to_utf8(wide_text, text);
if (wide_text)
(void)ProWstringFree(wide_text);
return converted;
}
static int
dialog_number(const char *name, double *value)
{
std::string text;
char *end = NULL;
if (!dialog_text(name, &text) || text.empty())
return 0;
*value = strtod(text.c_str(), &end);
return end && *end == '\0' && std::isfinite(*value);
}
static int
dialog_integer(const char *name, int32_t *value)
{
std::string text;
char *end = NULL;
const long parsed = dialog_text(name, &text) ? strtol(text.c_str(), &end, 10) : 0;
if (!end || *end != '\0' || parsed < INT32_MIN || parsed > INT32_MAX)
return 0;
*value = (int32_t)parsed;
return 1;
}
static int
dialog_check(const char *name, uint32_t flag, uint32_t *flags)
{
ProBoolean checked = PRO_B_FALSE;
if (ProUICheckbuttonGetState(CREO_UI_NAME, (char *)name, &checked) != PRO_TK_NO_ERROR)
return 0;
if (checked)
*flags |= flag;
return 1;
}
static int
dialog_radio(const char *name, std::string *selection)
{
char **names = NULL;
int count = 0;
const ProError err = ProUIRadiogroupSelectednamesGet(CREO_UI_NAME, (char *)name, &count, &names);
if (err != PRO_TK_NO_ERROR || count != 1 || !names || !names[0]) {
if (names)
ProStringarrayFree(names, count);
return 0;
}
*selection = names[0];
ProStringarrayFree(names, count);
return 1;
}
static int
capture_settings(struct creo_brl_snapshot_settings *settings, snapshot_settings_strings *strings)
{
std::string selection;
memset(settings, 0, sizeof(*settings));
settings->structure_size = CREO_BRL_SNAPSHOT_SETTINGS_V1_SIZE;
if (!dialog_text("out_fname", &strings->output_path) || strings->output_path.empty() ||
!dialog_text("log_fname", &strings->log_path) ||
!dialog_text("mtl_fname", &strings->material_path) ||
!dialog_text("param_rename", &strings->rename_parameters) ||
!dialog_text("param_save", &strings->preserve_parameters) ||
!dialog_integer("region_counter", &settings->region_id) ||
!dialog_integer("min_luminance", &settings->min_luminance) ||
!dialog_number("max_chord", &settings->max_chord) ||
!dialog_number("min_angle", &settings->min_angle) ||
!dialog_radio("transform", &selection))
return 0;
settings->xform_mode = selection == "x_to_z" ? CREO_BRL_SNAPSHOT_XFORM_X_TO_Z :
selection == "y_to_z" ? CREO_BRL_SNAPSHOT_XFORM_Y_TO_Z :
CREO_BRL_SNAPSHOT_XFORM_NONE;
if (!dialog_radio("chord_mode", &selection))
return 0;
settings->chord_mode = selection == "percent" ? CREO_BRL_SNAPSHOT_CHORD_RELATIVE :
CREO_BRL_SNAPSHOT_CHORD_ABSOLUTE;
settings->max_angle = settings->min_angle * 1.5;
settings->max_facets = 0;
settings->max_steps = 1;
settings->log_type = CREO_BRL_SNAPSHOT_LOG_FAILURE;
settings->min_edge = CREO_BRL_DEFAULT_MIN_EDGE_MM;
if (!dialog_check("elim_small", CREO_BRL_SNAPSHOT_SETTING_ELIMINATE_SMALL_FEATURES,
&settings->flags))
return 0;
if ((settings->flags & CREO_BRL_SNAPSHOT_SETTING_ELIMINATE_SMALL_FEATURES) != 0 &&
(!dialog_number("min_hole", &settings->min_hole) ||
!dialog_number("min_chamfer", &settings->min_chamfer) ||
!dialog_number("min_round", &settings->min_round)))
return 0;
return dialog_check("facets_only", CREO_BRL_SNAPSHOT_SETTING_FACETS_ONLY, &settings->flags) &&
dialog_check("export_stl", CREO_BRL_SNAPSHOT_SETTING_EXPORT_STL, &settings->flags) &&
dialog_check("check_solidity", CREO_BRL_SNAPSHOT_SETTING_CHECK_SOLIDITY, &settings->flags) &&
dialog_check("create_boxes", CREO_BRL_SNAPSHOT_SETTING_CREATE_BOXES, &settings->flags) &&
dialog_check("write_normals", CREO_BRL_SNAPSHOT_SETTING_WRITE_NORMALS, &settings->flags);
}
static int
model_scale_to_mm(ProMdl model, double *scale)
{
ProUnitsystem system;
ProUnititem length;
char unit_name[PRO_NAME_SIZE + 1] = {0};
double inches = 0.0;
if (ProMdlPrincipalunitsystemGet(model, &system) != PRO_TK_NO_ERROR ||
ProUnitsystemUnitGet(&system, PRO_UNITTYPE_LENGTH, &length) != PRO_TK_NO_ERROR)
return 0;
ProWstringToString(unit_name, length.name);
if (strcmp(unit_name, "ft") == 0)
inches = 12.0;
else if (strcmp(unit_name, "in") == 0)
inches = 1.0;
else if (strcmp(unit_name, "cm") == 0)
inches = 1.0 / 2.54;
else if (strcmp(unit_name, "mm") == 0)
inches = 1.0 / 25.4;
else if (strcmp(unit_name, "m") == 0)
inches = 1.0 / 0.0254;
else
return 0;
*scale = inches * 25.4;
return 1;
}
static void
set_vector(struct creo_brl_snapshot_vector *destination, const ProVector source, double scale)
{
destination->coordinates[0] = source[0] * scale;
destination->coordinates[1] = source[1] * scale;
destination->coordinates[2] = source[2] * scale;
}
static unsigned char
snapshot_color_component(double component)
{
static const unsigned char COLOR_COMPONENT_MAX = 255;
if (!std::isfinite(component) || component <= 0.0)
return 0;
if (component >= 1.0)
return COLOR_COMPONENT_MAX;
return (unsigned char)(component * COLOR_COMPONENT_MAX + 0.5);
}
static void
capture_part_appearance(ProMdl model, struct creo_brl_snapshot_part *part)
{
ProModelitem model_item;
ProSurfaceAppearanceProps appearance;
const int surface_side = 0;
if (ProMdlToModelitem(model, &model_item) != PRO_TK_NO_ERROR ||
ProSurfaceSideAppearancepropsGet(&model_item, surface_side, &appearance) != PRO_TK_NO_ERROR)
return;
for (size_t component = 0; component < CREO_BRL_SNAPSHOT_COLOR_COMPONENT_COUNT; ++component)
part->color[component] = snapshot_color_component(appearance.color_rgb[component]);
part->color_is_set = 1;
part->flags |= CREO_BRL_SNAPSHOT_PART_HAS_COLOR;
}
static void
capture_mass_properties(ProMdl model, struct creo_brl_snapshot_part *part)
{
ProMassProperty mass_properties = {};
if (ProSolidMassPropertyGet(ProMdlToSolid(model), NULL, &mass_properties) != PRO_TK_NO_ERROR)
return;
part->density = mass_properties.density;
part->mass = mass_properties.mass;
part->volume = mass_properties.volume;
part->flags |= CREO_BRL_SNAPSHOT_PART_HAS_MASS_PROPERTIES;
}
static void
capture_model_version(ProMdl model, std::string *version)
{
ProWVerstamp stamp;
char *stamp_text = NULL;
if (ProMdlVerstampGet(model, &stamp) != PRO_TK_NO_ERROR ||
ProVerstampStringGet(stamp, &stamp_text) != PRO_TK_NO_ERROR || !stamp_text)
return;
*version = stamp_text;
ProVerstampStringFree(&stamp_text);
}
static int
capture_tessellation(ProMdl model, double scale, const struct creo_brl_snapshot_settings *settings,
std::vector<struct creo_brl_snapshot_vector> *vertices,
std::vector<struct creo_brl_snapshot_triangle> *triangles,
std::vector<struct creo_brl_snapshot_vector> *normals,
std::vector<uint32_t> *normal_indices)
{
ProSurfaceTessellationData *tessellation = NULL;
int surface_count = 0;
const double chord = settings->max_chord / scale;
const double angle = settings->min_angle;
const int write_normals = (settings->flags & CREO_BRL_SNAPSHOT_SETTING_WRITE_NORMALS) != 0;
if (chord <= 0.0 || angle <= 0.0 ||
ProPartTessellate(ProMdlToPart(model), chord, angle, PRO_B_TRUE, &tessellation) != PRO_TK_NO_ERROR ||
ProArraySizeGet((ProArray)tessellation, &surface_count) != PRO_TK_NO_ERROR)
goto failure;
for (int surface = 0; surface < surface_count; ++surface) {
const ProSurfaceTessellationData *data = &tessellation[surface];
for (int facet = 0; facet < data->n_facets; ++facet) {
struct creo_brl_snapshot_triangle triangle = {};
const size_t first_vertex = vertices->size();
if (first_vertex > UINT32_MAX - CREO_BRL_SNAPSHOT_TRIANGLE_VERTEX_COUNT)
goto failure;
for (unsigned int corner = 0; corner < CREO_BRL_SNAPSHOT_TRIANGLE_VERTEX_COUNT; ++corner) {
struct creo_brl_snapshot_vector vertex = {};
const int source_index = data->facets[facet][corner];
if (source_index < 0 || source_index >= data->n_vertices)
goto failure;
set_vector(&vertex, data->vertices[source_index], scale);
vertices->push_back(vertex);
triangle.vertices[corner] = (uint32_t)(first_vertex + corner);
if (write_normals) {
struct creo_brl_snapshot_vector normal = {};
set_vector(&normal, data->normals[source_index], 1.0);
normals->push_back(normal);
normal_indices->push_back((uint32_t)(normals->size() - 1));
}
}
triangles->push_back(triangle);
}
}
(void)ProPartTessellationFree(&tessellation);
return !vertices->empty();
failure:
if (tessellation)
(void)ProPartTessellationFree(&tessellation);
return 0;
}
static int
snapshot_open_for_write(const char *snapshot_path, FILE **snapshot_file)
{
const int wide_path_length = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
snapshot_path, -1, NULL, 0);
std::vector<wchar_t> wide_path;
if (wide_path_length <= 0)
return 0;
wide_path.resize((size_t)wide_path_length);
if (MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, snapshot_path, -1,
&wide_path[0], wide_path_length) != wide_path_length)
return 0;
*snapshot_file = _wfopen(&wide_path[0], L"wb");
return *snapshot_file != NULL;
}
static int
write_range(FILE *snapshot_file, const void *data, uint64_t size,
struct creo_brl_snapshot_range *range)
{
const __int64 offset = _ftelli64(snapshot_file);
if (!range)
return 0;
if (size == 0) {
range->offset = 0;
range->size = 0;
return 1;
}
if (offset < 0 || fwrite(data, 1, (size_t)size, snapshot_file) != size)
return 0;
range->offset = (uint64_t)offset;
range->size = size;
return 1;
}
static int
write_text(FILE *snapshot_file, const std::string& text, struct creo_brl_snapshot_range *range)
{
return write_range(snapshot_file, text.data(), (uint64_t)text.size(), range);
}
static int
capture_model_name(ProMdl model, std::string *model_name)
{
ProName name;
return ProMdlMdlnameGet(model, name) == PRO_TK_NO_ERROR &&
wide_to_utf8(name, model_name) && !model_name->empty();
}
static int
capture_part_definition(ProMdl model,
const struct creo_brl_snapshot_settings *settings,
struct snapshot_part_capture *capture)
{
ProName material_name;
Pro3dPnt bbox[2];
double scale = 0.0;
int have_bbox = 0;
memset(&capture->part, 0, sizeof(capture->part));
capture->vertices.clear();
capture->triangles.clear();
capture->normals.clear();
capture->normal_indices.clear();
capture->strings = snapshot_part_strings();
if (!capture_model_name(model, &capture->strings.model_name) ||
!model_scale_to_mm(model, &scale))
return CREO_BRL_SNAPSHOT_CAPTURE_MODEL_FAILURE;
capture->part.structure_size = CREO_BRL_SNAPSHOT_PART_V1_SIZE;
capture->part.region_id = settings->region_id;
capture->part.model_to_mm = scale;
capture_model_version(model, &capture->strings.model_version);
capture_part_appearance(model, &capture->part);
capture_mass_properties(model, &capture->part);
if (ProPartMaterialNameGet(ProMdlToPart(model), material_name) == PRO_TK_NO_ERROR &&
wide_to_utf8(material_name, &capture->strings.material_name) &&
!capture->strings.material_name.empty())
capture->part.flags |= CREO_BRL_SNAPSHOT_PART_HAS_MATERIAL;
if ((capture->part.flags & CREO_BRL_SNAPSHOT_PART_HAS_MASS_PROPERTIES) == 0 &&
ProPartDensityGet(ProMdlToPart(model), &capture->part.density) != PRO_TK_NO_ERROR)
capture->part.density = 0.0;
have_bbox = ProSolidOutlineGet(ProMdlToSolid(model), bbox) == PRO_TK_NO_ERROR;
if (have_bbox) {
for (unsigned int coordinate = 0; coordinate < CREO_BRL_SNAPSHOT_COORDINATE_COUNT; ++coordinate) {
capture->part.bbox_min.coordinates[coordinate] = bbox[0][coordinate] * scale;
capture->part.bbox_max.coordinates[coordinate] = bbox[1][coordinate] * scale;
}
const double dx = capture->part.bbox_max.coordinates[0] - capture->part.bbox_min.coordinates[0];
const double dy = capture->part.bbox_max.coordinates[1] - capture->part.bbox_min.coordinates[1];
const double dz = capture->part.bbox_max.coordinates[2] - capture->part.bbox_min.coordinates[2];
capture->part.bbox_area = 2.0 * (dx * dy + dx * dz + dy * dz);
capture->part.bbox_diagonal = sqrt(dx * dx + dy * dy + dz * dz);
capture->part.bbox_volume = dx * dy * dz;
}
if (capture_tessellation(model, scale, settings, &capture->vertices, &capture->triangles,
&capture->normals, &capture->normal_indices)) {
capture->part.flags |= CREO_BRL_SNAPSHOT_PART_HAS_MESH;
if (!capture->normals.empty())
capture->part.flags |= CREO_BRL_SNAPSHOT_PART_HAS_NORMALS;
return CREO_BRL_SNAPSHOT_CAPTURE_SUCCESS;
}
if (have_bbox && (settings->flags & CREO_BRL_SNAPSHOT_SETTING_CREATE_BOXES)) {
capture->part.flags |= CREO_BRL_SNAPSHOT_PART_HAS_BBOX_FALLBACK;
return CREO_BRL_SNAPSHOT_CAPTURE_SUCCESS;
}
return CREO_BRL_SNAPSHOT_CAPTURE_TESSELLATION_FAILURE;
}
static int
scene_part_index(const struct snapshot_scene_capture *scene,
const std::string& model_name,
uint32_t *index_out)
{
for (size_t index = 0; index < scene->parts.size(); ++index) {
if (scene->parts[index].strings.model_name == model_name) {
*index_out = (uint32_t)index;
return 1;
}
}
return 0;
}
static int
scene_assembly_index(const struct snapshot_scene_capture *scene,
const std::string& model_name,
uint32_t *index_out)
{
for (size_t index = 0; index < scene->assemblies.size(); ++index) {
if (scene->assemblies[index].model_name == model_name) {
*index_out = (uint32_t)index;
return 1;
}
}
return 0;
}
static int
capture_scene_part(ProMdl model, struct snapshot_scene_capture *scene, uint32_t *index_out)
{
std::string model_name;
struct snapshot_part_capture capture;
int result = CREO_BRL_SNAPSHOT_CAPTURE_MODEL_FAILURE;
if (!capture_model_name(model, &model_name))
return CREO_BRL_SNAPSHOT_CAPTURE_MODEL_FAILURE;
if (scene_part_index(scene, model_name, index_out))
return CREO_BRL_SNAPSHOT_CAPTURE_SUCCESS;
if (scene->parts.size() >= UINT32_MAX)
return CREO_BRL_SNAPSHOT_CAPTURE_MODEL_FAILURE;
result = capture_part_definition(model, &scene->settings, &capture);
if (result != CREO_BRL_SNAPSHOT_CAPTURE_SUCCESS)
return result;
*index_out = (uint32_t)scene->parts.size();
scene->parts.push_back(capture);
return CREO_BRL_SNAPSHOT_CAPTURE_SUCCESS;
}
static void
snapshot_identity_matrix(struct creo_brl_snapshot_matrix *matrix)
{
memset(matrix, 0, sizeof(*matrix));
matrix->elements[0] = 1.0;
matrix->elements[5] = 1.0;
matrix->elements[10] = 1.0;
matrix->elements[15] = 1.0;
}
static int
capture_component_matrix(ProMdl parent,
ProFeature *feature,
struct creo_brl_snapshot_matrix *matrix)
{
ProAsmcomppath component_path;
ProIdTable component_ids;
ProMatrix creo_matrix;
double scale = 0.0;
snapshot_identity_matrix(matrix);
if (!model_scale_to_mm(parent, &scale))
return 0;
component_ids[0] = feature->id;
if (ProAsmcomppathInit(ProMdlToSolid(parent), component_ids, 1, &component_path) !=
PRO_TK_NO_ERROR ||
ProAsmcomppathTrfGet(&component_path, PRO_B_TRUE, creo_matrix) != PRO_TK_NO_ERROR)
return 1;
for (unsigned int column = 0; column < 4; ++column) {
for (unsigned int row = 0; row < 4; ++row) {
double value = creo_matrix[row][column];
if (row == 3 && column < CREO_BRL_SNAPSHOT_COORDINATE_COUNT)
value *= scale;
matrix->elements[column * 4 + row] = value;
}
}
return 1;
}
static int capture_scene_assembly(ProMdl model,
struct snapshot_scene_capture *scene,
uint32_t *index_out);
struct snapshot_component_context {
struct snapshot_scene_capture *scene;
ProMdl parent;
uint32_t assembly_index;
int result;
};
static ProError
snapshot_component_filter(ProFeature *feature, ProAppData *UNUSED(data))
{
ProFeattype feature_type;
ProFeatStatus feature_status;
if (ProFeatureTypeGet(feature, &feature_type) != PRO_TK_NO_ERROR ||
feature_type != PRO_FEAT_COMPONENT ||
ProFeatureStatusGet(feature, &feature_status) != PRO_TK_NO_ERROR ||
feature_status != PRO_FEAT_ACTIVE)
return PRO_TK_CONTINUE;
return PRO_TK_NO_ERROR;
}
static ProError
capture_scene_component(ProFeature *feature, ProError UNUSED(status), ProAppData app_data)
{
struct snapshot_component_context *context =
(struct snapshot_component_context *)app_data;
ProMdl model = NULL;
ProMdlType model_type;
ProBoolean is_skeleton = PRO_B_FALSE;
struct creo_brl_snapshot_assembly_member member = {};
int result = CREO_BRL_SNAPSHOT_CAPTURE_MODEL_FAILURE;
if (context->result != CREO_BRL_SNAPSHOT_CAPTURE_SUCCESS)
return PRO_TK_NO_ERROR;
if (ProAsmcompMdlGet(feature, &model) != PRO_TK_NO_ERROR ||
ProMdlTypeGet(model, &model_type) != PRO_TK_NO_ERROR) {
context->result = CREO_BRL_SNAPSHOT_CAPTURE_MODEL_FAILURE;
return PRO_TK_NO_ERROR;
}
ProMdlIsSkeleton(model, &is_skeleton);
if (is_skeleton)
return PRO_TK_NO_ERROR;
if (!capture_component_matrix(context->parent, feature, &member.matrix)) {
context->result = CREO_BRL_SNAPSHOT_CAPTURE_MODEL_FAILURE;
return PRO_TK_NO_ERROR;
}
if (model_type == PRO_MDL_PART) {
member.target_type = CREO_BRL_SNAPSHOT_SCENE_NODE_PART;
result = capture_scene_part(model, context->scene, &member.target_index);
} else if (model_type == PRO_MDL_ASSEMBLY) {
member.target_type = CREO_BRL_SNAPSHOT_SCENE_NODE_ASSEMBLY;
result = capture_scene_assembly(model, context->scene, &member.target_index);
} else {
return PRO_TK_NO_ERROR;
}
if (result != CREO_BRL_SNAPSHOT_CAPTURE_SUCCESS) {
context->result = result;
return PRO_TK_NO_ERROR;
}
context->scene->assemblies[context->assembly_index].members.push_back(member);
return PRO_TK_NO_ERROR;
}
static int
capture_scene_assembly(ProMdl model,
struct snapshot_scene_capture *scene,
uint32_t *index_out)
{
struct snapshot_assembly_capture capture = {};
struct snapshot_component_context context = {};
if (!capture_model_name(model, &capture.model_name))
return CREO_BRL_SNAPSHOT_CAPTURE_MODEL_FAILURE;
if (scene_assembly_index(scene, capture.model_name, index_out))
return CREO_BRL_SNAPSHOT_CAPTURE_SUCCESS;
if (scene->assemblies.size() >= UINT32_MAX)
return CREO_BRL_SNAPSHOT_CAPTURE_MODEL_FAILURE;
capture.assembly.structure_size = CREO_BRL_SNAPSHOT_ASSEMBLY_V2_SIZE;
capture_model_version(model, &capture.model_version);
*index_out = (uint32_t)scene->assemblies.size();
scene->assemblies.push_back(capture);
context.scene = scene;
context.parent = model;
context.assembly_index = *index_out;
context.result = CREO_BRL_SNAPSHOT_CAPTURE_SUCCESS;
if (ProSolidFeatVisit(ProMdlToPart(model), capture_scene_component,
(ProFeatureFilterAction)snapshot_component_filter,
(ProAppData)&context) != PRO_TK_NO_ERROR ||
context.result != CREO_BRL_SNAPSHOT_CAPTURE_SUCCESS)
return context.result == CREO_BRL_SNAPSHOT_CAPTURE_SUCCESS ?
CREO_BRL_SNAPSHOT_CAPTURE_MODEL_FAILURE : context.result;
return CREO_BRL_SNAPSHOT_CAPTURE_SUCCESS;
}
static int
write_settings_strings(FILE *snapshot_file,
struct creo_brl_snapshot_settings *settings,
const struct snapshot_settings_strings& strings)
{
return write_text(snapshot_file, strings.output_path, &settings->output_path) &&
write_text(snapshot_file, strings.log_path, &settings->log_path) &&
write_text(snapshot_file, strings.material_path, &settings->material_path) &&
write_text(snapshot_file, strings.rename_parameters, &settings->rename_parameters) &&
write_text(snapshot_file, strings.preserve_parameters, &settings->preserve_parameters);
}
static int
write_part_capture(FILE *snapshot_file, struct snapshot_part_capture *capture)
{
capture->part.vertex_count = capture->vertices.size();
capture->part.triangle_count = capture->triangles.size();
capture->part.normal_count = capture->normals.size();
capture->part.normal_index_count = capture->normal_indices.size();
return write_text(snapshot_file, capture->strings.model_name, &capture->part.model_name) &&
write_text(snapshot_file, capture->strings.model_version, &capture->part.model_version) &&
write_text(snapshot_file, capture->strings.material_name, &capture->part.material_name) &&
write_range(snapshot_file, capture->vertices.data(),
capture->vertices.size() * sizeof(capture->vertices[0]),
&capture->part.vertices) &&
write_range(snapshot_file, capture->triangles.data(),
capture->triangles.size() * sizeof(capture->triangles[0]),
&capture->part.triangles) &&
write_range(snapshot_file, capture->normals.data(),
capture->normals.size() * sizeof(capture->normals[0]),
&capture->part.normals) &&
write_range(snapshot_file, capture->normal_indices.data(),
capture->normal_indices.size() * sizeof(capture->normal_indices[0]),
&capture->part.normal_indices);
}
static int
finish_snapshot(FILE *snapshot_file, struct creo_brl_snapshot_header *header)
{
const __int64 end_offset = _ftelli64(snapshot_file);
if (end_offset < 0)
return 0;
header->snapshot_size = (uint64_t)end_offset;
header->payload_size = header->snapshot_size - header->header_size;
return header->snapshot_size >= header->header_size;
}
static int
write_single_part_snapshot(const char *snapshot_path,
const struct creo_brl_snapshot_settings *settings,
const struct snapshot_settings_strings& settings_strings,
struct snapshot_part_capture *capture)
{
struct creo_brl_snapshot_header header = {};
struct creo_brl_snapshot_single_part request = {};
FILE *snapshot_file = NULL;
int result = CREO_BRL_SNAPSHOT_CAPTURE_WRITE_FAILURE;
if (!snapshot_open_for_write(snapshot_path, &snapshot_file))
return result;
memcpy(header.magic, creo_brl_snapshot_magic, sizeof(header.magic));
header.format_version = CREO_BRL_SNAPSHOT_FORMAT_VERSION_V1;
header.header_size = CREO_BRL_SNAPSHOT_HEADER_V1_SIZE;
header.payload_type = CREO_BRL_SNAPSHOT_PAYLOAD_SINGLE_PART;
request.structure_size = CREO_BRL_SNAPSHOT_SINGLE_PART_V1_SIZE;
request.settings = *settings;
request.part = capture->part;
if (fwrite(&header, 1, sizeof(header), snapshot_file) != sizeof(header) ||
fwrite(&request, 1, sizeof(request), snapshot_file) != sizeof(request) ||
!write_settings_strings(snapshot_file, &request.settings, settings_strings) ||
!write_part_capture(snapshot_file, capture) ||
!finish_snapshot(snapshot_file, &header))
goto cleanup;
request.part = capture->part;
if (_fseeki64(snapshot_file, 0, SEEK_SET) != 0 ||
fwrite(&header, 1, sizeof(header), snapshot_file) != sizeof(header) ||
fwrite(&request, 1, sizeof(request), snapshot_file) != sizeof(request))
goto cleanup;
result = CREO_BRL_SNAPSHOT_CAPTURE_SUCCESS;
cleanup:
fclose(snapshot_file);
return result;
}
static int
write_scene_snapshot(const char *snapshot_path, struct snapshot_scene_capture *capture,
uint32_t root_type, uint32_t root_index)
{
struct creo_brl_snapshot_header header = {};
struct creo_brl_snapshot_scene scene = {};
FILE *snapshot_file = NULL;
int result = CREO_BRL_SNAPSHOT_CAPTURE_WRITE_FAILURE;
if (!snapshot_open_for_write(snapshot_path, &snapshot_file))
return result;
memcpy(header.magic, creo_brl_snapshot_magic, sizeof(header.magic));
header.format_version = CREO_BRL_SNAPSHOT_FORMAT_VERSION_V2;
header.header_size = CREO_BRL_SNAPSHOT_HEADER_V1_SIZE;
header.payload_type = CREO_BRL_SNAPSHOT_PAYLOAD_SCENE;
scene.structure_size = CREO_BRL_SNAPSHOT_SCENE_V2_SIZE;
scene.settings = capture->settings;
scene.part_count = capture->parts.size();
scene.assembly_count = capture->assemblies.size();
scene.root_type = root_type;
scene.root_index = root_index;
if (scene.part_count > 0) {
scene.parts.offset = header.header_size + sizeof(scene);
scene.parts.size = scene.part_count * sizeof(struct creo_brl_snapshot_part);
}
if (scene.assembly_count > 0) {
scene.assemblies.offset = header.header_size + sizeof(scene) + scene.parts.size;
scene.assemblies.size = scene.assembly_count * sizeof(struct creo_brl_snapshot_assembly);
}
if (fwrite(&header, 1, sizeof(header), snapshot_file) != sizeof(header) ||
fwrite(&scene, 1, sizeof(scene), snapshot_file) != sizeof(scene))
goto cleanup;
for (size_t index = 0; index < capture->parts.size(); ++index) {
if (fwrite(&capture->parts[index].part, 1, sizeof(capture->parts[index].part), snapshot_file) !=
sizeof(capture->parts[index].part))
goto cleanup;
}
for (size_t index = 0; index < capture->assemblies.size(); ++index) {
if (fwrite(&capture->assemblies[index].assembly, 1,
sizeof(capture->assemblies[index].assembly), snapshot_file) !=
sizeof(capture->assemblies[index].assembly))
goto cleanup;
}
if (!write_settings_strings(snapshot_file, &scene.settings, capture->settings_strings))
goto cleanup;
for (size_t index = 0; index < capture->parts.size(); ++index) {
if (!write_part_capture(snapshot_file, &capture->parts[index]))
goto cleanup;
}
for (size_t index = 0; index < capture->assemblies.size(); ++index) {
struct snapshot_assembly_capture *assembly = &capture->assemblies[index];
assembly->assembly.member_count = assembly->members.size();
if (!write_text(snapshot_file, assembly->model_name, &assembly->assembly.model_name) ||
!write_text(snapshot_file, assembly->model_version, &assembly->assembly.model_version) ||
!write_range(snapshot_file, assembly->members.data(),
assembly->members.size() * sizeof(assembly->members[0]),
&assembly->assembly.members))
goto cleanup;
}
if (!finish_snapshot(snapshot_file, &header) ||
_fseeki64(snapshot_file, 0, SEEK_SET) != 0 ||
fwrite(&header, 1, sizeof(header), snapshot_file) != sizeof(header) ||
fwrite(&scene, 1, sizeof(scene), snapshot_file) != sizeof(scene))
goto cleanup;
if (scene.part_count > 0 &&
_fseeki64(snapshot_file, (__int64)scene.parts.offset, SEEK_SET) != 0)
goto cleanup;
for (size_t index = 0; index < capture->parts.size(); ++index) {
if (fwrite(&capture->parts[index].part, 1, sizeof(capture->parts[index].part), snapshot_file) !=
sizeof(capture->parts[index].part))
goto cleanup;
}
if (scene.assembly_count > 0 &&
_fseeki64(snapshot_file, (__int64)scene.assemblies.offset, SEEK_SET) != 0)
goto cleanup;
for (size_t index = 0; index < capture->assemblies.size(); ++index) {
if (fwrite(&capture->assemblies[index].assembly, 1,
sizeof(capture->assemblies[index].assembly), snapshot_file) !=
sizeof(capture->assemblies[index].assembly))
goto cleanup;
}
result = CREO_BRL_SNAPSHOT_CAPTURE_SUCCESS;
cleanup:
fclose(snapshot_file);
return result;
}
extern "C" int
creo_brl_frontend_capture_snapshot(const char *snapshot_path)
{
struct creo_brl_snapshot_settings settings = {};
struct snapshot_settings_strings settings_strings;
ProMdl model = NULL;
ProMdlType model_type;
if (!snapshot_path || !snapshot_path[0])
return CREO_BRL_SNAPSHOT_CAPTURE_INVALID_REQUEST;
if (!capture_settings(&settings, &settings_strings))
return CREO_BRL_SNAPSHOT_CAPTURE_DIALOG_FAILURE;
if (ProMdlCurrentGet(&model) != PRO_TK_NO_ERROR)
return CREO_BRL_SNAPSHOT_CAPTURE_NO_ACTIVE_MODEL;
if (ProMdlTypeGet(model, &model_type) != PRO_TK_NO_ERROR)
return CREO_BRL_SNAPSHOT_CAPTURE_MODEL_FAILURE;
if (model_type == PRO_MDL_PART) {
struct snapshot_part_capture capture;
const int result = capture_part_definition(model, &settings, &capture);
return result == CREO_BRL_SNAPSHOT_CAPTURE_SUCCESS ?
write_single_part_snapshot(snapshot_path, &settings, settings_strings, &capture) : result;
}
if (model_type == PRO_MDL_ASSEMBLY) {
struct snapshot_scene_capture capture = {};
uint32_t root_index = 0;
int result = CREO_BRL_SNAPSHOT_CAPTURE_MODEL_FAILURE;
capture.settings = settings;
capture.settings_strings = settings_strings;
result = capture_scene_assembly(model, &capture, &root_index);
return result == CREO_BRL_SNAPSHOT_CAPTURE_SUCCESS ?
write_scene_snapshot(snapshot_path, &capture,
CREO_BRL_SNAPSHOT_SCENE_NODE_ASSEMBLY, root_index) : result;
}
return CREO_BRL_SNAPSHOT_CAPTURE_UNSUPPORTED_MODEL;
}
+22
View File
@@ -0,0 +1,22 @@
/**
* S N A P S H O T _ W R I T E R . H
* BRL-CAD
*/
#ifndef CREO_SNAPSHOT_WRITER_H
#define CREO_SNAPSHOT_WRITER_H
enum creo_brl_snapshot_capture_result {
CREO_BRL_SNAPSHOT_CAPTURE_SUCCESS = 0,
CREO_BRL_SNAPSHOT_CAPTURE_INVALID_REQUEST = -1,
CREO_BRL_SNAPSHOT_CAPTURE_DIALOG_FAILURE = -2,
CREO_BRL_SNAPSHOT_CAPTURE_MODEL_FAILURE = -3,
CREO_BRL_SNAPSHOT_CAPTURE_WRITE_FAILURE = -4,
CREO_BRL_SNAPSHOT_CAPTURE_NO_ACTIVE_MODEL = -5,
CREO_BRL_SNAPSHOT_CAPTURE_UNSUPPORTED_MODEL = -6,
CREO_BRL_SNAPSHOT_CAPTURE_TESSELLATION_FAILURE = -7
};
extern "C" int creo_brl_frontend_capture_snapshot(const char *snapshot_path);
#endif /* CREO_SNAPSHOT_WRITER_H */
+949 -137
View File
File diff suppressed because it is too large Load Diff