diff --git a/src/external/Creo/assembly.cpp b/src/external/Creo/assembly.cpp index 5ab8d7709fa..cc4d878f433 100644 --- a/src/external/Creo/assembly.cpp +++ b/src/external/Creo/assembly.cpp @@ -1,4 +1,5 @@ -/* A S S E M B L Y . C P P +/* + * A S S E M B L Y . C P P * BRL-CAD * * Copyright (c) 2017-2021 United States Government as represented by @@ -17,24 +18,25 @@ * License along with this file; see the file named COPYING for more * information. */ -/** @file assembly.cpp - * +/** + * @file assembly.cpp */ #include "common.h" #include "creo-brl.h" #include -/* Assembly processing container */ +/** Assembly processing container */ struct assem_conv_info { - struct creo_conv_info *cinfo; /* global state */ + struct creo_conv_info *cinfo; /** global state */ ProMdl curr_parent; struct wmember *wcmb; }; -/* Callback function used only for find_empty_assemblies */ + +/** Callback function used only for find_empty_assemblies */ extern "C" ProError -assembly_check_empty( ProFeature *feat, ProError UNUSED(status), ProAppData app_data ) +assembly_check_empty(ProFeature *feat, ProError UNUSED(status), ProAppData app_data) { ProError lstatus; ProMdlType type; @@ -42,85 +44,93 @@ assembly_check_empty( ProFeature *feat, ProError UNUSED(status), ProAppData app_ struct adata *ada = (struct adata *)app_data; struct creo_conv_info *cinfo = ada->cinfo; int *has_shape = (int *)ada->data; - if ((lstatus = ProAsmcompMdlNameGet(feat, &type, wname)) != PRO_TK_NO_ERROR ) return lstatus; + if ((lstatus = ProAsmcompMdlNameGet(feat, &type, wname)) != PRO_TK_NO_ERROR) return lstatus; if (cinfo->empty->find(wname) == cinfo->empty->end()) (*has_shape) = 1; return PRO_TK_NO_ERROR; } -/* Run this only *after* output_parts - that is where empty "assembly" objects will - * be identified. Without knowing which parts are empty, we can't know if an - * assembly of parts is empty. */ + +/** + * Run this only *after* output_parts - that is where empty "assembly" + * objects will be identified. Without knowing which parts are empty, + * we can't know if an assembly of parts is empty. + */ extern "C" void find_empty_assemblies(struct creo_conv_info *cinfo) { int steady_state = 0; if (cinfo->empty->size() == 0) return; while (!steady_state) { - std::set::iterator d_it; - steady_state = 1; - struct adata *ada; - BU_GET(ada, struct adata); - ada->cinfo = cinfo; - for (d_it = cinfo->assems->begin(); d_it != cinfo->assems->end(); d_it++) { - /* for each assem, verify at least one child is non-empty. If all - * children are empty, add to empty set and unset steady_state. */ - int has_shape = 0; - ada->data = (void *)&has_shape; - ProMdl model; - if (ProMdlnameInit(*d_it, PRO_MDLFILE_ASSEMBLY, &model) == PRO_TK_NO_ERROR ) { - if (cinfo->empty->find(*d_it) == cinfo->empty->end()) { - ProSolidFeatVisit(ProMdlToPart(model), assembly_check_empty, (ProFeatureFilterAction)component_filter, (ProAppData)ada); - if (!has_shape) { - char ename[MAXPATHLEN]; - wchar_t *stable = stable_wchar(cinfo, *d_it); - ProWstringToString(ename, *d_it); - if (!stable) { - creo_log(cinfo, MSG_DEBUG, "%s - is empty assembly, but no stable version of name found???.\n", ename); - } else { - creo_log(cinfo, MSG_DEBUG, "all contents of assembly %s are empty, skipping\n", ename); - cinfo->empty->insert(stable); - steady_state = 0; - } - creo_log(cinfo, MSG_FAIL, "%s not converted.\n", ename); - } - } - } - } + std::set::iterator d_it; + steady_state = 1; + struct adata *ada; + BU_GET(ada, struct adata); + ada->cinfo = cinfo; + for (d_it = cinfo->assems->begin(); d_it != cinfo->assems->end(); d_it++) { + /** + * For each assem, verify at least one child is non-empty. + * If all children are empty, add to empty set and unset + * steady_state. + */ + int has_shape = 0; + ada->data = (void *)&has_shape; + ProMdl model; + if (ProMdlnameInit(*d_it, PRO_MDLFILE_ASSEMBLY, &model) == PRO_TK_NO_ERROR) { + if (cinfo->empty->find(*d_it) == cinfo->empty->end()) { + ProSolidFeatVisit(ProMdlToPart(model), assembly_check_empty, (ProFeatureFilterAction)component_filter, (ProAppData)ada); + if (!has_shape) { + char ename[MAXPATHLEN]; + wchar_t *stable = stable_wchar(cinfo, *d_it); + ProWstringToString(ename, *d_it); + if (!stable) { + creo_log(cinfo, MSG_DEBUG, "%s - is empty assembly, but no stable version of name found???.\n", ename); + } else { + creo_log(cinfo, MSG_DEBUG, "all contents of assembly %s are empty, skipping\n", ename); + cinfo->empty->insert(stable); + steady_state = 0; + } + creo_log(cinfo, MSG_FAIL, "%s not converted.\n", ename); + } + } + } + } } } -/* routine to check if xform is an identity */ +/** Routine to check if xform is an identity */ extern "C" int -is_non_identity( ProMatrix xform ) +is_non_identity(ProMatrix xform) { int i, j; - for ( i=0; i<4; i++ ) { - for ( j=0; j<4; j++ ) { - if ( i == j ) { - if ( !NEAR_EQUAL(xform[i][j], 1.0, SMALL_FASTF) ) - return 1; - } else { - if ( !NEAR_EQUAL(xform[i][j], 0.0, SMALL_FASTF) ) - return 1; - } - } + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + if (i == j) { + if (!NEAR_EQUAL(xform[i][j], 1.0, SMALL_FASTF)) + return 1; + } else { + if (!NEAR_EQUAL(xform[i][j], 0.0, SMALL_FASTF)) + return 1; + } + } } return 0; } -/* Get the transformation matrix to apply to a member (feat) of a comb. - * this call is creating a path from the assembly to this particular member - * (assembly/member) + +/** + * Get the transformation matrix to apply to a member (feat) of a + * comb this call is creating a path from the assembly to this + * particular member (assembly/member) */ extern "C" ProError assembly_entry_matrix(struct creo_conv_info *cinfo, ProMdl parent, ProFeature *feat, mat_t *mat) { if(!feat || !mat) return PRO_TK_GENERAL_ERROR; - /* Get strings in case we need to log */ + /** Get strings in case we need to log */ ProError status; ProMdlType type; wchar_t wpname[CREO_NAME_MAX]; @@ -132,46 +142,49 @@ assembly_entry_matrix(struct creo_conv_info *cinfo, ProMdl parent, ProFeature *f ProAsmcompMdlNameGet(feat, &type, wcname); (void)ProWstringToString(cname, wcname); - /*** Find the CREO matrix ***/ + /** Find the CREO matrix */ ProAsmcomppath comp_path; ProMatrix xform; ProIdTable id_table; id_table[0] = feat->id; - /* create the path */ - status = ProAsmcomppathInit((ProSolid)parent, id_table, 1, &comp_path ); - if ( status != PRO_TK_NO_ERROR ) { - creo_log(cinfo, MSG_DEBUG, "%s: failed to get path from %s to %s, aborting\n", pname, pname, cname); - return status; + /** Create the path */ + status = ProAsmcomppathInit((ProSolid)parent, id_table, 1, &comp_path); + if (status != PRO_TK_NO_ERROR) { + creo_log(cinfo, MSG_DEBUG, "%s: failed to get path from %s to %s, aborting\n", pname, pname, cname); + return status; } - /* accumulate the xform matrix along the path created above */ - status = ProAsmcomppathTrfGet( &comp_path, PRO_B_TRUE, xform ); - if ( status != PRO_TK_NO_ERROR ) { - creo_log(cinfo, MSG_DEBUG, "%s: failed to get transformation matrix %s/%s, aborting\n", pname, pname, cname); - return status; + /** Accumulate the xform matrix along the path created above */ + status = ProAsmcomppathTrfGet(&comp_path, PRO_B_TRUE, xform); + if (status != PRO_TK_NO_ERROR) { + creo_log(cinfo, MSG_DEBUG, "%s: failed to get transformation matrix %s/%s, aborting\n", pname, pname, cname); + return status; } - /* Write the matrix to BRL-CAD form. Note: apparently, one - * of the functions of these matricies in Creo is to correct - * the size of subcomponents using different units. */ + /** + * Write the matrix to BRL-CAD form. Note: apparently, one + * of the functions of these matricies in Creo is to correct + * the size of subcomponents using different units. + */ if (is_non_identity(xform)) { - struct bu_vls mstr = BU_VLS_INIT_ZERO; - for (int j=0; j<4; j++) { - for (int k=0; k<4; k++ ) { - if ( k == 3 && j < 3 ) { - bu_vls_printf(&mstr, " %.12e", xform[k][j] * cinfo->creo_to_brl_conv ); - } else { - bu_vls_printf(&mstr, " %.12e", xform[k][j] ); - } - } - } - bn_decode_mat((*mat), bu_vls_addr(&mstr)); - bu_vls_free(&mstr); - return PRO_TK_NO_ERROR; + struct bu_vls mstr = BU_VLS_INIT_ZERO; + for (int j = 0; j < 4; j++) { + for (int k = 0; k < 4; k++) { + if (k == 3 && j < 3) { + bu_vls_printf(&mstr, " %.12e", xform[k][j] * cinfo->creo_to_brl_conv); + } else { + bu_vls_printf(&mstr, " %.12e", xform[k][j]); + } + } + } + bn_decode_mat((*mat), bu_vls_addr(&mstr)); + bu_vls_free(&mstr); + return PRO_TK_NO_ERROR; } return PRO_TK_GENERAL_ERROR; } + extern "C" ProError assembly_write_entry(ProFeature *feat, ProError UNUSED(status), ProAppData app_data) { @@ -185,47 +198,53 @@ assembly_write_entry(ProFeature *feat, ProError UNUSED(status), ProAppData app_d mat_t xform; MAT_IDN(xform); - /* Get name of current member */ - if ((lstatus = ProAsmcompMdlNameGet(feat, &mtype, wname)) != PRO_TK_NO_ERROR ) return PRO_TK_NO_ERROR; + /** Get name of current member */ + if ((lstatus = ProAsmcompMdlNameGet(feat, &mtype, wname)) != PRO_TK_NO_ERROR) return PRO_TK_NO_ERROR; - /* Skip this member if the object it refers to is empty */ + /** Skip this member if the object it refers to is empty */ if (ainfo->cinfo->empty->find(wname) != ainfo->cinfo->empty->end()) return PRO_TK_NO_ERROR; - /* If this is a skeleton, skip */ + /** If this is a skeleton, skip */ if ((ProAsmcompMdlGet(feat, &model)) == PRO_TK_NO_ERROR) { - ProMdlIsSkeleton(model, &is_skel); - if (is_skel) return PRO_TK_NO_ERROR; + ProMdlIsSkeleton(model, &is_skel); + if (is_skel) return PRO_TK_NO_ERROR; } - /* get BRL-CAD name */ + /** Get BRL-CAD name */ switch (mtype) { - case PRO_MDL_PART: - entry_name = get_brlcad_name(ainfo->cinfo, wname, "r", N_REGION); - break; - case PRO_MDL_ASSEMBLY: - entry_name = get_brlcad_name(ainfo->cinfo, wname, NULL, N_ASSEM); - break; - default: - return PRO_TK_NO_ERROR; - break; + case PRO_MDL_PART: + entry_name = get_brlcad_name(ainfo->cinfo, wname, "r", N_REGION); + break; + case PRO_MDL_ASSEMBLY: + entry_name = get_brlcad_name(ainfo->cinfo, wname, NULL, N_ASSEM); + break; + default: + return PRO_TK_NO_ERROR; + break; } - /* In case the name routine failed for whatever reason, don't call mk_addmember - all we'll get - * is a crash. Just keep going. */ + /** + * In case the name routine failed for whatever reason, don't call + * mk_addmember - all we'll get is a crash. Just keep going. + */ if (!entry_name) return PRO_TK_NO_ERROR; - /* Get matrix relative to current parent (if any) and create the comb entry */ - if ((lstatus = assembly_entry_matrix(ainfo->cinfo, ainfo->curr_parent, feat, &xform)) == PRO_TK_NO_ERROR ) { - (void)mk_addmember(bu_vls_addr(entry_name), &(ainfo->wcmb->l), xform, WMOP_UNION); + /** + * Get matrix relative to current parent (if any) and create the + * comb entry + */ + if ((lstatus = assembly_entry_matrix(ainfo->cinfo, ainfo->curr_parent, feat, &xform)) == PRO_TK_NO_ERROR) { + (void)mk_addmember(bu_vls_addr(entry_name), &(ainfo->wcmb->l), xform, WMOP_UNION); } else { - (void)mk_addmember(bu_vls_addr(entry_name), &(ainfo->wcmb->l), NULL, WMOP_UNION); + (void)mk_addmember(bu_vls_addr(entry_name), &(ainfo->wcmb->l), NULL, WMOP_UNION); } return PRO_TK_NO_ERROR; } -/* Only run this *after* find_empty_assemblies has been run */ + +/** Only run this *after* find_empty_assemblies has been run */ extern "C" ProError output_assembly(struct creo_conv_info *cinfo, ProMdl model) { @@ -236,93 +255,104 @@ output_assembly(struct creo_conv_info *cinfo, ProMdl model) BU_GET(ainfo, struct assem_conv_info); ainfo->cinfo = cinfo; - /* Check for exploded assembly. TODO - this is causing a crash, can't enable??? */ + /** + * Check for exploded assembly. + * + * TODO: This is causing a crash, can't enable??? + * + */ //ProBoolean is_exploded = PRO_B_FALSE; //ProAssemblyIsExploded(*(ProAssembly *)model, &is_exploded); //if (is_exploded) ProAssemblyUnexplode(*(ProAssembly *)model); - /* We'll need to assemble the list of children */ + /** We'll need to assemble the list of children */ struct wmember wcomb; BU_LIST_INIT(&wcomb.l); - /* Initial comb setup */ + /** Initial comb setup */ char cname[CREO_NAME_MAX]; ProMdlMdlnameGet(model, wname); ProWstringToString(cname, wname); ainfo->curr_parent = model; ainfo->wcmb = &wcomb; - /* Add children */ + /** Add children */ ProSolidFeatVisit(ProMdlToPart(model), assembly_write_entry, (ProFeatureFilterAction)component_filter, (ProAppData)ainfo); creo_log(cinfo, MSG_DEBUG, "%s: All children of assembly visited.\n", cname); - /* Get BRL-CAD name */ + /** Get BRL-CAD name */ comb_name = get_brlcad_name(cinfo, wname, NULL, N_ASSEM); - /* Data sufficient - write the comb */ + /** Data sufficient - write the comb */ mk_lcomb(cinfo->wdbp, bu_vls_addr(comb_name), &wcomb, 0, NULL, NULL, NULL, 0); - /* Set attributes, if the CREO object has any of the ones the user listed as of interest */ + /** + * Set attributes, if the CREO object has any of the ones + * on the user-supplied list. + */ struct directory *dp = db_lookup(cinfo->wdbp->dbip, bu_vls_addr(comb_name), LOOKUP_QUIET); struct bu_attribute_value_set avs; db5_get_attributes(cinfo->wdbp->dbip, &avs, dp); - /* Write the object ID as an attribute */ + /** Write the object ID as an attribute */ obj_name = get_brlcad_name(cinfo, wname, NULL, N_CREO); bu_avs_add(&avs, "CREO_NAME", bu_vls_addr(obj_name)); ProWVerstamp cstamp; if (ProMdlVerstampGet(model, &cstamp) == PRO_TK_NO_ERROR) { - char *vstr; - if (ProVerstampStringGet(cstamp, &vstr) == PRO_TK_NO_ERROR) { - bu_avs_add(&avs, "CREO_VERSION_STAMP", vstr); - } - ProVerstampStringFree(&vstr); + char *vstr; + if (ProVerstampStringGet(cstamp, &vstr) == PRO_TK_NO_ERROR) { + bu_avs_add(&avs, "CREO_VERSION_STAMP", vstr); + } + ProVerstampStringFree(&vstr); } - /* If we have a user supplied list of attributes to save, do it */ + /** If we have a user-supplied list of attributes to save, do it */ if (cinfo->attrs->size() > 0) { - for (unsigned int i = 0; i < cinfo->attrs->size(); i++) { - char *attr_val = NULL; - const char *arg = cinfo->attrs->at(i); - creo_attribute_val(&attr_val, arg, model); - if (attr_val) { - bu_avs_add(&avs, arg, attr_val); - bu_free(attr_val, "value string"); - } - } + for (unsigned int i = 0; i < cinfo->attrs->size(); i++) { + char *attr_val = NULL; + const char *arg = cinfo->attrs->at(i); + creo_attribute_val(&attr_val, arg, model); + if (attr_val) { + bu_avs_add(&avs, arg, attr_val); + bu_free(attr_val, "value string"); + } + } } - /* SolidMass properties are handled separately in CREO, so deal with those as well... */ + /** + * Solid mass properties are handled separately in CREO, + * so deal with those as well... + */ ProMassProperty mass_prop; struct bu_vls mpval = BU_VLS_INIT_ZERO; if (ProSolidMassPropertyGet(ProMdlToSolid(model), NULL, &mass_prop) == PRO_TK_NO_ERROR) { - if (mass_prop.density > 0.0) { - bu_vls_sprintf(&mpval, "%g", mass_prop.density); - bu_avs_add(&avs, "density", bu_vls_addr(&mpval)); - } - if (mass_prop.mass > 0.0) { - bu_vls_sprintf(&mpval, "%g", mass_prop.mass); - bu_avs_add(&avs, "mass", bu_vls_addr(&mpval)); - } - - if (mass_prop.volume > 0.0) { - bu_vls_sprintf(&mpval, "%g", mass_prop.volume); - bu_avs_add(&avs, "volume", bu_vls_addr(&mpval)); - } + if (mass_prop.density > 0.0) { + bu_vls_sprintf(&mpval, "%g", mass_prop.density); + bu_avs_add(&avs, "density", bu_vls_addr(&mpval)); + } + if (mass_prop.mass > 0.0) { + bu_vls_sprintf(&mpval, "%g", mass_prop.mass); + bu_avs_add(&avs, "mass", bu_vls_addr(&mpval)); + } + + if (mass_prop.volume > 0.0) { + bu_vls_sprintf(&mpval, "%g", mass_prop.volume); + bu_avs_add(&avs, "volume", bu_vls_addr(&mpval)); + } } - /* standardize and write */ + /** Standardize and write */ db5_standardize_avs(&avs); db5_update_attributes(dp, &avs, cinfo->wdbp->dbip); creo_log(cinfo, MSG_DEBUG, "%s: assembly conversion done.\n", cname); - /* Free local container */ + /** Free local container */ BU_PUT(ainfo, struct assem_conv_info); return PRO_TK_NO_ERROR; } -/* +/** * Local Variables: * mode: C * tab-width: 8 diff --git a/src/external/Creo/csg.cpp b/src/external/Creo/csg.cpp index 19407e6e81d..e0c3151cfc9 100644 --- a/src/external/Creo/csg.cpp +++ b/src/external/Creo/csg.cpp @@ -1,4 +1,5 @@ -/* C S G . C P P +/** + * C S G . C P P * BRL-CAD * * Copyright (c) 2017-2021 United States Government as represented by @@ -17,16 +18,16 @@ * License along with this file; see the file named COPYING for more * information. */ -/** @file csg.cpp - * +/** + * @file csg.cpp */ #include "common.h" #include "creo-brl.h" -#define MIN_RADIUS 1.0e-7 /* BRL-CAD does not allow tgc's with zero radius */ +#define MIN_RADIUS 1.0e-7 /** BRL-CAD does not allow tgc's with zero radius */ -/* Information needed to replace holes with CSG */ +/** Information needed to replace holes with CSG */ struct hole_info { ProFeature *feat; double radius; @@ -35,16 +36,17 @@ struct hole_info { int add_cbore; int add_csink; int hole_depth_type; - double cb_depth; /* counter-bore depth */ - double cb_diam; /* counter-bore diam */ - double cs_diam; /* counter-sink diam */ - double cs_angle; /* counter-sink angle */ - double hole_diam; /* drilled hle diameter */ - double hole_depth; /* drilled hole depth */ - double drill_angle; /* drill tip angle */ - Pro3dPnt end1, end2; /* axis endpoints for holes */ + double cb_depth; /** Counter-bore depth */ + double cb_diam; /** Counter-bore diam */ + double cs_diam; /** Counter-sink diam */ + double cs_angle; /** Counter-sink angle */ + double hole_diam; /** Drilled hole diameter */ + double hole_depth; /** Drilled hole depth */ + double drill_angle; /** Drill tip angle */ + Pro3dPnt end1, end2; /** Axis end-points for holes */ }; + extern "C" ProError hole_elem_filter(ProElement UNUSED(elem_tree), ProElement UNUSED(elem), ProElempath UNUSED(elem_path), ProAppData UNUSED(data)) { @@ -64,54 +66,54 @@ hole_elem_visit(ProElement UNUSED(elem_tree), ProElement elem, ProElempath UNUSE if ((err = ProElementValuetypeGet(elem, &data_type)) != PRO_TK_NO_ERROR) return err; switch (data_type) { - case PRO_VALUE_TYPE_INT: /* integer data type */ + case PRO_VALUE_TYPE_INT: /** Integer data type */ int intval; if ((err = ProElementIntegerGet(elem, NULL, &intval)) != PRO_TK_NO_ERROR) return err; if ((err = ProElementIdGet(elem, &elemid)) != PRO_TK_NO_ERROR) return err; switch (elemid) { - case PRO_E_HLE_ADD_CBORE: /* add counterbore */ - hinfo->add_cbore = intval; - break; - case PRO_E_HLE_ADD_CSINK: /* add countersink */ - hinfo->add_csink = intval; - break; - case PRO_E_HLE_DEPTH: /* hole depth */ + case PRO_E_HLE_ADD_CBORE: /** Add counterbore */ + hinfo->add_cbore = intval; + break; + case PRO_E_HLE_ADD_CSINK: /** Add countersink */ + hinfo->add_csink = intval; + break; + case PRO_E_HLE_DEPTH: /** Hole depth */ hinfo->hole_depth_type = intval; - break; - case PRO_E_HLE_TYPE_NEW: /* hole type */ + break; + case PRO_E_HLE_TYPE_NEW: /** Hole type */ hinfo->hole_type = intval; - break; + break; } break; - case PRO_VALUE_TYPE_DOUBLE: /* double data type */ + case PRO_VALUE_TYPE_DOUBLE: /** Double data type */ double dblval; if ((err = ProElementDoubleGet(elem, NULL, &dblval)) != PRO_TK_NO_ERROR) return err; if ((err = ProElementIdGet(elem, &elemid)) != PRO_TK_NO_ERROR) return err; switch (elemid) { - case PRO_E_DIAMETER: /* hole diameter */ - hinfo->hole_diam = dblval; - break; - case PRO_E_HLE_CBOREDEPTH: /* counterbore depth */ - hinfo->cb_depth = dblval; - break; - case PRO_E_HLE_CBOREDIAM: /* counterbore diameter */ - hinfo->cb_diam = dblval; - break; - case PRO_E_HLE_CSINKANGLE: /* countersink angle (deg) */ - hinfo->cs_angle = dblval; - break; - case PRO_E_HLE_CSINKDIAM: /* countersink diameter */ - hinfo->cs_diam = dblval; - break; - case PRO_E_HLE_DRILLANGLE: /* drill tip angle (deg) */ - hinfo->drill_angle = dblval; - break; - case PRO_E_HLE_DRILLDEPTH: /* drill depth w/o tip */ - hinfo->hole_depth = dblval; - break; - case PRO_E_HLE_HOLEDIAM: /* hole diameter */ - hinfo->hole_diam = dblval; - break; + case PRO_E_DIAMETER: /** Hole diameter */ + hinfo->hole_diam = dblval; + break; + case PRO_E_HLE_CBOREDEPTH: /** Counterbore depth */ + hinfo->cb_depth = dblval; + break; + case PRO_E_HLE_CBOREDIAM: /** Counterbore diameter */ + hinfo->cb_diam = dblval; + break; + case PRO_E_HLE_CSINKANGLE: /** Countersink angle (deg) */ + hinfo->cs_angle = dblval; + break; + case PRO_E_HLE_CSINKDIAM: /** Countersink diameter */ + hinfo->cs_diam = dblval; + break; + case PRO_E_HLE_DRILLANGLE: /** Drill tip angle (deg) */ + hinfo->drill_angle = dblval; + break; + case PRO_E_HLE_DRILLDEPTH: /** Drill depth w/o tip */ + hinfo->hole_depth = dblval; + break; + case PRO_E_HLE_HOLEDIAM: /** Hole diameter */ + hinfo->hole_diam = dblval; + break; } break; } @@ -124,6 +126,7 @@ geomitem_filter(ProDimension *UNUSED(dim), ProAppData UNUSED(data)) { return PRO_TK_NO_ERROR; } + extern "C" ProError geomitem_visit(ProGeomitem *item, ProError UNUSED(status), ProAppData data) { @@ -138,6 +141,7 @@ geomitem_visit(ProGeomitem *item, ProError UNUSED(status), ProAppData data) return PRO_TK_NO_ERROR; } + extern "C" struct bu_vls * tgc_hole_name(struct creo_conv_info *cinfo, wchar_t *wname, const char *suffix) { @@ -151,26 +155,28 @@ tgc_hole_name(struct creo_conv_info *cinfo, wchar_t *wname, const char *suffix) cname = get_brlcad_name(cinfo, wname, NULL, N_CREO); bu_vls_sprintf(hname, "%s_hole_0.%s", bu_vls_addr(cname), suffix); while ((dp = 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_DEBUG, "\t trying hole name : %s\n", bu_vls_addr(hname)); - if (count == LONG_MAX) { - bu_vls_free(hname); - BU_PUT(hname, struct bu_vls); - ProWstringToString(pname, wname); - creo_log(cinfo, MSG_DEBUG, "%s: hole name generation FAILED.\n", pname); - return NULL; - } + (void)bu_vls_incr(hname, NULL, "0:0:0:0:-", NULL, NULL); + count++; + creo_log(cinfo, MSG_DEBUG, "\t trying hole name : %s\n", bu_vls_addr(hname)); + if (count == LONG_MAX) { + bu_vls_free(hname); + BU_PUT(hname, struct bu_vls); + ProWstringToString(pname, wname); + creo_log(cinfo, MSG_DEBUG, "%s: hole name generation FAILED.\n", pname); + return NULL; + } } return hname; } -/* Subtract_hole() - * routine to create TGC primitives to make holes + +/** + * Subtract_hole() + * routine to create TGC primitives to make holes * - * return value: - * 0 - do not delete this hole feature before tessellating - * 1 - delete this hole feature before tessellating + * return value: + * 0 - do not delete this hole feature before tessellating + * 1 - delete this hole feature before tessellating */ extern "C" int subtract_hole(struct part_conv_info *pinfo) @@ -185,7 +191,7 @@ subtract_hole(struct part_conv_info *pinfo) vect_t a, b, c, d, h; if (pinfo->cinfo->do_facets_only) { - return (pinfo->diameter < cinfo->min_hole_diameter) ? 1 : 0; + return (pinfo->diameter < cinfo->min_hole_diameter) ? 1 : 0; } struct hole_info *hinfo; @@ -194,146 +200,146 @@ subtract_hole(struct part_conv_info *pinfo) hinfo->radius = pinfo->radius; hinfo->diameter = pinfo->diameter; - /* Do a more detailed characterization of the hole elements */ - if ((ret=ProFeatureElemtreeExtract(hinfo->feat, NULL, PRO_FEAT_EXTRACT_NO_OPTS, &elem_tree )) == PRO_TK_NO_ERROR ) { - if ((ret=ProElemtreeElementVisit( elem_tree, elem_path, hole_elem_filter, hole_elem_visit, (ProAppData)hinfo)) != PRO_TK_NO_ERROR ) { - if ( ProElementFree( &elem_tree ) != PRO_TK_NO_ERROR ) {fprintf( stderr, "Error freeing element tree\n" );} - BU_PUT(hinfo, struct hole_info); - return ret; - } - ProElementFree(&elem_tree); + /** Do a more detailed characterization of the hole elements */ + if ((ret=ProFeatureElemtreeExtract(hinfo->feat, NULL, PRO_FEAT_EXTRACT_NO_OPTS, &elem_tree)) == PRO_TK_NO_ERROR) { + if ((ret=ProElemtreeElementVisit(elem_tree, elem_path, hole_elem_filter, hole_elem_visit, (ProAppData)hinfo)) != PRO_TK_NO_ERROR) { + if (ProElementFree(&elem_tree) != PRO_TK_NO_ERROR) {fprintf(stderr, "Error freeing element tree\n");} + BU_PUT(hinfo, struct hole_info); + return ret; + } + ProElementFree(&elem_tree); } - /* need more info to recreate holes */ + /** Need more info to recreate holes */ if ((ret=ProFeatureGeomitemVisit(pinfo->feat, PRO_AXIS, geomitem_visit, geomitem_filter, (ProAppData)pinfo)) != PRO_TK_NO_ERROR) return ret; - /* Will need parent object name for naming */ + /** Will need parent object name for naming */ ProMdlMdlnameGet(pinfo->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) 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 ); - hname = tgc_hole_name(cinfo, wname, "s"); - mk_tgc(cinfo->wdbp, bu_vls_addr(hname), hinfo->end2, h, a, b, a, b); - if ((dp = db_lookup(cinfo->wdbp->dbip, bu_vls_addr(hname), LOOKUP_QUIET)) != RT_DIR_NULL) pinfo->subtractions->push_back(dp); - bu_vls_free(hname); - BU_PUT(hname, struct bu_vls); - } else if ( hinfo->hole_type == PRO_HLE_NEW_TYPE_STANDARD ) { - /* drilled hole with possible countersink and counterbore */ - point_t start; - vect_t dir; - double cb_radius; - double accum_depth=0.0; - double hole_radius=hinfo->hole_diam / 2.0; - - if (hinfo->hole_diam < cinfo->min_hole_diameter) return 1; - - VSUB2( dir, hinfo->end1, hinfo->end2 ); - VUNITIZE( dir ); - - VMOVE( start, hinfo->end2 ); - VSCALE( start, start, cinfo->creo_to_brl_conv ); - - 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; - VSCALE( a, a, cb_radius ); - VSCALE( b, b, cb_radius ); - VSCALE( h, dir, hinfo->cb_depth * cinfo->creo_to_brl_conv ); - 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) pinfo->subtractions->push_back(dp); - bu_vls_free(hname); - BU_PUT(hname, struct bu_vls); - - VADD2( start, start, h ); - accum_depth += hinfo->cb_depth; - hinfo->cb_diam = 0.0; - hinfo->cb_depth = 0.0; - } - if ( hinfo->add_csink == PRO_HLE_ADD_CSINK ) { - double cs_depth; - double cs_radius = hinfo->cs_diam / 2.0; - cs_depth = (hinfo->cs_diam - hinfo->hole_diam) / (2.0 * tan(hinfo->cs_angle * M_PI / 360.0 )); - bn_vec_ortho( a, dir ); - VCROSS( b, a, dir ); - 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 ); - 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) pinfo->subtractions->push_back(dp); - bu_vls_free(hname); - BU_PUT(hname, struct bu_vls); - - VADD2( start, start, h ); - accum_depth += cs_depth; - hinfo->cs_diam = 0.0; - hinfo->cs_angle = 0.0; - } - bn_vec_ortho( a, dir ); - VCROSS( b, a, dir ); - 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 ); - 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) pinfo->subtractions->push_back(dp); - bu_vls_free(hname); - BU_PUT(hname, struct bu_vls); - - VADD2( start, start, h ); - hinfo->hole_diam = 0.0; - hinfo->hole_depth = 0.0; - - if ( hinfo->hole_depth_type == PRO_HLE_STD_VAR_DEPTH ) { - double tip_depth; - bn_vec_ortho( a, dir ); - VCROSS( b, a, dir ); - VUNITIZE( b ); - 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( c, c, MIN_RADIUS ); - VSCALE( d, d, MIN_RADIUS ); - 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) pinfo->subtractions->push_back(dp); - bu_vls_free(hname); - BU_PUT(hname, struct bu_vls); - - hinfo->drill_angle = 0.0; - } + /** 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) 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); + hname = tgc_hole_name(cinfo, wname, "s"); + mk_tgc(cinfo->wdbp, bu_vls_addr(hname), hinfo->end2, h, a, b, a, b); + if ((dp = db_lookup(cinfo->wdbp->dbip, bu_vls_addr(hname), LOOKUP_QUIET)) != RT_DIR_NULL) pinfo->subtractions->push_back(dp); + bu_vls_free(hname); + BU_PUT(hname, struct bu_vls); + } else if (hinfo->hole_type == PRO_HLE_NEW_TYPE_STANDARD) { + /** Drilled hole with possible countersink and counterbore */ + point_t start; + vect_t dir; + double cb_radius; + double accum_depth=0.0; + double hole_radius=hinfo->hole_diam / 2.0; + + if (hinfo->hole_diam < cinfo->min_hole_diameter) return 1; + + VSUB2(dir, hinfo->end1, hinfo->end2); + VUNITIZE(dir); + + VMOVE(start, hinfo->end2); + VSCALE(start, start, cinfo->creo_to_brl_conv); + + 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; + VSCALE(a, a, cb_radius); + VSCALE(b, b, cb_radius); + VSCALE(h, dir, hinfo->cb_depth * cinfo->creo_to_brl_conv); + 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) pinfo->subtractions->push_back(dp); + bu_vls_free(hname); + BU_PUT(hname, struct bu_vls); + + VADD2(start, start, h); + accum_depth += hinfo->cb_depth; + hinfo->cb_diam = 0.0; + hinfo->cb_depth = 0.0; + } + if (hinfo->add_csink == PRO_HLE_ADD_CSINK) { + double cs_depth; + double cs_radius = hinfo->cs_diam / 2.0; + cs_depth = (hinfo->cs_diam - hinfo->hole_diam) / (2.0 * tan(hinfo->cs_angle * M_PI / 360.0 )); + bn_vec_ortho(a, dir); + VCROSS(b, a, dir); + 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); + 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) pinfo->subtractions->push_back(dp); + bu_vls_free(hname); + BU_PUT(hname, struct bu_vls); + + VADD2(start, start, h); + accum_depth += cs_depth; + hinfo->cs_diam = 0.0; + hinfo->cs_angle = 0.0; + } + bn_vec_ortho(a, dir); + VCROSS(b, a, dir); + 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); + 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) pinfo->subtractions->push_back(dp); + bu_vls_free(hname); + BU_PUT(hname, struct bu_vls); + + VADD2(start, start, h); + hinfo->hole_diam = 0.0; + hinfo->hole_depth = 0.0; + + if (hinfo->hole_depth_type == PRO_HLE_STD_VAR_DEPTH) { + double tip_depth; + bn_vec_ortho(a, dir); + VCROSS(b, a, dir); + VUNITIZE(b); + 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(c, c, MIN_RADIUS); + VSCALE(d, d, MIN_RADIUS); + 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) pinfo->subtractions->push_back(dp); + bu_vls_free(hname); + BU_PUT(hname, struct bu_vls); + + hinfo->drill_angle = 0.0; + } } else { - char pname[CREO_NAME_MAX]; - ProWstringToString(pname, wname); - creo_log(cinfo, MSG_DEBUG, "%s: unrecognized hole type\n", pname); - BU_PUT(hinfo, struct hole_info); - return 0; + char pname[CREO_NAME_MAX]; + ProWstringToString(pname, wname); + creo_log(cinfo, MSG_DEBUG, "%s: unrecognized hole type\n", pname); + BU_PUT(hinfo, struct hole_info); + return 0; } BU_PUT(hinfo, struct hole_info); diff --git a/src/external/Creo/main.cpp b/src/external/Creo/main.cpp index 6c0eb726dad..72c3d04c33a 100644 --- a/src/external/Creo/main.cpp +++ b/src/external/Creo/main.cpp @@ -1,4 +1,5 @@ -/* M A I N . C P P +/** + * M A I N . C P P * BRL-CAD * * Copyright (c) 2017-2021 United States Government as represented by @@ -17,48 +18,49 @@ * License along with this file; see the file named COPYING for more * information. */ -/** @file main.cpp - * +/** + * @file main.cpp */ #include "common.h" #include #include "creo-brl.h" + extern "C" void creo_conv_info_init(struct creo_conv_info *cinfo) { - /* Output file */ + /** Output file */ BU_GET(cinfo->output_file, struct bu_vls); bu_vls_init(cinfo->output_file); - /* Region ID */ + /** Region ID */ cinfo->reg_id = 1000; - /* File settings */ + /** File settings */ cinfo->logger = (FILE *)NULL; cinfo->logger_type=LOGGER_TYPE_NONE; cinfo->curr_msg_type = MSG_DEBUG; - /* units - model */ - cinfo->creo_to_brl_conv = 25.4; /* inches to mm */ - cinfo->local_tol=0.0; - cinfo->local_tol_sq=0.0; - - /* facetization settings */ - cinfo->max_error=1.5; - cinfo->min_error=1.5; - cinfo->tol_dist=0.0005; - cinfo->max_angle_cntrl=0.5; - cinfo->min_angle_cntrl=0.5; - cinfo->max_to_min_steps = 1; - cinfo->error_increment=0.0; - cinfo->angle_increment=0.0; - - /* csg settings */ - cinfo->min_hole_diameter=0.0; - cinfo->min_chamfer_dim=0.0; - cinfo->min_round_radius=0.0; + /** Units - model */ + cinfo->creo_to_brl_conv = 25.4; /** inches to mm */ + cinfo->local_tol = 0.0; + cinfo->local_tol_sq = 0.0; + + /** Facetization settings */ + cinfo->max_error = 1.5; + cinfo->min_error = 1.5; + cinfo->tol_dist = 0.0005; + cinfo->max_angle_cntrl = 0.5; + cinfo->min_angle_cntrl = 0.5; + cinfo->max_to_min_steps = 1; + cinfo->error_increment = 0.0; + cinfo->angle_increment = 0.0; + + /** CSG settings */ + cinfo->min_hole_diameter = 0.0; + cinfo->min_chamfer_dim = 0.0; + cinfo->min_round_radius = 0.0; cinfo->parts = new std::set; cinfo->assems = new std::set; @@ -75,6 +77,7 @@ creo_conv_info_init(struct creo_conv_info *cinfo) } + extern "C" void creo_conv_info_free(struct creo_conv_info *cinfo) { @@ -84,164 +87,187 @@ creo_conv_info_free(struct creo_conv_info *cinfo) std::set::iterator d_it; for (d_it = cinfo->parts->begin(); d_it != cinfo->parts->end(); d_it++) { - bu_free(*d_it, "free wchar str copy"); + bu_free(*d_it, "free wchar str copy"); } for (d_it = cinfo->assems->begin(); d_it != cinfo->assems->end(); d_it++) { - bu_free(*d_it, "free wchar str copy"); + bu_free(*d_it, "free wchar str copy"); } std::set::iterator s_it; for (s_it = cinfo->brlcad_names->begin(); s_it != cinfo->brlcad_names->end(); s_it++) { - struct bu_vls *v = *s_it; - bu_vls_free(v); - BU_PUT(v, struct bu_vls); + struct bu_vls *v = *s_it; + bu_vls_free(v); + BU_PUT(v, struct bu_vls); } for (s_it = cinfo->creo_names->begin(); s_it != cinfo->creo_names->end(); s_it++) { - struct bu_vls *v = *s_it; - bu_vls_free(v); - BU_PUT(v, struct bu_vls); + struct bu_vls *v = *s_it; + bu_vls_free(v); + BU_PUT(v, struct bu_vls); } for (unsigned int i = 0; i < cinfo->model_parameters->size(); i++) { - char *str = cinfo->model_parameters->at(i); - bu_free(str, "free model param string"); + char *str = cinfo->model_parameters->at(i); + bu_free(str, "free model param string"); } for (unsigned int i = 0; i < cinfo->attrs->size(); i++) { - char *str = cinfo->attrs->at(i); - bu_free(str, "free attrs string"); + char *str = cinfo->attrs->at(i); + bu_free(str, "free attrs string"); } delete cinfo->parts; delete cinfo->assems; - delete cinfo->empty; /* entries in empty were freed in parts and assems */ + delete cinfo->empty; /** Entries in empty were freed in parts and assems */ delete cinfo->brlcad_names; - delete cinfo->region_name_map; /* entries in name_map were freed in brlcad_names */ - delete cinfo->assem_name_map; /* entries in name_map were freed in brlcad_names */ - delete cinfo->solid_name_map; /* entries in name_map were freed in brlcad_names */ + delete cinfo->region_name_map; /** Entries in name_map were freed in brlcad_names */ + delete cinfo->assem_name_map; /** Entries in name_map were freed in brlcad_names */ + delete cinfo->solid_name_map; /** Entries in name_map were freed in brlcad_names */ delete cinfo->creo_name_map; delete cinfo->creo_names; if (cinfo->logger) fclose(cinfo->logger); wdb_close(cinfo->wdbp); - /* Finally, clear the container */ + /** Finally, clear the container */ //BU_PUT(cinfo, struct creo_conv_info); } + extern "C" void output_parts(struct creo_conv_info *cinfo) { std::set::iterator d_it; int cnt = 1; for (d_it = cinfo->parts->begin(); d_it != cinfo->parts->end(); d_it++) { - wchar_t wname[CREO_NAME_MAX]; - struct bu_vls *rname; - struct directory *rdp; - ProMdl m; - ProWVerstamp cstamp, gstamp; - if (ProMdlnameInit(*d_it, PRO_MDLFILE_PART, &m) != PRO_TK_NO_ERROR) return; - if (ProMdlNameGet(m, wname) != PRO_TK_NO_ERROR) return; - - /* If the part a) exists in the .g file already and b) has the same CREO - * version stamp as the part in the current CREO file, we don't need - * to re-export it to the .g file */ - rname = get_brlcad_name(cinfo, wname, "r", N_REGION); - rdp = db_lookup(cinfo->wdbp->dbip, bu_vls_addr(rname), LOOKUP_QUIET); - if (rdp != RT_DIR_NULL && ProMdlVerstampGet(m, &cstamp) == PRO_TK_NO_ERROR) { - const char *vs = NULL; - struct bu_attribute_value_set r_avs; - db5_get_attributes(cinfo->wdbp->dbip, &r_avs, rdp); - vs = bu_avs_get(&r_avs, "CREO_VERSION_STAMP"); - if (vs && ProStringVerstampGet((char *)vs, &gstamp) == PRO_TK_NO_ERROR && ProVerstampEqual(cstamp, gstamp) == PRO_B_TRUE) { - /* The .g object was created from the same version of the - * object that exists currently in the CREO file - skip */ - creo_log(cinfo, MSG_OK, "%s exists and is current - skipping\n", bu_vls_addr(rname)); - continue; - } else { - /* kill the existing object (region and child solid) - it's out of sync with CREO */ - struct directory **children = NULL; - struct rt_db_internal in; - if (rt_db_get_internal(&in, rdp, cinfo->wdbp->dbip, NULL, &rt_uniresource) >= 0) { - struct rt_comb_internal *comb = (struct rt_comb_internal *)in.idb_ptr; - int ccnt = db_comb_children(cinfo->wdbp->dbip, comb, &children, NULL, NULL); - if (ccnt > 0) { - for (int i = 0; i < ccnt; i++) { - db_delete(cinfo->wdbp->dbip, children[i]); - db_dirdelete(cinfo->wdbp->dbip, children[i]); - } - } - } - rt_db_free_internal(&in); - bu_free(children, "free child list"); - db_delete(cinfo->wdbp->dbip, rdp); - db_dirdelete(cinfo->wdbp->dbip, rdp); - db_update_nref(cinfo->wdbp->dbip, &rt_uniresource); - } - } - - /* All set - process the part */ - creo_log(cinfo, MSG_STATUS, "Processing part %d of %d", cnt++, cinfo->parts->size()); - if (output_part(cinfo, m) == PRO_TK_NOT_EXIST) cinfo->empty->insert(*d_it); + wchar_t wname[CREO_NAME_MAX]; + struct bu_vls *rname; + struct directory *rdp; + ProMdl m; + ProWVerstamp cstamp, gstamp; + if (ProMdlnameInit(*d_it, PRO_MDLFILE_PART, &m) != PRO_TK_NO_ERROR) return; + if (ProMdlNameGet(m, wname) != PRO_TK_NO_ERROR) return; + + /** + * If the part: + * a) exists in the .g file already and... + * b) has the same CREO version stamp as the part in the current + * CREO file + * then we don't need to re-export it to the .g file + */ + + rname = get_brlcad_name(cinfo, wname, "r", N_REGION); + rdp = db_lookup(cinfo->wdbp->dbip, bu_vls_addr(rname), LOOKUP_QUIET); + if (rdp != RT_DIR_NULL && ProMdlVerstampGet(m, &cstamp) == PRO_TK_NO_ERROR) { + const char *vs = NULL; + struct bu_attribute_value_set r_avs; + db5_get_attributes(cinfo->wdbp->dbip, &r_avs, rdp); + vs = bu_avs_get(&r_avs, "CREO_VERSION_STAMP"); + if (vs && ProStringVerstampGet((char *)vs, &gstamp) == PRO_TK_NO_ERROR && ProVerstampEqual(cstamp, gstamp) == PRO_B_TRUE) { + /** + * Skip the .g object if it was created from the same + * version of the object that exists currently in the + * CREO file + */ + creo_log(cinfo, MSG_OK, "%s exists and is current - skipping\n", bu_vls_addr(rname)); + continue; + } else { + /** + * Kill the existing object (region and child solid) + * it's out of sync with CREO + */ + struct directory **children = NULL; + struct rt_db_internal in; + if (rt_db_get_internal(&in, rdp, cinfo->wdbp->dbip, NULL, &rt_uniresource) >= 0) { + struct rt_comb_internal *comb = (struct rt_comb_internal *)in.idb_ptr; + int ccnt = db_comb_children(cinfo->wdbp->dbip, comb, &children, NULL, NULL); + if (ccnt > 0) { + for (int i = 0; i < ccnt; i++) { + db_delete(cinfo->wdbp->dbip, children[i]); + db_dirdelete(cinfo->wdbp->dbip, children[i]); + } + } + } + rt_db_free_internal(&in); + bu_free(children, "free child list"); + db_delete(cinfo->wdbp->dbip, rdp); + db_dirdelete(cinfo->wdbp->dbip, rdp); + db_update_nref(cinfo->wdbp->dbip, &rt_uniresource); + } + } + + /** All set - process the part */ + creo_log(cinfo, MSG_STATUS, "Processing part %d of %d", cnt++, cinfo->parts->size()); + if (output_part(cinfo, m) == PRO_TK_NOT_EXIST) cinfo->empty->insert(*d_it); } } + extern "C" void output_assems(struct creo_conv_info *cinfo) { std::set::iterator d_it; int cnt = 1; for (d_it = cinfo->assems->begin(); d_it != cinfo->assems->end(); d_it++) { - wchar_t wname[CREO_NAME_MAX]; - struct bu_vls *aname; - struct directory *adp; - ProMdl parent; - ProWVerstamp cstamp, gstamp; - ProMdlnameInit(*d_it, PRO_MDLFILE_ASSEMBLY, &parent); - if (ProMdlNameGet(parent, wname) != PRO_TK_NO_ERROR) continue; - - /* If the part a) exists in the .g file already and b) has the same CREO - * version stamp as the part in the current CREO file, we don't need - * to re-export it to the .g file */ - aname = get_brlcad_name(cinfo, wname, NULL, N_ASSEM); - adp = db_lookup(cinfo->wdbp->dbip, bu_vls_addr(aname), LOOKUP_QUIET); - if (adp != RT_DIR_NULL && ProMdlVerstampGet(parent, &cstamp) == PRO_TK_NO_ERROR) { - const char *vs = NULL; - struct bu_attribute_value_set a_avs; - db5_get_attributes(cinfo->wdbp->dbip, &a_avs, adp); - vs = bu_avs_get(&a_avs, "CREO_VERSION_STAMP"); - if (vs && ProStringVerstampGet((char *)vs, &gstamp) == PRO_TK_NO_ERROR && ProVerstampEqual(cstamp, gstamp) == PRO_B_TRUE) { - /* The .g object was created from the same version of the - * object that exists currently in the CREO file - skip */ - creo_log(cinfo, MSG_OK, "%s exists and is current - skipping\n", bu_vls_addr(aname)); - continue; - } else { - /* kill the existing object - it's out of sync with CREO */ - db_delete(cinfo->wdbp->dbip, adp); - db_dirdelete(cinfo->wdbp->dbip, adp); - db_update_nref(cinfo->wdbp->dbip, &rt_uniresource); - } - } - - /* Skip if we've determined this one is empty */ - if (cinfo->empty->find(wname) != cinfo->empty->end()) continue; - - /* All set - process the assembly */ - creo_log(cinfo, MSG_STATUS, "Processing assembly %d of %d", cnt++, cinfo->assems->size()); - output_assembly(cinfo, parent); + wchar_t wname[CREO_NAME_MAX]; + struct bu_vls *aname; + struct directory *adp; + ProMdl parent; + ProWVerstamp cstamp, gstamp; + ProMdlnameInit(*d_it, PRO_MDLFILE_ASSEMBLY, &parent); + if (ProMdlNameGet(parent, wname) != PRO_TK_NO_ERROR) continue; + + /** + * If the part: + * a) exists in the .g file already and... + * b) has the same CREO version stamp as the part in the current + * CREO file + * then we don't need to re-export it to the .g file + */ + aname = get_brlcad_name(cinfo, wname, NULL, N_ASSEM); + adp = db_lookup(cinfo->wdbp->dbip, bu_vls_addr(aname), LOOKUP_QUIET); + if (adp != RT_DIR_NULL && ProMdlVerstampGet(parent, &cstamp) == PRO_TK_NO_ERROR) { + const char *vs = NULL; + struct bu_attribute_value_set a_avs; + db5_get_attributes(cinfo->wdbp->dbip, &a_avs, adp); + vs = bu_avs_get(&a_avs, "CREO_VERSION_STAMP"); + if (vs && ProStringVerstampGet((char *)vs, &gstamp) == PRO_TK_NO_ERROR && ProVerstampEqual(cstamp, gstamp) == PRO_B_TRUE) { + /** + * Skip the .g object if it was created from the same + * version of the object that exists currently in the + * CREO file + */ + creo_log(cinfo, MSG_OK, "%s exists and is current - skipping\n", bu_vls_addr(aname)); + continue; + } else { + /** Kill the existing object - it's out of sync with CREO */ + db_delete(cinfo->wdbp->dbip, adp); + db_dirdelete(cinfo->wdbp->dbip, adp); + db_update_nref(cinfo->wdbp->dbip, &rt_uniresource); + } + } + + /** Skip if we've determined this one is empty */ + if (cinfo->empty->find(wname) != cinfo->empty->end()) continue; + + /** All set - process the assembly */ + creo_log(cinfo, MSG_STATUS, "Processing assembly %d of %d", cnt++, cinfo->assems->size()); + output_assembly(cinfo, parent); } } -/* Logic that builds up the sets of assemblies and parts. Doing a feature - * visit for all top level objects will result in a recursive walk of the - * hierarchy that adds all active objects into one of the converter lists. +/** + * Build up the sets of assemblies and parts. Doing a feature + * visit for all top level objects will result in a recursive walk + * of the hierarchy that adds all active objects into one of the + * converter lists. + * + * The "app_data" pointer holds the creo_conv_info container. * - * The "app_data" pointer holds the creo_conv_info container. */ extern "C" ProError -objects_gather( ProFeature *feat, ProError UNUSED(status), ProAppData app_data ) +objects_gather(ProFeature *feat, ProError UNUSED(status), ProAppData app_data) { ProError loc_status; ProMdl model; @@ -252,101 +278,106 @@ objects_gather( ProFeature *feat, ProError UNUSED(status), ProAppData app_data ) wchar_t *wname_saved; struct creo_conv_info *cinfo = (struct creo_conv_info *)app_data; - /* Get feature name */ - if ((loc_status = ProAsmcompMdlNameGet(feat, &type, wname)) != PRO_TK_NO_ERROR ) { - creo_log(cinfo, MSG_FAIL, "%s: failure getting name of child\n", name); - return PRO_TK_NO_ERROR; + /** Get feature name */ + if ((loc_status = ProAsmcompMdlNameGet(feat, &type, wname)) != PRO_TK_NO_ERROR) { + creo_log(cinfo, MSG_FAIL, "%s: failure getting name of child\n", name); + return PRO_TK_NO_ERROR; } (void)ProWstringToString(name, wname); - /* get the model for this member */ + /** Get the model for this member */ if ((loc_status = ProAsmcompMdlGet(feat, &model)) != PRO_TK_NO_ERROR) { - creo_log(cinfo, MSG_FAIL, "%s: failure getting model\n", name); - return PRO_TK_NO_ERROR; + creo_log(cinfo, MSG_FAIL, "%s: failure getting model\n", name); + return PRO_TK_NO_ERROR; } - /* get its type (part or assembly are the only ones that should make it here) */ + /** Get its type (only a part or assembly should make it here) */ if ((loc_status = ProMdlTypeGet(model, &type)) != PRO_TK_NO_ERROR) { - creo_log(cinfo, MSG_FAIL, "%s: failure getting type\n", name); - return PRO_TK_NO_ERROR; + creo_log(cinfo, MSG_FAIL, "%s: failure getting type\n", name); + return PRO_TK_NO_ERROR; } - /* If this is a skeleton, we're done */ + /** If this is a skeleton, we're done */ ProMdlIsSkeleton(model, &is_skel); if (is_skel) { - creo_log(cinfo, MSG_FAIL, "%s: is skeleton, skipping\n", name); - return PRO_TK_NO_ERROR; - } - - /* log this member */ - switch ( type ) { - case PRO_MDL_ASSEMBLY: - if (cinfo->assems->find(wname) == cinfo->assems->end()) { - wname_saved = (wchar_t *)bu_calloc(wcslen(wname)+1, sizeof(wchar_t), "CREO name"); - wcsncpy(wname_saved, wname, wcslen(wname)+1); - cinfo->assems->insert(wname_saved); - creo_log(cinfo, MSG_DEBUG, "walking into %s\n", name); - ProSolidFeatVisit(ProMdlToPart(model), objects_gather, (ProFeatureFilterAction)component_filter, app_data); - } - break; - case PRO_MDL_PART: - if (cinfo->parts->find(wname) == cinfo->parts->end()) { - wname_saved = (wchar_t *)bu_calloc(wcslen(wname)+1, sizeof(wchar_t), "CREO name"); - wcsncpy(wname_saved, wname, wcslen(wname)+1); - cinfo->parts->insert(wname_saved); - } - break; - default: - creo_log(cinfo, MSG_DEBUG, "%s: is neither an assembly or a part, skipping\n", name); - return PRO_TK_NO_ERROR; - break; + creo_log(cinfo, MSG_FAIL, "%s: is skeleton, skipping\n", name); + return PRO_TK_NO_ERROR; + } + + /** Log this member */ + switch (type) { + case PRO_MDL_ASSEMBLY: + if (cinfo->assems->find(wname) == cinfo->assems->end()) { + wname_saved = (wchar_t *)bu_calloc(wcslen(wname)+1, sizeof(wchar_t), "CREO name"); + wcsncpy(wname_saved, wname, wcslen(wname)+1); + cinfo->assems->insert(wname_saved); + creo_log(cinfo, MSG_DEBUG, "walking into %s\n", name); + ProSolidFeatVisit(ProMdlToPart(model), objects_gather, (ProFeatureFilterAction)component_filter, app_data); + } + break; + case PRO_MDL_PART: + if (cinfo->parts->find(wname) == cinfo->parts->end()) { + wname_saved = (wchar_t *)bu_calloc(wcslen(wname)+1, sizeof(wchar_t), "CREO name"); + wcsncpy(wname_saved, wname, wcslen(wname)+1); + cinfo->parts->insert(wname_saved); + } + break; + default: + creo_log(cinfo, MSG_DEBUG, "%s: is neither an assembly or a part, skipping\n", name); + return PRO_TK_NO_ERROR; + break; } return PRO_TK_NO_ERROR; } -/* + +/** * Routine to output the top level object that is currently displayed in CREO. * This is the real beginning of the processing code - doit collects user - * settings and calls this function. */ + * settings and calls this function. + */ extern "C" void -output_top_level_object(struct creo_conv_info *cinfo, ProMdl model, ProMdlType type ) +output_top_level_object(struct creo_conv_info *cinfo, ProMdl model, ProMdlType type) { wchar_t wname[CREO_NAME_MAX]; char name[CREO_NAME_MAX]; wchar_t *wname_saved; struct directory *tdp = RT_DIR_NULL; - /* get object name */ - if (ProMdlNameGet( model, wname ) != PRO_TK_NO_ERROR ) return; + /** Get object name */ + if (ProMdlNameGet(model, wname) != PRO_TK_NO_ERROR) return; (void)ProWstringToString(name, wname); - /* save name */ + /** Save name */ wname_saved = (wchar_t *)bu_calloc(wcslen(wname)+1, sizeof(wchar_t), "CREO name"); wcsncpy(wname_saved, wname, wcslen(wname)+1); - /* There are two possibilities - either we have a hierarchy, in which case we - * need to walk it and collect the objects to process, or we have a single part - * which we can process directly. */ - if ( type == PRO_MDL_PART ) { - /* One part only */ - cinfo->parts->insert(wname_saved); - output_parts(cinfo); - } else if ( type == PRO_MDL_ASSEMBLY ) { - /* Walk the hierarchy and process all necessary assemblies and parts */ - cinfo->assems->insert(wname_saved); - ProSolidFeatVisit(ProMdlToPart(model), objects_gather, (ProFeatureFilterAction)component_filter, (ProAppData)cinfo); - output_parts(cinfo); - find_empty_assemblies(cinfo); - (void)ProWindowRefresh(PRO_VALUE_UNUSED); - output_assems(cinfo); + /** + * There are two possibilities - either we have a hierarchy, + * in which case we need to walk it and collect the objects + * to process, or we have a single part which we can process + * directly. + */ + if (type == PRO_MDL_PART) { + /** One part only */ + cinfo->parts->insert(wname_saved); + output_parts(cinfo); + } else if (type == PRO_MDL_ASSEMBLY) { + /** Walk the hierarchy and process all necessary assemblies and parts */ + cinfo->assems->insert(wname_saved); + ProSolidFeatVisit(ProMdlToPart(model), objects_gather, (ProFeatureFilterAction)component_filter, (ProAppData)cinfo); + output_parts(cinfo); + find_empty_assemblies(cinfo); + (void)ProWindowRefresh(PRO_VALUE_UNUSED); + output_assems(cinfo); } else { - creo_log(cinfo, MSG_OK, "Top level object %s is neither PART nor ASSEMBLY, skipping", name); - return; + creo_log(cinfo, MSG_OK, "Top level object %s is neither PART nor ASSEMBLY, skipping", name); + return; } - /* Make a final toplevel comb based on the file name to hold the orientation matrix */ + /** Make a final toplevel comb based on the file name to hold the orientation matrix */ struct bu_vls *comb_name; struct bu_vls top_name = BU_VLS_INIT_ZERO; struct wmember wcomb; @@ -356,23 +387,24 @@ output_top_level_object(struct creo_conv_info *cinfo, ProMdl model, ProMdlType t bn_decode_mat(m, "0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 1"); comb_name = get_brlcad_name(cinfo, wname, NULL, N_ASSEM); if ((dp = db_lookup(cinfo->wdbp->dbip, bu_vls_addr(comb_name), LOOKUP_QUIET)) == RT_DIR_NULL) { - comb_name = get_brlcad_name(cinfo, wname, NULL, N_REGION); + comb_name = get_brlcad_name(cinfo, wname, NULL, N_REGION); } (void)mk_addmember(bu_vls_addr(comb_name), &(wcomb.l), m, WMOP_UNION); - /* Guarantee we have a non-colliding top level name */ + /** Guarantee we have a non-colliding top level name */ bu_vls_sprintf(&top_name, "all.g"); tdp = db_lookup(cinfo->wdbp->dbip, bu_vls_addr(&top_name), LOOKUP_QUIET); - if (tdp != RT_DIR_NULL) {bu_vls_sprintf(&top_name, "all-1.g"); - long count = 1; - tdp = db_lookup(cinfo->wdbp->dbip, bu_vls_addr(&top_name), LOOKUP_QUIET); - while (tdp != RT_DIR_NULL) { - (void)bu_vls_incr(&top_name, NULL, "0:0:0:0:-", NULL, NULL); - if (count == LONG_MAX) { - creo_log(cinfo, MSG_FAIL, "%s: top level name gen failed\n", cinfo->output_file); - break; - } - } + if (tdp != RT_DIR_NULL) { + bu_vls_sprintf(&top_name, "all-1.g"); + long count = 1; + tdp = db_lookup(cinfo->wdbp->dbip, bu_vls_addr(&top_name), LOOKUP_QUIET); + while (tdp != RT_DIR_NULL) { + (void)bu_vls_incr(&top_name, NULL, "0:0:0:0:-", NULL, NULL); + if (count == LONG_MAX) { + creo_log(cinfo, MSG_FAIL, "%s: top level name gen failed\n", cinfo->output_file); + break; + } + } } if (tdp == RT_DIR_NULL) mk_lcomb(cinfo->wdbp, bu_vls_addr(&top_name), &wcomb, 0, NULL, NULL, NULL, 0); bu_vls_free(&top_name); @@ -380,7 +412,6 @@ output_top_level_object(struct creo_conv_info *cinfo, ProMdl model, ProMdlType t } - extern "C" void doit(char *UNUSED(dialog), char *UNUSED(compnent), ProAppData UNUSED(appdata)) { @@ -392,456 +423,446 @@ doit(char *UNUSED(dialog), char *UNUSED(compnent), ProAppData UNUSED(appdata)) int n_selected_names; char **selected_names; - /* This replaces the global variables used in the original Pro/E converter */ + /** This replaces the global variables used in the original Creo converter */ struct creo_conv_info *cinfo = new creo_conv_info; creo_conv_info_init(cinfo); - ProStringToWstring(tmp_line, "Not processing" ); - status = ProUILabelTextSet( "creo_brl", "curr_proc", tmp_line ); + ProStringToWstring(tmp_line, "Not processing"); + status = ProUILabelTextSet("creo_brl", "curr_proc", tmp_line); - /********************/ - /* Set up logging */ - /********************/ + /** Set up logging */ { - char log_file[MAXPATHLEN]; - char logger_type_str[MAXPATHLEN]; - - /* get the name of the log file */ - status = ProUIInputpanelValueGet( "creo_brl", "log_file", &tmp_str ); - if ( status != PRO_TK_NO_ERROR ) { - fprintf(stderr, "Failed to get log file name\n"); - creo_conv_info_free(cinfo); - ProUIDialogDestroy("creo_brl"); - return; - } - ProWstringToString(log_file, tmp_str); - ProWstringFree(tmp_str); - - /* Set logger type */ - status = ProUIRadiogroupSelectednamesGet( "creo_brl", "log_file_type_rg", &n_selected_names, &selected_names ); - if (status != PRO_TK_NO_ERROR) { - fprintf( stderr, "Failed to get log file type\n" ); - creo_conv_info_free(cinfo); - ProUIDialogDestroy("creo_brl"); - return; - } - sprintf(logger_type_str,"%s", selected_names[0]); - ProStringarrayFree(selected_names, n_selected_names); - if (BU_STR_EQUAL("Failure", logger_type_str)) - cinfo->logger_type = LOGGER_TYPE_FAILURE; - else if (BU_STR_EQUAL("Success", logger_type_str)) - cinfo->logger_type = LOGGER_TYPE_SUCCESS; - else if (BU_STR_EQUAL("Failure/Success", logger_type_str)) - cinfo->logger_type = LOGGER_TYPE_FAILURE_OR_SUCCESS; - else - cinfo->logger_type = LOGGER_TYPE_ALL; - - /* open log file, if a name was provided */ - if (strlen(log_file) > 0) { - if ((cinfo->logger=fopen(log_file, "wb")) == NULL) { - creo_log(cinfo, MSG_FAIL, "Cannot open log file"); - creo_conv_info_free(cinfo); - ProUIDialogDestroy("creo_brl"); - return; - } - } else { - cinfo->logger = (FILE *)NULL; - } - } - - /**************************/ - /* Set up the output file */ - /**************************/ + char log_file[MAXPATHLEN]; + char logger_type_str[MAXPATHLEN]; + + /** Get the name of the log file */ + status = ProUIInputpanelValueGet("creo_brl", "log_file", &tmp_str); + if (status != PRO_TK_NO_ERROR) { + fprintf(stderr, "Failed to get log file name\n"); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; + } + ProWstringToString(log_file, tmp_str); + ProWstringFree(tmp_str); + + /** Set logger type */ + status = ProUIRadiogroupSelectednamesGet("creo_brl", "log_file_type_rg", &n_selected_names, &selected_names); + if (status != PRO_TK_NO_ERROR) { + fprintf(stderr, "Failed to get log file type\n"); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; + } + sprintf(logger_type_str,"%s", selected_names[0]); + ProStringarrayFree(selected_names, n_selected_names); + if (BU_STR_EQUAL("Failure", logger_type_str)) + cinfo->logger_type = LOGGER_TYPE_FAILURE; + else if (BU_STR_EQUAL("Success", logger_type_str)) + cinfo->logger_type = LOGGER_TYPE_SUCCESS; + else if (BU_STR_EQUAL("Failure/Success", logger_type_str)) + cinfo->logger_type = LOGGER_TYPE_FAILURE_OR_SUCCESS; + else + cinfo->logger_type = LOGGER_TYPE_ALL; + + /** Open log file, if a name was provided */ + if (strlen(log_file) > 0) { + if ((cinfo->logger=fopen(log_file, "wb")) == NULL) { + creo_log(cinfo, MSG_FAIL, "Cannot open log file"); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; + } + } else { + cinfo->logger = (FILE *)NULL; + } + } + + /** Set up the output file */ { - /* Get string from dialog */ - char output_file[128]; - wchar_t *w_output_file; - status = ProUIInputpanelValueGet("creo_brl", "output_file", &w_output_file); - if ( status != PRO_TK_NO_ERROR ) { - creo_log(cinfo, MSG_FAIL, "Failed to get output file name\n"); - creo_conv_info_free(cinfo); - ProUIDialogDestroy( "creo_brl" ); - return; - } - ProWstringToString(output_file, w_output_file); - ProWstringFree(w_output_file); - - /* If there is a pre-existing file, open it - it may be we only have to - * update some items in it. */ - if (bu_file_exists(output_file, NULL)) { - if ((cinfo->dbip = db_open(output_file, DB_OPEN_READWRITE)) != DBI_NULL) { - cinfo->wdbp = wdb_dbopen(cinfo->dbip, RT_WDB_TYPE_DB_DISK); - creo_log(cinfo, MSG_OK, "Note: %s exists - opening to update.\n", output_file); - } else { - creo_log(cinfo, MSG_FAIL, "Cannot open existing file: \n", output_file); - return; - } - } else { - - /* open output file */ - if ((cinfo->dbip = db_create(output_file, 5) ) == DBI_NULL) { - creo_log(cinfo, MSG_FAIL, "Cannot open output file: %s.\n", output_file); - creo_conv_info_free(cinfo); - ProUIDialogDestroy( "creo_brl" ); - return; - } - cinfo->wdbp = wdb_dbopen(cinfo->dbip, RT_WDB_TYPE_DB_DISK); - } - - /* Store the filename for later use */ - bu_vls_sprintf(cinfo->output_file, "%s", output_file); - } - - /***********************************************************************************/ - /* Read a user supplied list of model parameters in which to look for naming info. */ - /***********************************************************************************/ + /** Get string from dialog */ + char output_file[128]; + wchar_t *w_output_file; + status = ProUIInputpanelValueGet("creo_brl", "output_file", &w_output_file); + if (status != PRO_TK_NO_ERROR) { + creo_log(cinfo, MSG_FAIL, "Failed to get output file name\n"); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; + } + ProWstringToString(output_file, w_output_file); + ProWstringFree(w_output_file); + + /** + * If there is a pre-existing file, open it - it may be we + * only have to update some items in it. + */ + if (bu_file_exists(output_file, NULL)) { + if ((cinfo->dbip = db_open(output_file, DB_OPEN_READWRITE)) != DBI_NULL) { + cinfo->wdbp = wdb_dbopen(cinfo->dbip, RT_WDB_TYPE_DB_DISK); + creo_log(cinfo, MSG_OK, "Note: %s exists - opening to update.\n", output_file); + } else { + creo_log(cinfo, MSG_FAIL, "Cannot open existing file: \n", output_file); + return; + } + } else { + /** Open output file */ + if ((cinfo->dbip = db_create(output_file, 5)) == DBI_NULL) { + creo_log(cinfo, MSG_FAIL, "Cannot open output file: %s.\n", output_file); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; + } + cinfo->wdbp = wdb_dbopen(cinfo->dbip, RT_WDB_TYPE_DB_DISK); + } + + /** Store the filename for later use */ + bu_vls_sprintf(cinfo->output_file, "%s", output_file); + } + + /** Read user supplied list of model parameters for naming info. */ { - /* Get string from dialog */ - char attr_rename[MAXPATHLEN]; - wchar_t *w_attr_rename; - status = ProUIInputpanelValueGet("creo_brl", "attr_rename", &w_attr_rename); - if ( status != PRO_TK_NO_ERROR ) { - creo_log(cinfo, MSG_FAIL, "Failed to get name of model parameter specification file.\n"); - creo_conv_info_free(cinfo); - ProUIDialogDestroy( "creo_brl" ); - return; - } - ProWstringToString(attr_rename, w_attr_rename); - ProWstringFree(w_attr_rename); - - if (strlen(attr_rename) > 0) { - std::string pfilestr(attr_rename); - std::istringstream ss(pfilestr); - std::string line; - while (std::getline(ss, line)) { - std::string pkey; - std::istringstream ls(line); - while (std::getline(ls, pkey, ',')) { - /* Scrub leading and trailing whitespace */ - size_t startpos = pkey.find_first_not_of(" \t\n\v\f\r"); - if (std::string::npos != startpos) { - pkey = pkey.substr(startpos); - } - size_t endpos = pkey.find_last_not_of(" \t\n\v\f\r"); - if (std::string::npos != endpos) { - pkey = pkey.substr(0 ,endpos+1); - } - if (pkey.length() > 0) { - creo_log(cinfo, MSG_DEBUG, "Found model parameter naming key: %s.\n", pkey.c_str()); - cinfo->model_parameters->push_back(bu_strdup(pkey.c_str())); - } - } - } - } - } - - /***********************************************************************************/ - /* Read a user supplied list of model attributes to convert over to the .g file. */ - /***********************************************************************************/ + /** Get string from dialog */ + char attr_rename[MAXPATHLEN]; + wchar_t *w_attr_rename; + status = ProUIInputpanelValueGet("creo_brl", "attr_rename", &w_attr_rename); + if (status != PRO_TK_NO_ERROR) { + creo_log(cinfo, MSG_FAIL, "Failed to get name of model parameter specification file.\n"); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; + } + ProWstringToString(attr_rename, w_attr_rename); + ProWstringFree(w_attr_rename); + + if (strlen(attr_rename) > 0) { + std::string pfilestr(attr_rename); + std::istringstream ss(pfilestr); + std::string line; + while (std::getline(ss, line)) { + std::string pkey; + std::istringstream ls(line); + while (std::getline(ls, pkey, ',')) { + /** Scrub leading and trailing whitespace */ + size_t startpos = pkey.find_first_not_of(" \t\n\v\f\r"); + if (std::string::npos != startpos) { + pkey = pkey.substr(startpos); + } + size_t endpos = pkey.find_last_not_of(" \t\n\v\f\r"); + if (std::string::npos != endpos) { + pkey = pkey.substr(0 ,endpos+1); + } + if (pkey.length() > 0) { + creo_log(cinfo, MSG_DEBUG, "Found model parameter naming key: %s.\n", pkey.c_str()); + cinfo->model_parameters->push_back(bu_strdup(pkey.c_str())); + } + } + } + } + } + + /** Read user-supplied list of model attributes for conversion */ { - /* Get string from dialog */ - char attr_save[MAXPATHLEN]; - wchar_t *w_attr_save; - status = ProUIInputpanelValueGet("creo_brl", "attr_save", &w_attr_save); - if ( status != PRO_TK_NO_ERROR ) { - creo_log(cinfo, MSG_FAIL, "Failed to get name of attribute list file.\n"); - creo_conv_info_free(cinfo); - ProUIDialogDestroy( "creo_brl" ); - return; - } - ProWstringToString(attr_save, w_attr_save); - ProWstringFree(w_attr_save); - - if (strlen(attr_save) > 0) { - /* Parse the file contents into a list of parameter keys */ - std::string afilestr(attr_save); - std::istringstream ss(afilestr); - std::string line; - while (std::getline(ss, line)) { - std::string pkey; - std::istringstream ls(line); - while (std::getline(ls, pkey, ',')) { - /* Scrub leading and trailing whitespace */ - size_t startpos = pkey.find_first_not_of(" \t\n\v\f\r"); - if (std::string::npos != startpos) { - pkey = pkey.substr(startpos); - } - size_t endpos = pkey.find_last_not_of(" \t\n\v\f\r"); - if (std::string::npos != endpos) { - pkey = pkey.substr(0 ,endpos+1); - } - if (pkey.length() > 0) { - creo_log(cinfo, MSG_DEBUG, "Found attribute key: %s.\n", pkey.c_str()); - cinfo->attrs->push_back(bu_strdup(pkey.c_str())); - } - } - } - } - } - - /* get starting ident */ + /** Get string from dialog */ + char attr_save[MAXPATHLEN]; + wchar_t *w_attr_save; + status = ProUIInputpanelValueGet("creo_brl", "attr_save", &w_attr_save); + if (status != PRO_TK_NO_ERROR) { + creo_log(cinfo, MSG_FAIL, "Failed to get name of attribute list file.\n"); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; + } + ProWstringToString(attr_save, w_attr_save); + ProWstringFree(w_attr_save); + + if (strlen(attr_save) > 0) { + /** Parse file contents into a list of parameter keys */ + std::string afilestr(attr_save); + std::istringstream ss(afilestr); + std::string line; + while (std::getline(ss, line)) { + std::string pkey; + std::istringstream ls(line); + while (std::getline(ls, pkey, ',')) { + /** Scrub leading and trailing whitespace */ + size_t startpos = pkey.find_first_not_of(" \t\n\v\f\r"); + if (std::string::npos != startpos) { + pkey = pkey.substr(startpos); + } + size_t endpos = pkey.find_last_not_of(" \t\n\v\f\r"); + if (std::string::npos != endpos) { + pkey = pkey.substr(0 ,endpos+1); + } + if (pkey.length() > 0) { + creo_log(cinfo, MSG_DEBUG, "Found attribute key: %s.\n", pkey.c_str()); + cinfo->attrs->push_back(bu_strdup(pkey.c_str())); + } + } + } + } + } + + /** Get starting ident */ if ((status = ProUIInputpanelValueGet("creo_brl", "starting_ident", &tmp_str)) != PRO_TK_NO_ERROR) { - creo_log(cinfo, MSG_FAIL, "Failed to get starting ident.\n"); - creo_conv_info_free(cinfo); - ProUIDialogDestroy( "creo_brl" ); - return; + creo_log(cinfo, MSG_FAIL, "Failed to get starting ident.\n"); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; } else { - cinfo->reg_id = wstr_to_long(cinfo, tmp_str); - V_MAX(cinfo->reg_id, 1); - ProWstringFree(tmp_str); + cinfo->reg_id = wstr_to_long(cinfo, tmp_str); + V_MAX(cinfo->reg_id, 1); + ProWstringFree(tmp_str); } - - /* get max error */ + /** Get max error */ if ((status = ProUIInputpanelValueGet("creo_brl", "max_error", &tmp_str)) != PRO_TK_NO_ERROR) { - creo_log(cinfo, MSG_FAIL, "Failed to get max tessellation error.\n"); - creo_conv_info_free(cinfo); - ProUIDialogDestroy( "creo_brl" ); - return; + creo_log(cinfo, MSG_FAIL, "Failed to get max tessellation error.\n"); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; } else { - cinfo->max_error = wstr_to_double(cinfo, tmp_str); - ProWstringFree(tmp_str); + cinfo->max_error = wstr_to_double(cinfo, tmp_str); + ProWstringFree(tmp_str); } - - /* get min error */ + /** Get min error */ if ((status = ProUIInputpanelValueGet("creo_brl", "min_error", &tmp_str)) != PRO_TK_NO_ERROR) { - creo_log(cinfo, MSG_FAIL, "Failed to get min tessellation error.\n"); - creo_conv_info_free(cinfo); - ProUIDialogDestroy( "creo_brl" ); - return; + creo_log(cinfo, MSG_FAIL, "Failed to get min tessellation error.\n"); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; } else { - cinfo->min_error = wstr_to_double(cinfo, tmp_str); - ProWstringFree(tmp_str); - V_MAX(cinfo->max_error, cinfo->min_error); + cinfo->min_error = wstr_to_double(cinfo, tmp_str); + ProWstringFree(tmp_str); + V_MAX(cinfo->max_error, cinfo->min_error); } - - /* get the max angle control */ + /** Get the max angle control */ if ((status = ProUIInputpanelValueGet("creo_brl", "max_angle_ctrl", &tmp_str)) != PRO_TK_NO_ERROR) { - creo_log(cinfo, MSG_FAIL, "Failed to get max angle control.\n"); - creo_conv_info_free(cinfo); - ProUIDialogDestroy( "creo_brl" ); - return; + creo_log(cinfo, MSG_FAIL, "Failed to get max angle control.\n"); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; } else { - cinfo->max_angle_cntrl = wstr_to_double(cinfo, tmp_str); - ProWstringFree(tmp_str); + cinfo->max_angle_cntrl = wstr_to_double(cinfo, tmp_str); + ProWstringFree(tmp_str); } - - /* get the min angle control */ + /** Get the min angle control */ if ((status = ProUIInputpanelValueGet("creo_brl", "min_angle_ctrl", &tmp_str)) != PRO_TK_NO_ERROR) { - creo_log(cinfo, MSG_FAIL, "Failed to get min angle control.\n"); - creo_conv_info_free(cinfo); - ProUIDialogDestroy( "creo_brl" ); - return; + creo_log(cinfo, MSG_FAIL, "Failed to get min angle control.\n"); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; } else { - cinfo->min_angle_cntrl = wstr_to_double(cinfo, tmp_str); - ProWstringFree(tmp_str); - V_MAX(cinfo->max_angle_cntrl, cinfo->min_angle_cntrl); + cinfo->min_angle_cntrl = wstr_to_double(cinfo, tmp_str); + ProWstringFree(tmp_str); + V_MAX(cinfo->max_angle_cntrl, cinfo->min_angle_cntrl); } - /* get the max to min steps */ + /** Get the max to min steps */ if ((status = ProUIInputpanelValueGet("creo_brl", "isteps", &tmp_str)) != PRO_TK_NO_ERROR) { - creo_log(cinfo, MSG_FAIL, "Failed to get max to min steps.\n"); - creo_conv_info_free(cinfo); - ProUIDialogDestroy( "creo_brl" ); - return; + creo_log(cinfo, MSG_FAIL, "Failed to get max to min steps.\n"); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; } else { - cinfo->max_to_min_steps = wstr_to_long(cinfo, tmp_str); - ProWstringFree(tmp_str); - if (cinfo->max_to_min_steps <= 0) { - cinfo->max_to_min_steps = 0; - } else { - cinfo->error_increment = (ZERO((cinfo->max_error - cinfo->min_error))) ? 0 : (cinfo->max_error - cinfo->min_error) / (double)cinfo->max_to_min_steps; - cinfo->angle_increment = (ZERO((cinfo->max_angle_cntrl - cinfo->min_angle_cntrl))) ? 0 : (cinfo->max_angle_cntrl - cinfo->min_angle_cntrl) / (double)cinfo->max_to_min_steps; - if (ZERO(cinfo->error_increment) && ZERO(cinfo->angle_increment)) cinfo->max_to_min_steps = 0; - } - } - - /* check if user wants to do any CSG */ + cinfo->max_to_min_steps = wstr_to_long(cinfo, tmp_str); + ProWstringFree(tmp_str); + if (cinfo->max_to_min_steps <= 0) { + cinfo->max_to_min_steps = 0; + } else { + cinfo->error_increment = (ZERO((cinfo->max_error - cinfo->min_error))) ? 0 : (cinfo->max_error - cinfo->min_error) / (double)cinfo->max_to_min_steps; + cinfo->angle_increment = (ZERO((cinfo->max_angle_cntrl - cinfo->min_angle_cntrl))) ? 0 : (cinfo->max_angle_cntrl - cinfo->min_angle_cntrl) / (double)cinfo->max_to_min_steps; + if (ZERO(cinfo->error_increment) && ZERO(cinfo->angle_increment)) cinfo->max_to_min_steps = 0; + } + } + + /** Check if user wants to do any CSG */ if ((status = ProUICheckbuttonGetState("creo_brl", "facets_only", &cinfo->do_facets_only)) != PRO_TK_NO_ERROR) { - creo_log(cinfo, MSG_FAIL, "Failed to get checkbutton setting (facetize only).\n"); - creo_conv_info_free(cinfo); - ProUIDialogDestroy( "creo_brl" ); - return; + creo_log(cinfo, MSG_FAIL, "Failed to get checkbutton setting (facetize only).\n"); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; } - /* check if user wants to eliminate small features */ - if ((status = ProUICheckbuttonGetState("creo_brl", "elim_small", &cinfo->do_elims)) != PRO_TK_NO_ERROR ) { - creo_log(cinfo, MSG_FAIL, "Failed to get checkbutton setting (eliminate small features).\n"); - creo_conv_info_free(cinfo); - ProUIDialogDestroy( "creo_brl" ); - return; + /** Check if user wants to eliminate small features */ + if ((status = ProUICheckbuttonGetState("creo_brl", "elim_small", &cinfo->do_elims)) != PRO_TK_NO_ERROR) { + creo_log(cinfo, MSG_FAIL, "Failed to get checkbutton setting (eliminate small features).\n"); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; } - /* check if user wants to test solidity */ - if ((status = ProUICheckbuttonGetState("creo_brl", "check_solidity", &cinfo->check_solidity)) != PRO_TK_NO_ERROR ) { - creo_log(cinfo, MSG_FAIL, "Failed to get checkbutton setting (check solidity).\n"); - creo_conv_info_free(cinfo); - ProUIDialogDestroy( "creo_brl" ); - return; + /** Check if user wants to test solidity */ + if ((status = ProUICheckbuttonGetState("creo_brl", "check_solidity", &cinfo->check_solidity)) != PRO_TK_NO_ERROR) { + creo_log(cinfo, MSG_FAIL, "Failed to get checkbutton setting (check solidity).\n"); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; } - /* check if user wants surface normals in the BOT's */ - if ((status = ProUICheckbuttonGetState("creo_brl", "get_normals", &cinfo->get_normals)) != PRO_TK_NO_ERROR ) { - creo_log(cinfo, MSG_FAIL, "Failed to get checkbutton setting (extract surface normals).\n"); - creo_conv_info_free(cinfo); - ProUIDialogDestroy( "creo_brl" ); - return; + /** Check if user wants surface normals in the BOT's */ + if ((status = ProUICheckbuttonGetState("creo_brl", "get_normals", &cinfo->get_normals)) != PRO_TK_NO_ERROR) { + creo_log(cinfo, MSG_FAIL, "Failed to get checkbutton setting (extract surface normals).\n"); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; } - /* check if user wants to test solidity */ - if ((status = ProUICheckbuttonGetState("creo_brl", "debug_bboxes", &cinfo->debug_bboxes)) != PRO_TK_NO_ERROR ) { - creo_log(cinfo, MSG_FAIL, "Failed to get checkbutton setting (debugging bboxes).\n"); - creo_conv_info_free(cinfo); - ProUIDialogDestroy( "creo_brl" ); - return; + /** Check for user selected log file type */ + if ((status = ProUICheckbuttonGetState("creo_brl", "debug_bboxes", &cinfo->debug_bboxes)) != PRO_TK_NO_ERROR) { + creo_log(cinfo, MSG_FAIL, "Failed to get checkbutton setting (debugging bboxes).\n"); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; } if (cinfo->do_elims) { - - /* get the minimum hole diameter */ - if ((status = ProUIInputpanelValueGet("creo_brl", "min_hole", &tmp_str)) != PRO_TK_NO_ERROR) { - creo_log(cinfo, MSG_FAIL, "Failed to get minimum hole diameter.\n"); - creo_conv_info_free(cinfo); - ProUIDialogDestroy( "creo_brl" ); - return; - } else { - cinfo->min_hole_diameter = wstr_to_double(cinfo, tmp_str); - V_MAX(cinfo->min_hole_diameter, 0.0); - ProWstringFree(tmp_str); - } - - /* get the minimum chamfer dimension */ - if ((status = ProUIInputpanelValueGet("creo_brl", "min_chamfer", &tmp_str)) != PRO_TK_NO_ERROR) { - creo_log(cinfo, MSG_FAIL, "Failed to get minimum chamfer diameter.\n"); - creo_conv_info_free(cinfo); - ProUIDialogDestroy( "creo_brl" ); - return; - } else { - cinfo->min_chamfer_dim = wstr_to_double(cinfo, tmp_str); - V_MAX(cinfo->min_chamfer_dim, 0.0); - ProWstringFree(tmp_str); - } - - /* get the minimum round radius */ - if ((status = ProUIInputpanelValueGet("creo_brl", "min_round", &tmp_str)) != PRO_TK_NO_ERROR) { - creo_log(cinfo, MSG_FAIL, "Failed to get minimum round radius.\n"); - creo_conv_info_free(cinfo); - ProUIDialogDestroy( "creo_brl" ); - return; - } else { - cinfo->min_round_radius = wstr_to_double(cinfo, tmp_str); - V_MAX(cinfo->min_round_radius, 0.0); - ProWstringFree(tmp_str); - } + /** Get the minimum hole diameter */ + if ((status = ProUIInputpanelValueGet("creo_brl", "min_hole", &tmp_str)) != PRO_TK_NO_ERROR) { + creo_log(cinfo, MSG_FAIL, "Failed to get minimum hole diameter.\n"); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; + } else { + cinfo->min_hole_diameter = wstr_to_double(cinfo, tmp_str); + V_MAX(cinfo->min_hole_diameter, 0.0); + ProWstringFree(tmp_str); + } + + /** Get the minimum chamfer dimension */ + if ((status = ProUIInputpanelValueGet("creo_brl", "min_chamfer", &tmp_str)) != PRO_TK_NO_ERROR) { + creo_log(cinfo, MSG_FAIL, "Failed to get minimum chamfer diameter.\n"); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; + } else { + cinfo->min_chamfer_dim = wstr_to_double(cinfo, tmp_str); + V_MAX(cinfo->min_chamfer_dim, 0.0); + ProWstringFree(tmp_str); + } + + /** Get the minimum round radius */ + if ((status = ProUIInputpanelValueGet("creo_brl", "min_round", &tmp_str)) != PRO_TK_NO_ERROR) { + creo_log(cinfo, MSG_FAIL, "Failed to get minimum round radius.\n"); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; + } else { + cinfo->min_round_radius = wstr_to_double(cinfo, tmp_str); + V_MAX(cinfo->min_round_radius, 0.0); + ProWstringFree(tmp_str); + } } else { - cinfo->min_hole_diameter = 0.0; - cinfo->min_round_radius = 0.0; - cinfo->min_chamfer_dim = 0.0; + cinfo->min_hole_diameter = 0.0; + cinfo->min_round_radius = 0.0; + cinfo->min_chamfer_dim = 0.0; } - /* get the currently displayed model in Pro/E */ - if ((status = ProMdlCurrentGet(&model)) == PRO_TK_BAD_CONTEXT ) { - creo_log(cinfo, MSG_FAIL, "No model is displayed!!\n"); - creo_conv_info_free(cinfo); - ProUIDialogDestroy( "creo_brl" ); - return; - } + /** Get currently displayed model in Creo */ + if ((status = ProMdlCurrentGet(&model)) == PRO_TK_BAD_CONTEXT) { + creo_log(cinfo, MSG_FAIL, "No model is displayed!!\n"); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; + } - /* get its type */ + /** Get model type */ if ((status = ProMdlTypeGet(model, &type)) == PRO_TK_BAD_INPUTS) { - creo_log(cinfo, MSG_FAIL, "Cannot get type of current model!!\n"); - creo_conv_info_free(cinfo); - ProUIDialogDestroy( "creo_brl" ); - return; + creo_log(cinfo, MSG_FAIL, "Cannot get type of current model!!\n"); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; } - /* can only do parts and assemblies, no drawings, etc. */ - if ( type != PRO_MDL_ASSEMBLY && type != PRO_MDL_PART ) { - creo_log(cinfo, MSG_FAIL, "Current model is not a solid object.\n"); - creo_conv_info_free(cinfo); - ProUIDialogDestroy( "creo_brl" ); - return; + /** Limit scope to parts and assemblies, no drawings, etc. */ + if (type != PRO_MDL_ASSEMBLY && type != PRO_MDL_PART) { + creo_log(cinfo, MSG_FAIL, "Current model is not a solid object.\n"); + creo_conv_info_free(cinfo); + ProUIDialogDestroy("creo_brl"); + return; } - /* TODO -verify this is working correctly */ + /** TODO - verify this is working correctly */ creo_model_units(&(cinfo->creo_to_brl_conv), model); - /* adjust tolerance for Pro/E units */ + /** Adjust tolerance for Creo units */ cinfo->local_tol = cinfo->tol_dist / cinfo->creo_to_brl_conv; cinfo->local_tol_sq = cinfo->local_tol * cinfo->local_tol; - /* output the top level object + /** + * Output the top-level object * this will recurse through the entire model */ - output_top_level_object(cinfo, model, type ); + output_top_level_object(cinfo, model, type); - /* let user know we are done */ - ProStringToWstring( tmp_line, "Conversion complete" ); - ProUILabelTextSet( "creo_brl", "curr_proc", tmp_line ); + /** Let user know we are done */ + ProStringToWstring(tmp_line, "Conversion complete"); + ProUILabelTextSet("creo_brl", "curr_proc", tmp_line); ProMessageClear(); if (cinfo->warn_feature_unsuppress) { - struct bu_vls errmsg = BU_VLS_INIT_ZERO; - bu_vls_sprintf(&errmsg, "During the conversion, one or more parts had features suppressed. After the conversion was complete, an\nattempt was made to unsuppress these same features.\nOne or more unsuppression operations failed, so some features are still\nsuppressed. Please exit CREO without saving any\nchanges so that this problem will not persist."); - PopupMsg("Warning - Restoration Failure", bu_vls_addr(&errmsg)); - bu_vls_free(&errmsg); + struct bu_vls errmsg = BU_VLS_INIT_ZERO; + bu_vls_sprintf(&errmsg, "During the conversion, one or more parts had features suppressed.\nAfter the conversion was complete, an attempt was made to unsuppress\nthese same features. One or more unsuppression operations failed, so\nsome features are still suppressed. Please exit CREO without saving\nany changes so that this problem will not persist."); + PopupMsg("Warning - Restoration Failure", bu_vls_addr(&errmsg)); + bu_vls_free(&errmsg); } creo_conv_info_free(cinfo); return; } - extern "C" void elim_small_activate(char *dialog_name, char *button_name, ProAppData UNUSED(data)) { ProBoolean state; - if (ProUICheckbuttonGetState( dialog_name, button_name, &state) != PRO_TK_NO_ERROR) { - fprintf( stderr, "checkbutton activate routine: failed to get state\n" ); - return; + if (ProUICheckbuttonGetState(dialog_name, button_name, &state) != PRO_TK_NO_ERROR) { + fprintf(stderr, "checkbutton activate routine: failed to get state\n"); + return; } if (state) { - if (ProUIInputpanelEditable(dialog_name, "min_hole") != PRO_TK_NO_ERROR) { - creo_log(NULL, MSG_STATUS, "Failed to activate \"minimum hole diameter\""); - return; - } - if (ProUIInputpanelEditable(dialog_name, "min_chamfer") != PRO_TK_NO_ERROR) { - creo_log(NULL, MSG_STATUS, "Failed to activate \"minimum chamfer dimension\""); - return; - } - if (ProUIInputpanelEditable(dialog_name, "min_round") != PRO_TK_NO_ERROR) { - creo_log(NULL, MSG_STATUS, "Failed to activate \"minimum round radius\""); - return; - } + if (ProUIInputpanelEditable(dialog_name, "min_hole") != PRO_TK_NO_ERROR) { + creo_log(NULL, MSG_STATUS, "Failed to activate \"minimum hole diameter\""); + return; + } + if (ProUIInputpanelEditable(dialog_name, "min_chamfer") != PRO_TK_NO_ERROR) { + creo_log(NULL, MSG_STATUS, "Failed to activate \"minimum chamfer dimension\""); + return; + } + if (ProUIInputpanelEditable(dialog_name, "min_round") != PRO_TK_NO_ERROR) { + creo_log(NULL, MSG_STATUS, "Failed to activate \"minimum round radius\""); + return; + } } else { - if (ProUIInputpanelReadOnly(dialog_name, "min_hole") != PRO_TK_NO_ERROR) { - creo_log(NULL, MSG_STATUS, "Failed to de-activate \"minimum hole diameter\""); - return; - } - if (ProUIInputpanelReadOnly(dialog_name, "min_chamfer") != PRO_TK_NO_ERROR) { - creo_log(NULL, MSG_STATUS, "Failed to de-activate \"minimum chamfer dimension\""); - return; - } - if (ProUIInputpanelReadOnly(dialog_name, "min_round") != PRO_TK_NO_ERROR) { - creo_log(NULL, MSG_STATUS, "Failed to de-activate \"minimum round radius\""); - return; - } + if (ProUIInputpanelReadOnly(dialog_name, "min_hole") != PRO_TK_NO_ERROR) { + creo_log(NULL, MSG_STATUS, "Failed to de-activate \"minimum hole diameter\""); + return; + } + if (ProUIInputpanelReadOnly(dialog_name, "min_chamfer") != PRO_TK_NO_ERROR) { + creo_log(NULL, MSG_STATUS, "Failed to de-activate \"minimum chamfer dimension\""); + return; + } + if (ProUIInputpanelReadOnly(dialog_name, "min_round") != PRO_TK_NO_ERROR) { + creo_log(NULL, MSG_STATUS, "Failed to de-activate \"minimum round radius\""); + return; + } } } + extern "C" void do_quit(char *UNUSED(dialog), char *UNUSED(compnent), ProAppData UNUSED(appdata)) { ProUIDialogDestroy("creo_brl"); } -/* driver routine for converting CREO to BRL-CAD */ + +/** Driver routine for converting CREO to BRL-CAD */ extern "C" int creo_brl(uiCmdCmdId UNUSED(command), uiCmdValue *UNUSED(p_value), void *UNUSED(p_push_cmd_data)) { @@ -851,92 +872,100 @@ creo_brl(uiCmdCmdId UNUSED(command), uiCmdValue *UNUSED(p_value), void *UNUSED(p creo_log(NULL, MSG_STATUS, "Launching creo_brl..."); - /* use UI dialog */ + /** Use UI dialog */ if (ProUIDialogCreate("creo_brl", "creo_brl") != PRO_TK_NO_ERROR) { - bu_vls_printf(&vls, "Failed to create dialog box for creo-brl\n"); - goto print_msg; + bu_vls_printf(&vls, "Failed to create dialog box for creo-brl\n"); + goto print_msg; } if (ProUICheckbuttonActivateActionSet("creo_brl", "elim_small", elim_small_activate, NULL) != PRO_TK_NO_ERROR) { - bu_vls_printf(&vls, "Failed to set action for \"eliminate small features\" checkbutton\n"); - goto print_msg; + bu_vls_printf(&vls, "Failed to set action for \"eliminate small features\" checkbutton\n"); + goto print_msg; } if (ProUIPushbuttonActivateActionSet("creo_brl", "doit", doit, NULL) != PRO_TK_NO_ERROR) { - bu_vls_printf(&vls, "Failed to set action for 'Go' button\n"); - destroy_dialog = 1; - goto print_msg; + bu_vls_printf(&vls, "Failed to set action for 'Go' button\n"); + destroy_dialog = 1; + goto print_msg; } if (ProUIPushbuttonActivateActionSet("creo_brl", "quit", do_quit, NULL) != PRO_TK_NO_ERROR) { - bu_vls_printf(&vls, "Failed to set action for 'Quit' button\n"); - destroy_dialog = 1; - goto print_msg; + bu_vls_printf(&vls, "Failed to set action for 'Quit' button\n"); + destroy_dialog = 1; + goto print_msg; } - /* File names may get longer than the default... */ + /** File names may get longer than the default... */ ProUIInputpanelMaxlenSet("creo_brl", "output_file", MAXPATHLEN - 1); ProUIInputpanelMaxlenSet("creo_brl", "log_file", MAXPATHLEN - 1); ProMdl model; if (ProMdlCurrentGet(&model) != PRO_TK_BAD_CONTEXT) { - wchar_t wname[CREO_NAME_MAX]; - if (ProMdlNameGet(model, wname) == PRO_TK_NO_ERROR) { - struct bu_vls groot = BU_VLS_INIT_ZERO; - struct bu_vls lroot = BU_VLS_INIT_ZERO; - char name[CREO_NAME_MAX]; - (void)ProWstringToString(name, wname); - /* Supply a sensible default for the .g file... */ - if (bu_path_component(&groot, name, BU_PATH_BASENAME_EXTLESS)) { - wchar_t wgout[CREO_NAME_MAX]; - bu_vls_printf(&groot, ".g"); - (void)ProStringToWstring(wgout, bu_vls_addr(&groot)); - ProUIInputpanelValueSet("creo_brl", "output_file", wgout); - bu_vls_free(&groot); - } - /* suggest a default log file... */ - if (bu_path_component(&lroot, name, BU_PATH_BASENAME_EXTLESS)) { - /* Supply a sensible default for the .g file... */ - wchar_t wgout[CREO_NAME_MAX]; - bu_vls_printf(&lroot, "-log.txt"); - (void)ProStringToWstring(wgout, bu_vls_addr(&lroot)); - ProUIInputpanelValueSet("creo_brl", "log_file", wgout); - bu_vls_free(&lroot); - } - } - } - - /* Rather than files, (or in addition to?) should probably allow users to input lists directly... to do so, need to increase char limit */ + wchar_t wname[CREO_NAME_MAX]; + if (ProMdlNameGet(model, wname) == PRO_TK_NO_ERROR) { + struct bu_vls groot = BU_VLS_INIT_ZERO; + struct bu_vls lroot = BU_VLS_INIT_ZERO; + char name[CREO_NAME_MAX]; + (void)ProWstringToString(name, wname); + /** Supply a sensible default for the .g file... */ + if (bu_path_component(&groot, name, BU_PATH_BASENAME_EXTLESS)) { + wchar_t wgout[CREO_NAME_MAX]; + bu_vls_printf(&groot, ".g"); + (void)ProStringToWstring(wgout, bu_vls_addr(&groot)); + ProUIInputpanelValueSet("creo_brl", "output_file", wgout); + bu_vls_free(&groot); + } + /** Suggest a default log file... */ + if (bu_path_component(&lroot, name, BU_PATH_BASENAME_EXTLESS)) { + /** Supply a sensible default for the .g file... */ + wchar_t wgout[CREO_NAME_MAX]; + bu_vls_printf(&lroot, "-log.txt"); + (void)ProStringToWstring(wgout, bu_vls_addr(&lroot)); + ProUIInputpanelValueSet("creo_brl", "log_file", wgout); + bu_vls_free(&lroot); + } + } + } + + /** + * Rather than files, (or in addition to?) should probably allow + * users to input lists directly... to do so, need to increase char + * limit + */ ProUIInputpanelMaxlenSet("creo_brl", "attr_rename", MAXPATHLEN - 1); ProUIInputpanelMaxlenSet("creo_brl", "attr_save", MAXPATHLEN - 1); if (ProUIDialogActivate("creo_brl", &ret_status) != PRO_TK_NO_ERROR) { - bu_vls_printf(&vls, "Error in creo-brl Dialog: dialog returned %d\n", ret_status); + bu_vls_printf(&vls, "Error in creo-brl Dialog: dialog returned %d\n", ret_status); } -print_msg: + print_msg: if (bu_vls_strlen(&vls) > 0) creo_log(NULL, MSG_FAIL, bu_vls_addr(&vls)); bu_vls_free(&vls); if (destroy_dialog) ProUIDialogDestroy("creo_brl"); return 0; } -/* this routine determines whether the "creo-brl" menu item in Pro/E + +/** + * This routine determines whether the "creo-brl" menu item in Creo * should be displayed as available or greyed out */ extern "C" uiCmdAccessState creo_brl_access(uiCmdAccessMode UNUSED(access_mode)) { - /* doing the correct checks appears to be unreliable */ + /** Doing the correct checks appears to be unreliable */ return ACCESS_AVAILABLE; } -/******************************************************************************** - * IMPORTANT - the names of the next two functions - user_initialize and - * user_terminate - are dictated by the CREO API. These are the hooks that tie - * the rest of the code into the CREO system. Both are *required* to be - * present, even if the user_terminate function doesn't do any actual work. - ********************************************************************************/ + +/* + * IMPORTANT - the names of the next two functions - user_initialize + * and user_terminate - are dictated by the CREO API. These are the + * hooks that tie the rest of the code into the CREO system. Both + * are *required* to be present, even if the user_terminate function + * doesn't do any actual work. + */ extern "C" int user_initialize() { @@ -944,36 +973,37 @@ extern "C" int user_initialize() int i; uiCmdCmdId cmd_id; - /* Pro/E says always check the size of w_char */ + /** Creo says always check the size of w_char */ status = ProWcharSizeVerify (sizeof (wchar_t), &i); - if ( status != PRO_TK_NO_ERROR || (i != sizeof (wchar_t)) ) { - creo_log(NULL, MSG_FAIL, "ERROR wchar_t Incorrect size (%d). Should be: %d", (int)sizeof(wchar_t), i ); - return -1; + if (status != PRO_TK_NO_ERROR || (i != sizeof (wchar_t))) { + creo_log(NULL, MSG_FAIL, "ERROR wchar_t Incorrect size (%d). Should be: %d", (int)sizeof(wchar_t), i); + return -1; } - /* add a command that calls our creo-brl routine */ - status = ProCmdActionAdd( "CREO-BRL", (uiCmdCmdActFn)creo_brl, uiProe2ndImmediate, creo_brl_access, PRO_B_FALSE, PRO_B_FALSE, &cmd_id ); - if ( status != PRO_TK_NO_ERROR ) { - creo_log(NULL, MSG_FAIL, "Failed to add creo-brl action" ); - return -1; + /** Add a command that calls our creo-brl routine */ + status = ProCmdActionAdd("CREO-BRL", (uiCmdCmdActFn)creo_brl, uiProe2ndImmediate, creo_brl_access, PRO_B_FALSE, PRO_B_FALSE, &cmd_id); + if (status != PRO_TK_NO_ERROR) { + creo_log(NULL, MSG_FAIL, "Failed to add creo-brl action"); + return -1; } - /* add a menu item that runs the new command */ + /** Add a menu item that runs the new command */ ProFileName msgfil = {'\0'}; ProStringToWstring(msgfil, CREO_BRL_MSG_FILE); - status = ProMenubarmenuPushbuttonAdd( "File", "CREO-BRL", "CREO-BRL", "CREO-BRL-HELP", "File.psh_exit", PRO_B_FALSE, cmd_id, msgfil ); - if ( status != PRO_TK_NO_ERROR ) { - creo_log(NULL, MSG_FAIL, "Failed to add creo-brl menu button" ); - return -1; + status = ProMenubarmenuPushbuttonAdd("File", "CREO-BRL", "CREO-BRL", "CREO-BRL-HELP", "File.psh_exit", PRO_B_FALSE, cmd_id, msgfil); + if (status != PRO_TK_NO_ERROR) { + creo_log(NULL, MSG_FAIL, "Failed to add creo-brl menu button"); + return -1; } - /* let user know we are here */ + /** Let user know we are here */ //PopupMsg("Plugin Successfully Loaded", "The CREO to BRL-CAD converter plugin Version 0.2 was successfully loaded."); return 0; } + extern "C" void user_terminate() { ProMessageClear(); diff --git a/src/external/Creo/part.cpp b/src/external/Creo/part.cpp index d633bb123a2..3e635b1c648 100644 --- a/src/external/Creo/part.cpp +++ b/src/external/Creo/part.cpp @@ -1,4 +1,5 @@ -/* P A R T . C P P +/** + * P A R T . C P P * BRL-CAD * * Copyright (c) 2017-2021 United States Government as represented by @@ -17,20 +18,23 @@ * License along with this file; see the file named COPYING for more * information. */ -/** @file part.cpp - * +/** + * @file part.cpp */ #include "common.h" #include "creo-brl.h" + extern "C" ProError generic_filter(ProDimension *UNUSED(dim), ProAppData UNUSED(data)) { return PRO_TK_NO_ERROR; } -/* routine to check for bad triangles - * only checks for triangles with duplicate vertices + +/** + * Routine to check for bad triangles, only checks for triangles with + * duplicate vertices */ extern "C" int bad_triangle(struct creo_conv_info *cinfo, int v1, int v2, int v3, struct bg_vert_tree *tree) @@ -42,24 +46,24 @@ bad_triangle(struct creo_conv_info *cinfo, int v1, int v2, int v3, struct bg_ve dist = 0; for (int i = 0; i < 3; i++) { - coord = tree->the_array[v1*3+i] - tree->the_array[v2*3+i]; - dist += coord * coord; + coord = tree->the_array[v1*3+i] - tree->the_array[v2*3+i]; + dist += coord * coord; } dist = sqrt(dist); if (dist < cinfo->local_tol) return 1; dist = 0; for (int i = 0; i < 3; i++) { - coord = tree->the_array[v2*3+i] - tree->the_array[v3*3+i]; - dist += coord * coord; + coord = tree->the_array[v2*3+i] - tree->the_array[v3*3+i]; + dist += coord * coord; } dist = sqrt(dist); if (dist < cinfo->local_tol) return 1; dist = 0; - for (int i=0; i<3; i++ ) { - coord = tree->the_array[v1*3+i] - tree->the_array[v3*3+i]; - dist += coord * coord; + for (int i = 0; i < 3; i++) { + coord = tree->the_array[v1*3+i] - tree->the_array[v3*3+i]; + dist += coord * coord; } dist = sqrt(dist); if (dist < cinfo->local_tol) return 1; @@ -67,85 +71,92 @@ bad_triangle(struct creo_conv_info *cinfo, int v1, int v2, int v3, struct bg_ve return 0; } -/* If we have a CREO modeling feature that adds material, it can impact - * the decision on which conversion methods are practical */ + +/** If we have a CREO modeling feature that adds material, it can + * impact the decision on which conversion methods are practical + */ extern "C" int -feat_adds_material( ProFeattype feat_type ) +feat_adds_material(ProFeattype feat_type) { - if ( feat_type >= PRO_FEAT_UDF_THREAD ) { - return 1; + if (feat_type >= PRO_FEAT_UDF_THREAD) { + return 1; } - switch ( feat_type ) { - case PRO_FEAT_SHAFT: - case PRO_FEAT_PROTRUSION: - case PRO_FEAT_NECK: - case PRO_FEAT_FLANGE: - case PRO_FEAT_RIB: - case PRO_FEAT_EAR: - case PRO_FEAT_DOME: - case PRO_FEAT_LOC_PUSH: - case PRO_FEAT_UDF: - case PRO_FEAT_DRAFT: - case PRO_FEAT_SHELL: - case PRO_FEAT_DOME2: - case PRO_FEAT_IMPORT: - case PRO_FEAT_MERGE: - case PRO_FEAT_MOLD: - case PRO_FEAT_OFFSET: - case PRO_FEAT_REPLACE_SURF: - case PRO_FEAT_PIPE: - return 1; - break; - default: - return 0; - break; + switch (feat_type) { + case PRO_FEAT_SHAFT: + case PRO_FEAT_PROTRUSION: + case PRO_FEAT_NECK: + case PRO_FEAT_FLANGE: + case PRO_FEAT_RIB: + case PRO_FEAT_EAR: + case PRO_FEAT_DOME: + case PRO_FEAT_LOC_PUSH: + case PRO_FEAT_UDF: + case PRO_FEAT_DRAFT: + case PRO_FEAT_SHELL: + case PRO_FEAT_DOME2: + case PRO_FEAT_IMPORT: + case PRO_FEAT_MERGE: + case PRO_FEAT_MOLD: + case PRO_FEAT_OFFSET: + case PRO_FEAT_REPLACE_SURF: + case PRO_FEAT_PIPE: + return 1; + break; + default: + return 0; + break; } return 0; } + extern "C" const char *feat_status_to_str(ProFeatStatus feat_stat) { static const char *feat_status[]={ - "PRO_FEAT_ACTIVE", - "PRO_FEAT_INACTIVE", - "PRO_FEAT_FAMTAB_SUPPRESSED", - "PRO_FEAT_SIMP_REP_SUPPRESSED", - "PRO_FEAT_PROG_SUPPRESSED", - "PRO_FEAT_SUPPRESSED", - "PRO_FEAT_UNREGENERATED" + "PRO_FEAT_ACTIVE", + "PRO_FEAT_INACTIVE", + "PRO_FEAT_FAMTAB_SUPPRESSED", + "PRO_FEAT_SIMP_REP_SUPPRESSED", + "PRO_FEAT_PROG_SUPPRESSED", + "PRO_FEAT_SUPPRESSED", + "PRO_FEAT_UNREGENERATED" }; return feat_status[feat_stat]; } -/* this routine filters out which features should be visited by the feature visit initiated in - * the output_part() routine. + +/** + * This routine filters out which features should be visited by the + * feature visit initiated in the output_part() routine. */ extern "C" ProError -feature_filter( ProFeature *feat, ProAppData data ) +feature_filter(ProFeature *feat, ProAppData data) { ProError ret; struct part_conv_info *pinfo = (struct part_conv_info *)data; if ((ret=ProFeatureTypeGet(feat, &pinfo->type)) != PRO_TK_NO_ERROR) return ret; - /* handle holes, chamfers, and rounds only */ + /** Handle holes, chamfers, and rounds only */ if (pinfo->type == PRO_FEAT_HOLE || pinfo->type == PRO_FEAT_CHAMFER || pinfo->type == PRO_FEAT_ROUND) { - return PRO_TK_NO_ERROR; + return PRO_TK_NO_ERROR; } - /* if we encounter a protrusion (or any feature that adds material) after a hole, - * we cannot convert previous holes to CSG */ + /** + * If we encounter a protrusion (or any feature that adds material) + * after a hole, we cannot convert previous holes to CSG + */ if (feat_adds_material(pinfo->type)) pinfo->csg_holes_supported = 0; - /* skip everything else */ + /** Skip everything else */ return PRO_TK_CONTINUE; } extern "C" ProError -check_dimension( ProDimension *dim, ProError UNUSED(status), ProAppData data ) +check_dimension(ProDimension *dim, ProError UNUSED(status), ProAppData data) { ProDimensiontype dim_type; ProError ret; @@ -155,29 +166,30 @@ check_dimension( ProDimension *dim, ProError UNUSED(status), ProAppData data ) if ((ret=ProDimensionTypeGet(dim, &dim_type)) != PRO_TK_NO_ERROR) return ret; switch (dim_type) { - case PRODIMTYPE_RADIUS: - if ((ret=ProDimensionValueGet(dim, &pinfo->radius)) != PRO_TK_NO_ERROR) return ret; - pinfo->diameter = 2.0 * pinfo->radius; - pinfo->got_diameter = 1; - break; - case PRODIMTYPE_DIAMETER: - if ((ret=ProDimensionValueGet(dim, &pinfo->diameter)) != PRO_TK_NO_ERROR) return ret; - pinfo->radius = pinfo->diameter / 2.0; - pinfo->got_diameter = 1; - break; - case PRODIMTYPE_LINEAR: - if ((ret=ProDimensionValueGet(dim, &tmp)) != PRO_TK_NO_ERROR) return ret; - if (pinfo->got_distance1) { - pinfo->distance2 = tmp; - } else { - pinfo->got_distance1 = 1; - pinfo->distance1 = tmp; - } - break; + case PRODIMTYPE_RADIUS: + if ((ret=ProDimensionValueGet(dim, &pinfo->radius)) != PRO_TK_NO_ERROR) return ret; + pinfo->diameter = 2.0 * pinfo->radius; + pinfo->got_diameter = 1; + break; + case PRODIMTYPE_DIAMETER: + if ((ret=ProDimensionValueGet(dim, &pinfo->diameter)) != PRO_TK_NO_ERROR) return ret; + pinfo->radius = pinfo->diameter / 2.0; + pinfo->got_diameter = 1; + break; + case PRODIMTYPE_LINEAR: + if ((ret=ProDimensionValueGet(dim, &tmp)) != PRO_TK_NO_ERROR) return ret; + if (pinfo->got_distance1) { + pinfo->distance2 = tmp; + } else { + pinfo->got_distance1 = 1; + pinfo->distance1 = tmp; + } + break; } return PRO_TK_NO_ERROR; } + extern "C" ProError do_feature_visit(ProFeature *feat, ProError UNUSED(status), ProAppData data) { @@ -196,35 +208,40 @@ do_feature_visit(ProFeature *feat, ProError UNUSED(status), ProAppData data) if (pinfo->type == PRO_FEAT_HOLE) { - /* If the hole can be suppressed, do that */ - if (pinfo->diameter < pinfo->cinfo->min_hole_diameter) { - pinfo->suppressed_features->push_back(feat->id); - return ret; - } + /** If the hole can be suppressed, do that */ + if (pinfo->diameter < pinfo->cinfo->min_hole_diameter) { + pinfo->suppressed_features->push_back(feat->id); + return ret; + } - /* If the hole is too large to suppress and we're not doing any CSG, we're done - it's up to the facetizer. */ - if (pinfo->cinfo->do_facets_only) return ret; + /** + * If the hole is too large to suppress and we're not doing any CSG, + * we're done - it's up to the facetizer. + */ + if (pinfo->cinfo->do_facets_only) return ret; - /* If we can consider CSG, look into hole replacement */ - if (subtract_hole(pinfo)) pinfo->suppressed_features->push_back(feat->id); + /** If we can consider CSG, look into hole replacement */ + if (subtract_hole(pinfo)) pinfo->suppressed_features->push_back(feat->id); - return ret; + return ret; } - /* With rounds, suppress any with radius below user specified value */ + /** With rounds, suppress any with radius below user specified value */ if (pinfo->type == PRO_FEAT_ROUND) { - if (pinfo->got_diameter && pinfo->radius < pinfo->cinfo->min_round_radius) pinfo->suppressed_features->push_back(feat->id); - return ret; + if (pinfo->got_diameter && pinfo->radius < pinfo->cinfo->min_round_radius) pinfo->suppressed_features->push_back(feat->id); + return ret; } - /* With chamfers, suppress any where both distances (if retrieved) or the - * single distance are below the user specified value */ + /** + * With chamfers, suppress any where both distances (if retrieved) + * or the single distance are below the user specified value + */ if (pinfo->type == PRO_FEAT_CHAMFER) { - if ( pinfo->got_distance1 && pinfo->distance1 < pinfo->cinfo->min_chamfer_dim && - pinfo->distance2 < pinfo->cinfo->min_chamfer_dim ) { - pinfo->suppressed_features->push_back(feat->id); - } - return ret; + if (pinfo->got_distance1 && pinfo->distance1 < pinfo->cinfo->min_chamfer_dim && + pinfo->distance2 < pinfo->cinfo->min_chamfer_dim) { + pinfo->suppressed_features->push_back(feat->id); + } + return ret; } return ret; @@ -242,34 +259,34 @@ unsuppress_features(struct part_conv_info *pinfo) ProMdlMdlnameGet(pinfo->model, wname); ProWstringToString(pname, wname); - for (unsigned int i=0; i < pinfo->suppressed_features->size(); i++) { - ProFeature feat; - ProFeatStatus feat_stat; - - if (ProFeatureInit(ProMdlToSolid(pinfo->model), pinfo->suppressed_features->at(i), &feat) != PRO_TK_NO_ERROR) continue; - if (ProFeatureStatusGet(&feat, &feat_stat) != PRO_TK_NO_ERROR) continue; - if (feat_stat != PRO_FEAT_SUPPRESSED ) continue; - - /* unsuppress this one */ - creo_log(pinfo->cinfo, MSG_STATUS, "%s: unsuppressing feature %d", pname, pinfo->suppressed_features->at(i)); - int status = ProFeatureResume(ProMdlToSolid(pinfo->model), &(pinfo->suppressed_features->at(i)), 1, resume_opts, 1); - - /* Tell the user what happened */ - switch (status) { - case PRO_TK_NO_ERROR: - creo_log(pinfo->cinfo, MSG_STATUS, "%s: feature %d unsuppressed", pname, pinfo->suppressed_features->at(i)); - break; - case PRO_TK_SUPP_PARENTS: - creo_log(pinfo->cinfo, MSG_DEBUG, "%s: suppressed parents for feature %d not found\n", pname, pinfo->suppressed_features->at(i) ); - break; - default: - creo_log(pinfo->cinfo, MSG_DEBUG, "%s: feature id %d unsuppression failed\n", pname, pinfo->suppressed_features->at(i) ); - break; - } + for (unsigned int i = 0; i < pinfo->suppressed_features->size(); i++) { + ProFeature feat; + ProFeatStatus feat_stat; + + if (ProFeatureInit(ProMdlToSolid(pinfo->model), pinfo->suppressed_features->at(i), &feat) != PRO_TK_NO_ERROR) continue; + if (ProFeatureStatusGet(&feat, &feat_stat) != PRO_TK_NO_ERROR) continue; + if (feat_stat != PRO_FEAT_SUPPRESSED) continue; + + /** Unsuppress this one */ + creo_log(pinfo->cinfo, MSG_STATUS, "%s: unsuppressing feature %d", pname, pinfo->suppressed_features->at(i)); + int status = ProFeatureResume(ProMdlToSolid(pinfo->model), &(pinfo->suppressed_features->at(i)), 1, resume_opts, 1); + + /** Tell the user what happened */ + switch (status) { + case PRO_TK_NO_ERROR: + creo_log(pinfo->cinfo, MSG_STATUS, "%s: feature %d unsuppressed", pname, pinfo->suppressed_features->at(i)); + break; + case PRO_TK_SUPP_PARENTS: + creo_log(pinfo->cinfo, MSG_DEBUG, "%s: suppressed parents for feature %d not found\n", pname, pinfo->suppressed_features->at(i)); + break; + default: + creo_log(pinfo->cinfo, MSG_DEBUG, "%s: feature id %d unsuppression failed\n", pname, pinfo->suppressed_features->at(i)); + break; + } } } -/* TODO - will probably need maps from CREO data items to ON data items here... */ +/** TODO - will probably need maps from CREO data items to ON data items here... */ struct brep_data { ON_Brep *brep; ProSurface s; @@ -286,31 +303,39 @@ edge_filter(ProEdge UNUSED(e), ProAppData UNUSED(app_data)) { return PRO_TK_NO_ERROR; } -// ProEdge appears to correspond to the ON_BrepEdge. + +/** ProEdge appears to correspond to the ON_BrepEdge. */ extern "C" ProError edge_process(ProEdge UNUSED(e), ProError UNUSED(status), ProAppData app_data) { int current_surf_id; struct brep_data *bdata = (struct brep_data *)app_data; ProSurface s = bdata->s; ProSurfaceIdGet(s, ¤t_surf_id); - //ON_BrepLoop &nl = bdata->brep->m_L[bdata->curr_loop_id]; - - // TODO - there appears to be no way to get at ProEdgedata from an - // existing edge??? If that's the case, and we're limited to - // the ProEdgeToNURBS() capability, then we may have to use the - // step-g routines for creating our own trimming curves (arrgh!) - //ProGeomitemdata *edata; - //ProEdgeDataGet(e, &edata); + /** + * + * //ON_BrepLoop &nl = bdata->brep->m_L[bdata->curr_loop_id]; + * + * TODO - there appears to be no way to get at ProEdgedata from an + * existing edge??? If that's the case, and we're limited to + * the ProEdgeToNURBS() capability, then we may have to use the + * step-g routines for creating our own trimming curves (arrgh!) + * + * //ProGeomitemdata *edata; + * //ProEdgeDataGet(e, &edata); + * + */ return PRO_TK_NO_ERROR; } + extern "C" ProError contour_filter(ProContour UNUSED(c), ProAppData UNUSED(app_data)) { return PRO_TK_NO_ERROR; } -// Contours appear to correspond to Loops in OpenNURBS. + +/** Contours appear to correspond to Loops in OpenNURBS. */ extern "C" ProError contour_process(ProContour c, ProError UNUSED(status), ProAppData app_data) { struct brep_data *bdata = (struct brep_data *)app_data; @@ -332,11 +357,13 @@ contour_process(ProContour c, ProError UNUSED(status), ProAppData app_data) { return PRO_TK_NO_ERROR; } + extern "C" ProError surface_filter(ProSurface UNUSED(s), ProAppData UNUSED(app_data)) { return PRO_TK_NO_ERROR; } + extern "C" ProError surface_process(ProSurface s, ProError UNUSED(status), ProAppData app_data) { int c_id; @@ -350,84 +377,84 @@ surface_process(ProSurface s, ProError UNUSED(status), ProAppData app_data) { ON_Brep *nbrep = bdata->brep; ProSurfaceIdGet(s, &c_id); if (bdata->cs_to_onf->find(c_id) == bdata->cs_to_onf->end()) { - int s_id; - ProSurfaceToNURBS(s, &ndata); - ProSurfacedataGet(ndata, &s_type, uvmin, uvmax, &s_orient, &s_shape, &s_id); - if (s_type == PRO_SRF_B_SPL) { - int degree[2]; - double *up_array = NULL; - double *vp_array = NULL; - double *w_array = NULL; - ProVector *cntl_pnts; - int ucnt, vcnt, ccnt; - if (ProBsplinesrfdataGet(&s_shape, degree, &up_array, &vp_array, &w_array, &cntl_pnts, &ucnt, &vcnt, &ccnt) == PRO_TK_NO_ERROR) { - int ucvmax = ucnt - degree[0] - 2; - int vcvmax = vcnt - degree[1] - 2; - - ON_NurbsSurface *ns = ON_NurbsSurface::New(3, (w_array) ? 1 : 0, degree[0]+1, degree[1]+1, ucvmax+1, vcvmax+1); - - // knot index (>= 0 and < Order + CV_count - 2) - // generate u-knots - int n = ucvmax+1; - int p = degree[0]; - int m = n + p - 1; - for (int i = 0; i < p; i++) { - ns->SetKnot(0, i, 0.0); - } - for (int j = 1; j < n - p; j++) { - double x = (double)j / (double)(n - p); - int knot_index = j + p - 1; - ns->SetKnot(0, knot_index, x); - } - for (int i = m - p; i < m; i++) { - ns->SetKnot(0, i, 1.0); - } - // generate v-knots - n = vcvmax+1; - p = degree[1]; - m = n + p - 1; - for (int i = 0; i < p; i++) { - ns->SetKnot(1, i, 0.0); - } - for (int j = 1; j < n - p; j++) { - double x = (double)j / (double)(n - p); - int knot_index = j + p - 1; - ns->SetKnot(1, knot_index, x); - } - for (int i = m - p; i < m; i++) { - ns->SetKnot(1, i, 1.0); - } - - if (ns->m_is_rat) { - for (int i = 0; i <= ucvmax; i++) { - for (int j = 0; j <= vcvmax; j++) { - ON_4dPoint cv; - cv[0] = cntl_pnts[i*(vcvmax+1)+j][0]; - cv[1] = cntl_pnts[i*(vcvmax+1)+j][1]; - cv[2] = cntl_pnts[i*(vcvmax+1)+j][2]; - cv[3] = w_array[i]; - ns->SetCV(i,j,cv); - } - } - } else { - for (int i = 0; i <= ucvmax; i++) { - for (int j = 0; j <= vcvmax; j++) { - ON_3dPoint cv; - cv[0] = cntl_pnts[i*(vcvmax+1)+j][0]; - cv[1] = cntl_pnts[i*(vcvmax+1)+j][1]; - cv[2] = cntl_pnts[i*(vcvmax+1)+j][2]; - ns->SetCV(i,j,cv); - } - } - } - int n_id = nbrep->AddSurface(ns); - ON_BrepFace &nface = nbrep->NewFace(n_id); - (*bdata->cs_to_onf)[c_id] = nface.m_face_index; - if (s_orient == PRO_SURF_ORIENT_IN) nbrep->FlipFace(nface); - } - - ProSurfaceContourVisit(s, contour_process, contour_filter, app_data); - } + int s_id; + ProSurfaceToNURBS(s, &ndata); + ProSurfacedataGet(ndata, &s_type, uvmin, uvmax, &s_orient, &s_shape, &s_id); + if (s_type == PRO_SRF_B_SPL) { + int degree[2]; + double *up_array = NULL; + double *vp_array = NULL; + double *w_array = NULL; + ProVector *cntl_pnts; + int ucnt, vcnt, ccnt; + if (ProBsplinesrfdataGet(&s_shape, degree, &up_array, &vp_array, &w_array, &cntl_pnts, &ucnt, &vcnt, &ccnt) == PRO_TK_NO_ERROR) { + int ucvmax = ucnt - degree[0] - 2; + int vcvmax = vcnt - degree[1] - 2; + + ON_NurbsSurface *ns = ON_NurbsSurface::New(3, (w_array) ? 1 : 0, degree[0]+1, degree[1]+1, ucvmax+1, vcvmax+1); + + // knot index (>= 0 and < Order + CV_count - 2) + // generate u-knots + int n = ucvmax+1; + int p = degree[0]; + int m = n + p - 1; + for (int i = 0; i < p; i++) { + ns->SetKnot(0, i, 0.0); + } + for (int j = 1; j < n - p; j++) { + double x = (double)j / (double)(n - p); + int knot_index = j + p - 1; + ns->SetKnot(0, knot_index, x); + } + for (int i = m - p; i < m; i++) { + ns->SetKnot(0, i, 1.0); + } + /** generate v-knots */ + n = vcvmax+1; + p = degree[1]; + m = n + p - 1; + for (int i = 0; i < p; i++) { + ns->SetKnot(1, i, 0.0); + } + for (int j = 1; j < n - p; j++) { + double x = (double)j / (double)(n - p); + int knot_index = j + p - 1; + ns->SetKnot(1, knot_index, x); + } + for (int i = m - p; i < m; i++) { + ns->SetKnot(1, i, 1.0); + } + + if (ns->m_is_rat) { + for (int i = 0; i <= ucvmax; i++) { + for (int j = 0; j <= vcvmax; j++) { + ON_4dPoint cv; + cv[0] = cntl_pnts[i*(vcvmax+1)+j][0]; + cv[1] = cntl_pnts[i*(vcvmax+1)+j][1]; + cv[2] = cntl_pnts[i*(vcvmax+1)+j][2]; + cv[3] = w_array[i]; + ns->SetCV(i,j,cv); + } + } + } else { + for (int i = 0; i <= ucvmax; i++) { + for (int j = 0; j <= vcvmax; j++) { + ON_3dPoint cv; + cv[0] = cntl_pnts[i*(vcvmax+1)+j][0]; + cv[1] = cntl_pnts[i*(vcvmax+1)+j][1]; + cv[2] = cntl_pnts[i*(vcvmax+1)+j][2]; + ns->SetCV(i,j,cv); + } + } + } + int n_id = nbrep->AddSurface(ns); + ON_BrepFace &nface = nbrep->NewFace(n_id); + (*bdata->cs_to_onf)[c_id] = nface.m_face_index; + if (s_orient == PRO_SURF_ORIENT_IN) nbrep->FlipFace(nface); + } + + ProSurfaceContourVisit(s, contour_process, contour_filter, app_data); + } } return PRO_TK_NO_ERROR; @@ -451,7 +478,7 @@ opennurbs_part(struct creo_conv_info *cinfo, ProMdl model, struct bu_vls **sname ProMdlMdlnameGet(model, wname); ProSolidSurfaceVisit(psol, surface_process, surface_filter, (ProAppData)&bdata); - /* Output the solid */ + /** Output the solid */ *sname = get_brlcad_name(cinfo, wname, "brep", N_SOLID); mk_brep(cinfo->wdbp, bu_vls_addr(*sname), nbrep); /* @@ -483,6 +510,7 @@ opennurbs_part(struct creo_conv_info *cinfo, ProMdl model, struct bu_vls **sname return ret; } + extern "C" ProError tessellate_part(struct creo_conv_info *cinfo, ProMdl model, struct bu_vls **sname) { @@ -507,9 +535,9 @@ tessellate_part(struct creo_conv_info *cinfo, ProMdl model, struct bu_vls **snam double curr_angle; double factor = cinfo->creo_to_brl_conv; - // Note: The below code works, but we can't use model units - Creo - // "corrects" object sizes with matricies in the parent hierarchies - // and correcting it here results in problems with those matricies. + // Note: The below code works, but we can't use model units - Creo + // "corrects" object sizes with matricies in the parent hierarchies + // and correcting it here results in problems with those matricies. // ProError ustatus = creo_model_units(&factor, model); ProMdlMdlnameGet(model, wname); @@ -517,150 +545,155 @@ tessellate_part(struct creo_conv_info *cinfo, ProMdl model, struct bu_vls **snam creo_log(cinfo, MSG_DEBUG, "Tessellating part %s...\n", pname); - /* Tessellate part, going from coarse to fine tessellation */ + /** Tessellate part, going from coarse to fine tessellation */ for (int i = 0; i <= cinfo->max_to_min_steps; ++i) { - curr_error = cinfo->max_error - (i * cinfo->error_increment); - curr_angle = cinfo->min_angle_cntrl + (i * cinfo->angle_increment); - - vert_tree = bg_vert_tree_create(); - norm_tree = bg_vert_tree_create(); - - //creo_log(cinfo, MSG_OK, "\tTessellating %s using: error - %g, angle - %g\n", pname, curr_error, curr_angle); - - status = ProPartTessellate(ProMdlToPart(model), curr_error/cinfo->creo_to_brl_conv, curr_angle, PRO_B_TRUE, &tess); - if (status != PRO_TK_NO_ERROR) { - creo_log(cinfo, MSG_DEBUG, "%s: failed to tessellate using: error - %g, angle - %g\n", pname, curr_error, curr_angle); - // creo_log(cinfo, MSG_DEBUG, "\tmax_error = %g, min_error - %g, error_increment - %g\n", cinfo->max_error, cinfo->min_error, cinfo->error_increment); - // creo_log(cinfo, MSG_DEBUG, "\tmax_angle_cntrl = %g, min_angle_cntrl - %g, angle_increment - %g\n", cinfo->max_angle_cntrl, cinfo->min_angle_cntrl, cinfo->angle_increment); - // creo_log(cinfo, MSG_DEBUG, "\tcurr_error = %g, curr_angle - %g\n", curr_error, curr_angle); - continue; - } - - - /* We got through the initial tests - how many surfaces do we have? */ - status = ProArraySizeGet( (ProArray)tess, &surface_count ); - if (status != PRO_TK_NO_ERROR) goto tess_cleanup; - if ( surface_count < 1 ) { - - /* free the tessellation memory */ - ProPartTessellationFree( &tess ); - tess = NULL; - - /* Free trees */ - bg_vert_tree_destroy(vert_tree); - bg_vert_tree_destroy(norm_tree); - - status = PRO_TK_NOT_EXIST; - goto tess_cleanup; - } - - - for (int surfno=0; surfno < surface_count; surfno++ ) { - for (int j=0; j < tess[surfno].n_facets; j++ ) { - /* grab the triangle */ - vert_no = tess[surfno].facets[j][0]; - v1 = bg_vert_tree_add(vert_tree, tess[surfno].vertices[vert_no][0], tess[surfno].vertices[vert_no][1], - tess[surfno].vertices[vert_no][2], cinfo->local_tol_sq ); - vert_no = tess[surfno].facets[j][1]; - v2 = bg_vert_tree_add(vert_tree, tess[surfno].vertices[vert_no][0], tess[surfno].vertices[vert_no][1], - tess[surfno].vertices[vert_no][2], cinfo->local_tol_sq ); - vert_no = tess[surfno].facets[j][2]; - v3 = bg_vert_tree_add(vert_tree, tess[surfno].vertices[vert_no][0], tess[surfno].vertices[vert_no][1], - tess[surfno].vertices[vert_no][2], cinfo->local_tol_sq ); - - if (bad_triangle(cinfo, v1, v2, v3, vert_tree)) continue; - - faces.push_back(v1); - faces.push_back(v3); - faces.push_back(v2); - - /* grab the surface normals */ - if (cinfo->get_normals) { - vert_no = tess[surfno].facets[j][0]; - VUNITIZE( tess[surfno].normals[vert_no] ); - n1 = bg_vert_tree_add(norm_tree, tess[surfno].normals[vert_no][0], tess[surfno].normals[vert_no][1], - tess[surfno].normals[vert_no][2], cinfo->local_tol_sq ); - vert_no = tess[surfno].facets[j][1]; - VUNITIZE( tess[surfno].normals[vert_no] ); - n2 = bg_vert_tree_add(norm_tree, tess[surfno].normals[vert_no][0], tess[surfno].normals[vert_no][1], - tess[surfno].normals[vert_no][2], cinfo->local_tol_sq ); - vert_no = tess[surfno].facets[j][2]; - VUNITIZE( tess[surfno].normals[vert_no] ); - n3 = bg_vert_tree_add(norm_tree, tess[surfno].normals[vert_no][0], tess[surfno].normals[vert_no][1], - tess[surfno].normals[vert_no][2], cinfo->local_tol_sq ); - - face_normals.push_back(n1); - face_normals.push_back(n3); - face_normals.push_back(n2); - } - } - } - - /* Check solidity */ - int bot_is_solid = !bg_trimesh_solid((int)vert_tree->curr_vert, (int)faces.size() / 3, vert_tree->the_array, &faces[0], NULL); - - /* If it's not solid and we're testing solidity, keep trying... */ - if (!bot_is_solid) { - if (cinfo->check_solidity) { - /* free the tessellation memory */ - ProPartTessellationFree( &tess ); - tess = NULL; - - /* Free trees */ - bg_vert_tree_destroy(vert_tree); - bg_vert_tree_destroy(norm_tree); - - creo_log(cinfo, MSG_DEBUG, "%s tessellation using error - %g, angle - %g failed solidity test, trying next level...\n", pname, curr_error, curr_angle); - - } else { - creo_log(cinfo, MSG_DEBUG, "%s tessellation failed solidity test, but solidity requirement is not enabled... continuing...\n", pname, curr_error, curr_angle); - success = 1; - break; - } - } else { - success = 1; - break; - } + curr_error = cinfo->max_error - (i * cinfo->error_increment); + curr_angle = cinfo->min_angle_cntrl + (i * cinfo->angle_increment); + + vert_tree = bg_vert_tree_create(); + norm_tree = bg_vert_tree_create(); + + //creo_log(cinfo, MSG_OK, "\tTessellating %s using: error - %g, angle - %g\n", pname, curr_error, curr_angle); + + status = ProPartTessellate(ProMdlToPart(model), curr_error/cinfo->creo_to_brl_conv, curr_angle, PRO_B_TRUE, &tess); + if (status != PRO_TK_NO_ERROR) { + creo_log(cinfo, MSG_DEBUG, "%s: failed to tessellate using: error - %g, angle - %g\n", pname, curr_error, curr_angle); + /** + * TODO -- Find out if these serve a purpose: + * + * //creo_log(cinfo, MSG_DEBUG, "\tmax_error = %g, min_error - %g, error_increment - %g\n", cinfo->max_error, cinfo->min_error, cinfo->error_increment); + * //creo_log(cinfo, MSG_DEBUG, "\tmax_angle_cntrl = %g, min_angle_cntrl - %g, angle_increment - %g\n", cinfo->max_angle_cntrl, cinfo->min_angle_cntrl, cinfo->angle_increment); + * //creo_log(cinfo, MSG_DEBUG, "\tcurr_error = %g, curr_angle - %g\n", curr_error, curr_angle); + * + */ + continue; + } + + + /** We got through the initial tests - how many surfaces do we have? */ + status = ProArraySizeGet((ProArray)tess, &surface_count); + if (status != PRO_TK_NO_ERROR) goto tess_cleanup; + if (surface_count < 1) { + + /** Free the tessellation memory */ + ProPartTessellationFree(&tess); + tess = NULL; + + /** Free trees */ + bg_vert_tree_destroy(vert_tree); + bg_vert_tree_destroy(norm_tree); + + status = PRO_TK_NOT_EXIST; + goto tess_cleanup; + } + + + for (int surfno = 0; surfno < surface_count; surfno++) { + for (int j = 0; j < tess[surfno].n_facets; j++) { + /** Grab the triangle */ + vert_no = tess[surfno].facets[j][0]; + v1 = bg_vert_tree_add(vert_tree, tess[surfno].vertices[vert_no][0], tess[surfno].vertices[vert_no][1], + tess[surfno].vertices[vert_no][2], cinfo->local_tol_sq); + vert_no = tess[surfno].facets[j][1]; + v2 = bg_vert_tree_add(vert_tree, tess[surfno].vertices[vert_no][0], tess[surfno].vertices[vert_no][1], + tess[surfno].vertices[vert_no][2], cinfo->local_tol_sq); + vert_no = tess[surfno].facets[j][2]; + v3 = bg_vert_tree_add(vert_tree, tess[surfno].vertices[vert_no][0], tess[surfno].vertices[vert_no][1], + tess[surfno].vertices[vert_no][2], cinfo->local_tol_sq); + + if (bad_triangle(cinfo, v1, v2, v3, vert_tree)) continue; + + faces.push_back(v1); + faces.push_back(v3); + faces.push_back(v2); + + /** Grab the surface normals */ + if (cinfo->get_normals) { + vert_no = tess[surfno].facets[j][0]; + VUNITIZE(tess[surfno].normals[vert_no]); + n1 = bg_vert_tree_add(norm_tree, tess[surfno].normals[vert_no][0], tess[surfno].normals[vert_no][1], + tess[surfno].normals[vert_no][2], cinfo->local_tol_sq); + vert_no = tess[surfno].facets[j][1]; + VUNITIZE(tess[surfno].normals[vert_no]); + n2 = bg_vert_tree_add(norm_tree, tess[surfno].normals[vert_no][0], tess[surfno].normals[vert_no][1], + tess[surfno].normals[vert_no][2], cinfo->local_tol_sq); + vert_no = tess[surfno].facets[j][2]; + VUNITIZE(tess[surfno].normals[vert_no]); + n3 = bg_vert_tree_add(norm_tree, tess[surfno].normals[vert_no][0], tess[surfno].normals[vert_no][1], + tess[surfno].normals[vert_no][2], cinfo->local_tol_sq); + + face_normals.push_back(n1); + face_normals.push_back(n3); + face_normals.push_back(n2); + } + } + } + + /** Check solidity */ + int bot_is_solid = !bg_trimesh_solid((int)vert_tree->curr_vert, (int)faces.size() / 3, vert_tree->the_array, &faces[0], NULL); + + /** If it's not solid and we're testing solidity, keep trying... */ + if (!bot_is_solid) { + if (cinfo->check_solidity) { + /** Free the tessellation memory */ + ProPartTessellationFree(&tess); + tess = NULL; + + /** Free trees */ + bg_vert_tree_destroy(vert_tree); + bg_vert_tree_destroy(norm_tree); + + creo_log(cinfo, MSG_DEBUG, "%s tessellation using error - %g, angle - %g failed solidity test, trying next level...\n", pname, curr_error, curr_angle); + + } else { + creo_log(cinfo, MSG_DEBUG, "%s tessellation failed solidity test, but solidity requirement is not enabled... continuing...\n", pname, curr_error, curr_angle); + success = 1; + break; + } + } else { + success = 1; + break; + } } if (!success) { - status = PRO_TK_NOT_EXIST; - goto tess_cleanup; + status = PRO_TK_NOT_EXIST; + goto tess_cleanup; } else { - status = PRO_TK_NO_ERROR; + status = PRO_TK_NO_ERROR; } - /* make sure we have non-zero faces (and if needed, face_normals) vectors */ + /** Make sure we have non-zero faces (and if needed, face_normals) vectors */ if (faces.size() == 0 || !vert_tree->curr_vert) { - status = PRO_TK_NOT_EXIST; - goto tess_cleanup; + status = PRO_TK_NOT_EXIST; + goto tess_cleanup; } if (cinfo->get_normals && face_normals.size() == 0) { - status = PRO_TK_NOT_EXIST; - goto tess_cleanup; + status = PRO_TK_NOT_EXIST; + goto tess_cleanup; } creo_log(cinfo, MSG_OK, "%s: successfully tessellated with tessellation error: %g and angle: %g!!!\n", pname, curr_error, curr_angle); for (unsigned int i = 0; i < vert_tree->curr_vert * 3; i++) { - vert_tree->the_array[i] = vert_tree->the_array[i] * factor; + vert_tree->the_array[i] = vert_tree->the_array[i] * factor; } - /* Output the solid - TODO - what is the correct ordering??? does CCW always work? */ + /** Output the solid - TODO - what is the correct ordering??? does CCW always work? */ *sname = get_brlcad_name(cinfo, wname, "s", N_SOLID); if (cinfo->get_normals) { - mk_bot_w_normals(cinfo->wdbp, bu_vls_addr(*sname), RT_BOT_SOLID, RT_BOT_CCW, 0, vert_tree->curr_vert, (size_t)(faces.size()/3), vert_tree->the_array, &faces[0], NULL, NULL, (size_t)(face_normals.size()/3), norm_tree->the_array, &face_normals[0]); + mk_bot_w_normals(cinfo->wdbp, bu_vls_addr(*sname), RT_BOT_SOLID, RT_BOT_CCW, 0, vert_tree->curr_vert, (size_t)(faces.size()/3), vert_tree->the_array, &faces[0], NULL, NULL, (size_t)(face_normals.size()/3), norm_tree->the_array, &face_normals[0]); } else { - mk_bot(cinfo->wdbp, bu_vls_addr(*sname), RT_BOT_SOLID, RT_BOT_CCW, 0, vert_tree->curr_vert, (size_t)(faces.size()/3), vert_tree->the_array, &faces[0], NULL, NULL); + mk_bot(cinfo->wdbp, bu_vls_addr(*sname), RT_BOT_SOLID, RT_BOT_CCW, 0, vert_tree->curr_vert, (size_t)(faces.size()/3), vert_tree->the_array, &faces[0], NULL, NULL); } tess_cleanup: - /* free the tessellation memory */ - ProPartTessellationFree( &tess ); + /** Free the tessellation memory */ + ProPartTessellationFree(&tess); tess = NULL; - /* Free trees */ + /** Free trees */ bg_vert_tree_destroy(vert_tree); bg_vert_tree_destroy(norm_tree); @@ -668,14 +701,15 @@ tessellate_part(struct creo_conv_info *cinfo, ProMdl model, struct bu_vls **snam } -/* routine to output a part as a BRL-CAD region with one BOT solid +/** + * Routine to output a part as a BRL-CAD region with one BOT solid * The region will have the name from Pro/E with a .r suffix. - w* The solid will have the same name with ".bot" prefix. + * The solid will have the same name with ".bot" prefix. * - * returns: - * PRO_TK_NO_ERROR - OK - * PRO_TK_NOT_EXIST - Object not solid - * other ProError returns - error + * returns: + * PRO_TK_NO_ERROR - OK + * PRO_TK_NOT_EXIST - Object not solid + * other ProError returns - error */ extern "C" ProError output_part(struct creo_conv_info *cinfo, ProMdl model) @@ -737,200 +771,218 @@ output_part(struct creo_conv_info *cinfo, ProMdl model) ProWstringToString(pname, wname); creo_log(cinfo, MSG_OK, "Processing %s:\n", pname); - /* TODO - add some up-front logic to detect parts with no associated geometry. */ - + /** + * TODO - add some up-front logic to detect parts with no + * associated geometry. + */ - /* Collect info about things that might be eliminated */ + /** Collect info about things that might be eliminated */ if (cinfo->do_elims) { - - /* Apply user supplied criteria to see if we have anything to suppress */ - ProSolidFeatVisit(ProMdlToSolid(model), do_feature_visit, feature_filter, (ProAppData)pinfo); - - /* If we've got anything to suppress, go ahead and do it. */ - if (!pinfo->suppressed_features->empty()) { - ret = ProFeatureSuppress(ProMdlToSolid(model), &(pinfo->suppressed_features->at(0)), pinfo->suppressed_features->size(), NULL, 0 ); - /* If something went wrong, need to undo just the suppressions we added */ - if (ret != PRO_TK_NO_ERROR) { - creo_log(cinfo, MSG_DEBUG, "%s: failed to suppress features!!!\n", pname); - unsuppress_features(pinfo); - } else { - creo_log(cinfo, MSG_STATUS, "%s: features suppressed... continuing with conversion\n", pname); - } - } + /** + * Apply user supplied criteria to see if we have anything + * to suppress + */ + ProSolidFeatVisit(ProMdlToSolid(model), do_feature_visit, feature_filter, (ProAppData)pinfo); + + /** If we've got anything to suppress, go ahead and do it. */ + if (!pinfo->suppressed_features->empty()) { + ret = ProFeatureSuppress(ProMdlToSolid(model), &(pinfo->suppressed_features->at(0)), pinfo->suppressed_features->size(), NULL, 0); + /** If something went wrong, need to undo just the suppressions we added */ + if (ret != PRO_TK_NO_ERROR) { + creo_log(cinfo, MSG_DEBUG, "%s: failed to suppress features!!!\n", pname); + unsuppress_features(pinfo); + } else { + creo_log(cinfo, MSG_STATUS, "%s: features suppressed... continuing with conversion\n", pname); + } + } } - /* Get bounding box of a solid using "ProSolidOutlineGet" + /** + * Get bounding box of a solid using "ProSolidOutlineGet" * TODO - may want to use this to implement relative facetization tolerance... */ if (ProSolidOutlineGet(ProMdlToSolid(model), bboxpnts) != PRO_TK_NO_ERROR) have_bbox = 0; - /* TODO - support an option to convert to ON_Brep */ - //status = opennurbs_part(cinfo, model, &sname); + /** + * TODO - support an option to convert to ON_Brep + * + * //status = opennurbs_part(cinfo, model, &sname); + * + */ - /* Tessellate */ + /** Tessellate */ status = tessellate_part(cinfo, model, &sname); - /* Deal with the solid conversion results */ + /** Deal with the solid conversion results */ if (status == PRO_TK_NOT_EXIST) { - /* Failed!!! */ - creo_log(cinfo, MSG_DEBUG, "%s: tessellation failed.\n", pname); - if (cinfo->debug_bboxes && have_bbox) { - /* A failed solid conversion with a bounding box indicates a problem - rather than - * ignore it, put the bbox in the .g file as a placeholder. */ - point_t rmin, rmax; - failed_solid = 1; - sname = get_brlcad_name(cinfo, wname, "rpp", N_SOLID); - rmin[0] = bboxpnts[0][0]; - rmin[1] = bboxpnts[0][1]; - rmin[2] = bboxpnts[0][2]; - rmax[0] = bboxpnts[1][0]; - rmax[1] = bboxpnts[1][1]; - rmax[2] = bboxpnts[1][2]; - mk_rpp(cinfo->wdbp, bu_vls_addr(sname), rmin, rmax); - creo_log(cinfo, MSG_FAIL, "%s: replaced with bounding box.\n", pname); - goto have_part; - } else { - wchar_t *stable = stable_wchar(cinfo, wname); - if (!stable) { - creo_log(cinfo, MSG_DEBUG, "%s - no stable version of name found???.\n", pname); - } else { - cinfo->empty->insert(stable); - } - creo_log(cinfo, MSG_FAIL, "%s not converted.\n", pname); - ret = status; - goto cleanup; - } + /** Failed!!! */ + creo_log(cinfo, MSG_DEBUG, "%s: tessellation failed.\n", pname); + if (cinfo->debug_bboxes && have_bbox) { + /** + * A failed solid conversion with a bounding box indicates a + * problem. Rather than ignore it, put the bbox in the .g file + * as a placeholder. + */ + point_t rmin, rmax; + failed_solid = 1; + sname = get_brlcad_name(cinfo, wname, "rpp", N_SOLID); + rmin[0] = bboxpnts[0][0]; + rmin[1] = bboxpnts[0][1]; + rmin[2] = bboxpnts[0][2]; + rmax[0] = bboxpnts[1][0]; + rmax[1] = bboxpnts[1][1]; + rmax[2] = bboxpnts[1][2]; + mk_rpp(cinfo->wdbp, bu_vls_addr(sname), rmin, rmax); + creo_log(cinfo, MSG_FAIL, "%s: replaced with bounding box.\n", pname); + goto have_part; + } else { + wchar_t *stable = stable_wchar(cinfo, wname); + if (!stable) { + creo_log(cinfo, MSG_DEBUG, "%s - no stable version of name found???.\n", pname); + } else { + cinfo->empty->insert(stable); + } + creo_log(cinfo, MSG_FAIL, "%s not converted.\n", pname); + ret = status; + goto cleanup; + } } have_part: - /* We've got a part - the output for a part is a parent region and the solid underneath it. */ - //have_part: + /** + * We've got a part - the output for a part is a parent region + * and the solid underneath it. + * + */ + BU_LIST_INIT(&wcomb.l); rname = get_brlcad_name(cinfo, wname, "r", N_REGION); - /* Add the solid to the region comb */ + /** Add the solid to the region comb */ (void)mk_addmember(bu_vls_addr(sname), &wcomb.l, NULL, WMOP_UNION); - /* Add any subtraction solids created by the hole handling */ + /** Add any subtraction solids created by the hole handling */ for (unsigned int i = 0; i < pinfo->subtractions->size(); i++) { - (void)mk_addmember(pinfo->subtractions->at(i)->d_namep, &wcomb.l, NULL, WMOP_SUBTRACT); + (void)mk_addmember(pinfo->subtractions->at(i)->d_namep, &wcomb.l, NULL, WMOP_SUBTRACT); } - /* Get the surface properties from the part and output the region comb */ + /** Get the surface properties from the part and output the region comb */ ProMdlToModelitem(model, &mitm); if (ProSurfaceAppearancepropsGet(&mitm, &aprops) == PRO_TK_NO_ERROR) { - /* use the colors, ... that were set in CREO */ - rgbflts[0] = aprops.color_rgb[0]; - rgbflts[1] = aprops.color_rgb[1]; - rgbflts[2] = aprops.color_rgb[2]; - bu_color_from_rgb_floats(&color, rgbflts); - bu_color_to_rgb_chars(&color, rgb); - - /* shader args */ - /* FIXME: make exporting material optional */ - bu_vls_sprintf(&shader_args, "{"); - if (!NEAR_ZERO(aprops.transparency, SMALL_FASTF)) bu_vls_printf(&shader_args, " tr %g", aprops.transparency); - if (!NEAR_EQUAL(aprops.shininess, 1.0, SMALL_FASTF)) bu_vls_printf(&shader_args, " sh %d", (int)(aprops.shininess * 18 + 2.0)); - if (!NEAR_EQUAL(aprops.diffuse, 0.3, SMALL_FASTF)) bu_vls_printf(&shader_args, " di %g", aprops.diffuse); - if (!NEAR_EQUAL(aprops.highlite, 0.7, SMALL_FASTF)) bu_vls_printf(&shader_args, " sp %g", aprops.highlite); - bu_vls_printf(&shader_args, "}"); - - /* Make the region comb */ - mk_comb(cinfo->wdbp, bu_vls_addr(rname), &wcomb.l, 1, - NULL, NULL, (const unsigned char *)rgb, - cinfo->reg_id, 0, 0, 0, 0, 0, 0); + /** Use the colors, ... that were set in CREO */ + rgbflts[0] = aprops.color_rgb[0]; + rgbflts[1] = aprops.color_rgb[1]; + rgbflts[2] = aprops.color_rgb[2]; + bu_color_from_rgb_floats(&color, rgbflts); + bu_color_to_rgb_chars(&color, rgb); + + /** Shader args */ + /** + * TODO Make exporting material optional + */ + bu_vls_sprintf(&shader_args, "{"); + if (!NEAR_ZERO(aprops.transparency, SMALL_FASTF)) bu_vls_printf(&shader_args, " tr %g", aprops.transparency); + if (!NEAR_EQUAL(aprops.shininess, 1.0, SMALL_FASTF)) bu_vls_printf(&shader_args, " sh %d", (int)(aprops.shininess * 18 + 2.0)); + if (!NEAR_EQUAL(aprops.diffuse, 0.3, SMALL_FASTF)) bu_vls_printf(&shader_args, " di %g", aprops.diffuse); + if (!NEAR_EQUAL(aprops.highlite, 0.7, SMALL_FASTF)) bu_vls_printf(&shader_args, " sp %g", aprops.highlite); + bu_vls_printf(&shader_args, "}"); + + /** Make the region comb */ + mk_comb(cinfo->wdbp, bu_vls_addr(rname), &wcomb.l, 1, + NULL, NULL, (const unsigned char *)rgb, + cinfo->reg_id, 0, 0, 0, 0, 0, 0); } else { - /* something is wrong, but just ignore the missing properties */ - creo_log(cinfo, MSG_DEBUG, "Error getting surface properties for %s\n", pname); - mk_comb(cinfo->wdbp, bu_vls_addr(rname), &wcomb.l, 1, NULL, NULL, NULL, cinfo->reg_id, 0, 0, 0, 0, 0, 0); + /** Something is wrong, but just ignore the missing properties */ + creo_log(cinfo, MSG_DEBUG, "Error getting surface properties for %s\n", pname); + mk_comb(cinfo->wdbp, bu_vls_addr(rname), &wcomb.l, 1, NULL, NULL, NULL, cinfo->reg_id, 0, 0, 0, 0, 0, 0); } - /* Set the CREO_NAME attribute for the solid/primitive */ + /** Set the CREO_NAME attribute for the solid/primitive */ creo_id = get_brlcad_name(cinfo, wname, NULL, N_CREO); sdp = db_lookup(cinfo->wdbp->dbip, bu_vls_addr(sname), LOOKUP_QUIET); db5_get_attributes(cinfo->wdbp->dbip, &s_avs, sdp); bu_avs_add(&s_avs, "CREO_NAME", bu_vls_addr(creo_id)); if (failed_solid) { - bu_avs_add(&s_avs, "SOLID_STATUS", "FAILED"); + bu_avs_add(&s_avs, "SOLID_STATUS", "FAILED"); } db5_standardize_avs(&s_avs); db5_update_attributes(sdp, &s_avs, cinfo->wdbp->dbip); - /* Set the CREO attributes for the region */ + /** Set the CREO attributes for the region */ rdp = db_lookup(cinfo->wdbp->dbip, bu_vls_addr(rname), LOOKUP_QUIET); db5_get_attributes(cinfo->wdbp->dbip, &r_avs, rdp); bu_avs_add(&r_avs, "CREO_NAME", bu_vls_addr(creo_id)); if (ProMdlVerstampGet(model, &cstamp) == PRO_TK_NO_ERROR) { - if (ProVerstampStringGet(cstamp, &verstr) == PRO_TK_NO_ERROR) { - bu_avs_add(&r_avs, "CREO_VERSION_STAMP", verstr); - } - ProVerstampStringFree(&verstr); + if (ProVerstampStringGet(cstamp, &verstr) == PRO_TK_NO_ERROR) { + bu_avs_add(&r_avs, "CREO_VERSION_STAMP", verstr); + } + ProVerstampStringFree(&verstr); } - /* if the part has a material, add it as an attribute */ - if (ProPartMaterialNameGet(ProMdlToPart(model), material) == PRO_TK_NO_ERROR ) { - ProWstringToString(str, material); - bu_avs_add(&r_avs, "material_name", str); - - /* get the density for this material */ - if (ProPartMaterialdataGet( ProMdlToPart(model), material, &material_props) == PRO_TK_NO_ERROR) { - got_density = 1; - bu_vls_sprintf(&mdstr, "%g", material_props.mass_density); - bu_avs_add(&r_avs, "density", bu_vls_addr(&mdstr)); - bu_vls_free(&mdstr); - } + /** If the part has a material, add it as an attribute */ + if (ProPartMaterialNameGet(ProMdlToPart(model), material) == PRO_TK_NO_ERROR) { + ProWstringToString(str, material); + bu_avs_add(&r_avs, "material_name", str); + + /** Get the density for this material */ + if (ProPartMaterialdataGet(ProMdlToPart(model), material, &material_props) == PRO_TK_NO_ERROR) { + got_density = 1; + bu_vls_sprintf(&mdstr, "%g", material_props.mass_density); + bu_avs_add(&r_avs, "density", bu_vls_addr(&mdstr)); + bu_vls_free(&mdstr); + } } - /* calculate mass properties */ + /** Calculate mass properties */ if (ProSolidMassPropertyGet(ProMdlToSolid(model), NULL, &mass_prop) == PRO_TK_NO_ERROR) { - if (!got_density && mass_prop.density > 0.0) { - bu_vls_sprintf(&vstr, "%g", mass_prop.density); - bu_avs_add(&r_avs, "density", bu_vls_addr(&vstr)); - } - if (mass_prop.mass > 0.0) { - bu_vls_sprintf(&vstr, "%g", mass_prop.mass); - bu_avs_add(&r_avs, "mass", bu_vls_addr(&vstr)); - } - if (mass_prop.volume > 0.0) { - bu_vls_sprintf(&vstr, "%g", mass_prop.volume); - bu_avs_add(&r_avs, "volume", bu_vls_addr(&vstr)); - } - bu_vls_free(&vstr); + if (!got_density && mass_prop.density > 0.0) { + bu_vls_sprintf(&vstr, "%g", mass_prop.density); + bu_avs_add(&r_avs, "density", bu_vls_addr(&vstr)); + } + if (mass_prop.mass > 0.0) { + bu_vls_sprintf(&vstr, "%g", mass_prop.mass); + bu_avs_add(&r_avs, "mass", bu_vls_addr(&vstr)); + } + if (mass_prop.volume > 0.0) { + bu_vls_sprintf(&vstr, "%g", mass_prop.volume); + bu_avs_add(&r_avs, "volume", bu_vls_addr(&vstr)); + } + bu_vls_free(&vstr); } - /* If we have a user supplied list of attributes to save, do it */ + /** If we have a user supplied list of attributes to save, do it */ if (cinfo->attrs->size() > 0) { - for (unsigned int i = 0; i < cinfo->attrs->size(); i++) { - char *attr_val = NULL; - const char *arg = cinfo->attrs->at(i); - creo_attribute_val(&attr_val, arg, model); - if (attr_val) { - bu_avs_add(&r_avs, arg, attr_val); - bu_free(attr_val, "value string"); - } - } + for (unsigned int i = 0; i < cinfo->attrs->size(); i++) { + char *attr_val = NULL; + const char *arg = cinfo->attrs->at(i); + creo_attribute_val(&attr_val, arg, model); + if (attr_val) { + bu_avs_add(&r_avs, arg, attr_val); + bu_free(attr_val, "value string"); + } + } } - /* Update attributes stored on disk */ + /** Update attributes stored on disk */ db5_standardize_avs(&r_avs); db5_update_attributes(rdp, &r_avs, cinfo->wdbp->dbip); - /* increment the region id - this is a concern if we move to multithreaded generation... */ + /** Increment the region id - this is a concern if we move to multithreaded generation... */ cinfo->reg_id++; cleanup: - /* unsuppress anything we suppressed */ + /** Unsuppress anything we suppressed */ if (cinfo->do_elims && !pinfo->suppressed_features->empty()) { - creo_log(cinfo, MSG_OK, "Unsuppressing %d features\n", pinfo->suppressed_features->size()); - ret = ProFeatureResume(ProMdlToSolid(model), &pinfo->suppressed_features->at(0), pinfo->suppressed_features->size(), NULL, 0); - if (ret != PRO_TK_NO_ERROR) { - creo_log(cinfo, MSG_DEBUG, "%s: failed to unsuppress features.\n", pname); - cinfo->warn_feature_unsuppress = 1; - return ret; - } - creo_log(cinfo, MSG_STATUS, "Successfully unsuppressed features."); + creo_log(cinfo, MSG_OK, "Unsuppressing %d features\n", pinfo->suppressed_features->size()); + ret = ProFeatureResume(ProMdlToSolid(model), &pinfo->suppressed_features->at(0), pinfo->suppressed_features->size(), NULL, 0); + if (ret != PRO_TK_NO_ERROR) { + creo_log(cinfo, MSG_DEBUG, "%s: failed to unsuppress features.\n", pname); + cinfo->warn_feature_unsuppress = 1; + return ret; + } + creo_log(cinfo, MSG_STATUS, "Successfully unsuppressed features."); } delete pinfo->suppressed_features; @@ -940,7 +992,7 @@ output_part(struct creo_conv_info *cinfo, ProMdl model) return ret; } -/* +/** * Local Variables: * mode: C * tab-width: 8