[cgma-dev] r3496 - in cgm/branches/merge-cubit12/geom/ACIS_SRC: . gtcAttrib gtcAttrib/incl gtcAttrib/src
kraftche at cae.wisc.edu
kraftche at cae.wisc.edu
Tue Jan 26 20:15:24 CST 2010
Author: kraftche
Date: 2010-01-26 20:15:23 -0600 (Tue, 26 Jan 2010)
New Revision: 3496
Added:
cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisHistory.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisHistory.hpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisTopologyTool.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisTopologyTool.hpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_history.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_history.hpp
Modified:
cgm/branches/merge-cubit12/geom/ACIS_SRC/
cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisBridge.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisDrawTool.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisEdgeTool.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisFacetManager.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisFacetManager.hpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisFeatureEngine.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisFeatureEngine.hpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisHealerTool.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisHealerTool.hpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisModifyEngine.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisModifyEngine.hpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisQueryEngine.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisQueryEngine.hpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisSurfaceTool.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisSurfaceTool.hpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisToolUtil.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisToolUtil.hpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisTweakTool.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisTweakTool.hpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/BodyACIS.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/BodyACIS.hpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/CMakeLists.txt
cgm/branches/merge-cubit12/geom/ACIS_SRC/CoEdgeACIS.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/CurveACIS.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/CurveACIS.hpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/LoopACIS.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/LoopACIS.hpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/LumpACIS.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/LumpACIS.hpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/Makefile.am
cgm/branches/merge-cubit12/geom/ACIS_SRC/PointACIS.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/ShellACIS.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/SurfaceACIS.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/SurfaceACIS.hpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/UseACIS.cmake
cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_cubit_owner.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_cubit_owner.hpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_snl.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_snl.hpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_snl_simple.cpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_snl_simple.hpp
cgm/branches/merge-cubit12/geom/ACIS_SRC/decl_none.h
cgm/branches/merge-cubit12/geom/ACIS_SRC/gtcAttrib/
cgm/branches/merge-cubit12/geom/ACIS_SRC/gtcAttrib/CMakeLists.txt
cgm/branches/merge-cubit12/geom/ACIS_SRC/gtcAttrib/Makefile
cgm/branches/merge-cubit12/geom/ACIS_SRC/gtcAttrib/incl/
cgm/branches/merge-cubit12/geom/ACIS_SRC/gtcAttrib/incl/attrib_gtc_export.h
cgm/branches/merge-cubit12/geom/ACIS_SRC/gtcAttrib/src/
cgm/branches/merge-cubit12/geom/ACIS_SRC/gtcAttrib/src/attrib_gtc.C
Log:
Initial merge of Cubit-12 ACIS port w/ current CGM.
This probably doesn't even compile yet.
Property changes on: cgm/branches/merge-cubit12/geom/ACIS_SRC
___________________________________________________________________
Modified: svn:mergeinfo
- /cgm/trunk/geom/ACIS_SRC:3427-3493
+ /cgm/branches/cubit/geom/ACIS_SRC:3487-3491
/cgm/trunk/geom/ACIS_SRC:3427-3493
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisBridge.cpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisBridge.cpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisBridge.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -12,11 +12,7 @@
//-------------------------------------------------------------------------
// ************* BEGIN ACIS INCLUDES *************
-#if CUBIT_ACIS_VERSION < 1100
-#include "kernel/kernapi/api/api.hxx"
-#else
#include "api.hxx"
-#endif
// ************* END ACIS INCLUDES ***************
// ************* BEGIN CUBIT INCLUDES *************
@@ -99,6 +95,7 @@
{
API_BEGIN;
attribute->unhook();
+ attribute->lose();
API_END;
}
}
@@ -129,6 +126,7 @@
(attrib_ptr->string_data_list()->step_and_get())->c_str()) == 0))
{
attribute_gtc->unhook();
+ attribute_gtc->lose();
loop_continue = CUBIT_FALSE;
}
}
@@ -149,6 +147,7 @@
attrib_ptr->string_data_list()->reset();
attribute_len->unhook();
+ attribute_len->lose();
loop_continue = CUBIT_FALSE;
}
@@ -170,6 +169,7 @@
{
API_BEGIN;
attribute->unhook();
+ attribute->lose();
API_END;
}
ATTRIB_GTC_NAME *attribute_gtc =
@@ -184,6 +184,7 @@
{
API_BEGIN;
attribute_gtc->unhook();
+ attribute_gtc->lose();
API_END;
}
@@ -199,6 +200,7 @@
{
API_BEGIN;
attribute_len->unhook();
+ attribute_len->lose();
API_END;
}
}
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisDrawTool.cpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisDrawTool.cpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisDrawTool.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -9,6 +9,7 @@
// ********** BEGIN ACIS INCLUDES **********
#include "entity.hxx"
#include "body.hxx"
+#include "wire.hxx"
#include "lump.hxx"
#include "shell.hxx"
#include "loop.hxx"
@@ -81,7 +82,8 @@
return draw_FACE( (FACE*)ENTITY_ptr, color, tessellate, flush );
}
else if( IS_ENTITY_TYPE( ENTITY_ptr, LOOP ) ||
- IS_ENTITY_TYPE( ENTITY_ptr, COEDGE ) )
+ IS_ENTITY_TYPE( ENTITY_ptr, COEDGE ) ||
+ IS_ENTITY_TYPE( ENTITY_ptr, WIRE ) )
{
DLIList<EDGE*> EDGE_list;
AQE->get_EDGEs( ENTITY_ptr, EDGE_list );
@@ -127,13 +129,12 @@
Curve *curve_ptr = AQE->populate_topology_bridges( (EDGE *)copied_ENTITY_ptr );
GMem g_mem;
- int num_points;
// get the graphics
CubitStatus stat;
- stat = AQE->get_graphics( curve_ptr, num_points, &g_mem );
+ stat = AQE->get_graphics( curve_ptr, &g_mem );
- if (stat==CUBIT_FAILURE || num_points == 0)
+ if (stat==CUBIT_FAILURE || g_mem.pointListCount == 0)
{
PRINT_ERROR("Unable to tessellate a curve for display\n" );
AQE->delete_solid_model_entities( curve_ptr );
@@ -179,41 +180,30 @@
if( tessellate )
{
- int num_tris, num_pnts, num_facets;
GMem g_mem;
unsigned short norm_tol = 10;
double dist_tol = -1.0;
- AQE->get_graphics( FACE_ptr, num_tris, num_pnts, num_facets,
- &g_mem, norm_tol, dist_tol );
+ AQE->get_graphics( FACE_ptr, &g_mem, norm_tol, dist_tol );
- if(num_tris < 1)
+ if(g_mem.fListCount < 1)
{
// decrease tolerance and try again (we can get this for small features)
norm_tol /= 2;
- AQE->get_graphics( FACE_ptr, num_tris, num_pnts, num_facets, &g_mem,
- norm_tol, dist_tol);
+ AQE->get_graphics( FACE_ptr, &g_mem, norm_tol, dist_tol);
}
- if(num_tris < 1)
+ if(g_mem.fListCount < 1)
{
// lets give up
PRINT_ERROR( "Unable to tessellate surface for display\n" );
return CUBIT_FAILURE;
}
- // Draw the triangles
- GPoint p[3];
- GPoint* plist = g_mem.point_list();
- int* facet_list = g_mem.facet_list();
- int i, c = 0;
- for( i=0; i<num_tris; i++ )
- {
- p[0] = plist[facet_list[++c]];
- p[2] = plist[facet_list[++c]];
- p[1] = plist[facet_list[++c]];
- c++;
- GfxPreview::draw_tri( p, color );
- }
+ // draw this more efficiently as a list of polygons
+ const float* xyzs = reinterpret_cast<const float*>(g_mem.point_list());
+ GfxPreview::draw_polygons(g_mem.pointListCount, xyzs,
+ g_mem.fListCount, g_mem.facet_list(),
+ color);
}
else
{
@@ -236,5 +226,7 @@
{
const SPAposition &coords = VERTEX_ptr->geometry()->coords();
GfxPreview::draw_point( coords.x(), coords.y(), coords.z(), color );
+ if( flush )
+ GfxPreview::flush();
return CUBIT_SUCCESS;
}
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisEdgeTool.cpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisEdgeTool.cpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisEdgeTool.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -7,19 +7,11 @@
// ********** BEGIN ACIS INCLUDES **********
-#if CUBIT_ACIS_VERSION < 1100
-#include "kernel/kernapi/api/kernapi.hxx"
-#include "kernel/kerndata/top/body.hxx"
-#include "kernel/kerndata/top/vertex.hxx"
-#include "kernel/kerndata/geom/point.hxx"
-#include "intersct/sg_husk/split/esplit.hxx"
-#else
#include "kernapi.hxx"
#include "vertex.hxx"
#include "point.hxx"
#include "coverapi.hxx"
#include "esplit.hxx"
-#endif
// ********** END ACIS INCLUDES **********
@@ -64,9 +56,6 @@
AcisEdgeTool::create_curve_combine( DLIList<Curve*>& curve_list,
Curve *&new_curve_ptr )
{
- AcisQueryEngine *const AQE = AcisQueryEngine::instance();
- GeometryQueryTool *const GQT = GeometryQueryTool::instance();
-
new_curve_ptr = create_curve_combine( curve_list );
if (!new_curve_ptr)
return CUBIT_FAILURE;
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisFacetManager.cpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisFacetManager.cpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisFacetManager.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -13,11 +13,7 @@
//#define ACIS_FACET_MAN_DEBUG
-#if CUBIT_ACIS_VERSION < 1100
-#include "baseutil/vector/position.hxx"
-#else
#include "position.hxx"
-#endif
// #define ACIS_FACET_MAN_DEBUG
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisFacetManager.hpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisFacetManager.hpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisFacetManager.hpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -9,11 +9,7 @@
#ifndef ACISFACETMANAGER_HPP
#define ACISFACETMANAGER_HPP
-#if CUBIT_ACIS_VERSION < 1100
-#include "faceter/meshmgr/meshmg.hxx"
-#else
#include "meshmg.hxx"
-#endif
#include "AcisTypes.h"
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisFeatureEngine.cpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisFeatureEngine.cpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisFeatureEngine.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -34,6 +34,11 @@
GeometryFeatureTool::instance()->add_gfe(this);
}
+AcisFeatureEngine::~AcisFeatureEngine()
+{
+ instance_ = NULL;
+}
+
CubitBoolean AcisFeatureEngine::is_feature_engine( const TopologyBridge* tb_ptr )
{
if(dynamic_cast<AcisBridge*>(const_cast<TopologyBridge*>(tb_ptr)))
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisFeatureEngine.hpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisFeatureEngine.hpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisFeatureEngine.hpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -19,7 +19,7 @@
static AcisFeatureEngine* instance();
//! virtual destructor
- virtual ~AcisFeatureEngine() {}
+ virtual ~AcisFeatureEngine();
//! returns CUBIT_TRUE if the entity belongs to this feature engine
virtual CubitBoolean is_feature_engine( const TopologyBridge* );
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisHealerTool.cpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisHealerTool.cpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisHealerTool.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -12,54 +12,6 @@
#include "undefwin_.h"
#endif
-#if CUBIT_ACIS_VERSION < 1100
-#include "kernel/acis.hxx"
-#include "kernel/kernapi/api/api.hxx"
-#include "kernel/kernapi/api/kernapi.hxx"
-#include "kernel/kerndata/top/body.hxx"
-#include "kernel/kerndata/top/face.hxx"
-
-#include "boolean/kernapi/api/boolapi.hxx"
-#include "euler/kernapi/api/eulerapi.hxx"
-#include "healhusk/heal_api/heal_api.hxx"
-
-#include "kernel/kerndata/data/entity.hxx"
-#include "kernel/kerndata/lists/lists.hxx"
-
-#include "kernel/kerndata/top/alltop.hxx" // Required for is_TEDGE
-
-#include "healhusk/util/bhl_opt.hxx"
-#include "healhusk/util/tols.hxx"
-#include "healhusk/tgtspl/net_heal.hxx"
-#include "healhusk/attrib/at_aggr.hxx"
-#include "healhusk/attrib/aggrsimg.hxx"
-#include "healhusk/attrib/aggrstch.hxx"
-#include "healhusk/attrib/hmaster.hxx"
-#include "healhusk/attrib/entsimg.hxx"
-#include "healhusk/attrib/hanalsol.hxx"
-#include "healhusk/attrib/huvsolv.hxx"
-#include "healhusk/simgeom/simgeom.hxx"
-# include "healhusk/stitch/stitch.hxx"
-# include "healhusk/stitch/stch_utl.hxx"
-
-// Needed for advanced feedback
-#include "healhusk/attrib/aggrgbld.hxx"
-#include "healhusk/attrib/edgmbld.hxx"
-#include "healhusk/attrib/vegmbld.hxx"
-#include "healhusk/attrib/cegmbld.hxx"
-#include "healhusk/attrib/fagmbld.hxx"
-#include "healhusk/attrib/entstch.hxx"
-#include "healhusk/attrib/curgmbld.hxx"
-#include "healhusk/attrib/surgmbld.hxx"
-#include "healhusk/attrib/pcgmbld.hxx"
-#include "healhusk/attrib/shlgmbld.hxx"
-#include "healhusk/attrib/lpgmbld.hxx"
-#include "healhusk/attrib/lmpgmbld.hxx"
-#include "healhusk/util/traverse.hxx"
-#include "healhusk/attrib/hsharped.hxx"
-#include "healhusk/attrib/hadvspl.hxx"
-#include "healhusk/attrib/hreblend.hxx"
-#else
#include "acis.hxx"
#include "api.hxx"
#include "kernapi.hxx"
@@ -106,7 +58,6 @@
# include "traverse_heal.hxx"
# include "hsharped.hxx"
# include "hadvspl.hxx"
-#endif
#ifdef UNIX_PORT
# include "defwin_.h"
@@ -139,7 +90,6 @@
#include "Shell.hpp"
#include "RefVolume.hpp"
#include "RefVertex.hpp"
-
#include "DLIList.hpp"
// ********** END CUBIT INCLUDES **********
@@ -162,7 +112,8 @@
static double defaultStitchMinTol = CUBIT_DBL_MAX;
static logical stitchMinTolSw = FALSE;
static double stitchMaxTol = 0;
-static double defaultStitchMaxTol = CUBIT_DBL_MAX;
+//static double defaultStitchMaxTol = CUBIT_DBL_MAX;
+static double defaultStitchMaxTol = 0.1;
static logical stitchMaxTolSw = FALSE;
static logical doStitch = TRUE;
static logical userControlStitch = FALSE;
@@ -373,13 +324,9 @@
if( !userControlSimplify || (userControlSimplify && doSimplify) )
{
-#if CUBIT_ACIS_VERSION < 1100
- result = api_hh_simplify_auto( BODY_ptr);
-#else
hh_simplify_options simp_opts;
simp_opts.set_do_curve_simplification(0);
result = api_hh_simplify_auto( BODY_ptr, &simp_opts );
-#endif
if( !result.ok() )
{
PRINT_ERROR( "error in simplify\n" );
@@ -1127,12 +1074,12 @@
if ( isosplineTolSw == TRUE )
{
- ATTRIB_HH_AGGR_ISOSPLINE * att = (ATTRIB_HH_AGGR_ISOSPLINE *)
+ /*ATTRIB_HH_AGGR_ISOSPLINE * att = (ATTRIB_HH_AGGR_ISOSPLINE *)*/
find_leaf_attrib(body,ATTRIB_HH_AGGR_ISOSPLINE_TYPE);
}
else if ( defaultIsosplineTol != CUBIT_DBL_MAX )
{
- ATTRIB_HH_AGGR_ISOSPLINE * att = (ATTRIB_HH_AGGR_ISOSPLINE *)
+ /*ATTRIB_HH_AGGR_ISOSPLINE * att = (ATTRIB_HH_AGGR_ISOSPLINE *)*/
find_leaf_attrib(body,ATTRIB_HH_AGGR_ISOSPLINE_TYPE);
}
@@ -1409,7 +1356,7 @@
else if( ent != NULL )
{
if( ent->identity(BODY_LEVEL)==BODY_TYPE) {
- ATTRIB_HH_AGGR_ISOSPLINE * att = (ATTRIB_HH_AGGR_ISOSPLINE *)
+ /*ATTRIB_HH_AGGR_ISOSPLINE * att = (ATTRIB_HH_AGGR_ISOSPLINE *)*/
find_leaf_attrib(ent,ATTRIB_HH_AGGR_ISOSPLINE_TYPE);
}
}
@@ -2163,7 +2110,7 @@
ATTRIB_HH_ENT_GEOMBUILD_EDGE *att = (ATTRIB_HH_ENT_GEOMBUILD_EDGE *)
find_leaf_attrib(ent_list[i],ATTRIB_HH_ENT_GEOMBUILD_EDGE_TYPE);
if (NULL != att){
- if(att->get_vexity () == TANGENT){
+ if(att->get_vexity () == ACIS_TANGENT){
TopologyEntity* te_ptr = ATTRIB_CUBIT_OWNER::get_topology_entity(ent_list[i]);
ref_edge_ptr = CAST_TO( te_ptr, RefEdge );
if( ref_edge_ptr == NULL )
@@ -2188,7 +2135,7 @@
ATTRIB_HH_ENT_GEOMBUILD_EDGE *att = (ATTRIB_HH_ENT_GEOMBUILD_EDGE *)
find_leaf_attrib(ent_list[i],ATTRIB_HH_ENT_GEOMBUILD_EDGE_TYPE);
if (NULL != att){
- if(att->get_vexity () ==CONVEX){
+ if(att->get_vexity () ==ACIS_CONVEX){
TopologyEntity* te_ptr = ATTRIB_CUBIT_OWNER::get_topology_entity(ent_list[i]);
ref_edge_ptr = CAST_TO( te_ptr, RefEdge );
if( ref_edge_ptr == NULL )
@@ -2213,7 +2160,7 @@
ATTRIB_HH_ENT_GEOMBUILD_EDGE *att = (ATTRIB_HH_ENT_GEOMBUILD_EDGE *)
find_leaf_attrib(ent_list[i],ATTRIB_HH_ENT_GEOMBUILD_EDGE_TYPE);
if (NULL != att){
- if(att->get_vexity () ==CONCAVE){
+ if(att->get_vexity () ==ACIS_CONCAVE){
TopologyEntity* te_ptr = ATTRIB_CUBIT_OWNER::get_topology_entity(ent_list[i]);
ref_edge_ptr = CAST_TO( te_ptr, RefEdge );
if( ref_edge_ptr == NULL )
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisHealerTool.hpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisHealerTool.hpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisHealerTool.hpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -28,6 +28,10 @@
class BODY;
class ENTITY;
+const int ACIS_TANGENT = 0;
+const int ACIS_CONVEX = 1;
+const int ACIS_CONCAVE = - 1;
+
class AcisHealerTool : public GeometryHealerEngine
{
public:
Copied: cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisHistory.cpp (from rev 3491, cgm/branches/cubit/geom/ACIS_SRC/AcisHistory.cpp)
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisHistory.cpp (rev 0)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisHistory.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -0,0 +1,580 @@
+
+#include "AcisHistory.hpp"
+#include "AcisQueryEngine.hpp"
+#include "CubitMessage.hpp"
+#include "RefEntity.hpp"
+#include "acistype.hxx"
+#include "lists.hxx"
+#include "attrib_history.hpp"
+#include "CGMHistory.hpp"
+#include "GeometryQueryTool.hpp"
+
+/*Here's a brief description of how the history is created in the
+ * Acis port:
+ * 1. Create an AcisHistory object.
+ *
+ * 2. TopologyBridges are given to the port for modification. From
+ * the TopologyBridges, get all associated parent and child TopologyBridges.
+ * From each TopologyBridge, get a) the corresponding RefEntity
+ * and b) the corresponding ENTITY(s).
+ *
+ * 3. On every ACIS ENTITY, attach an attrib_history attribute.
+ * The attrib_history basically holds a unique 'tracking' integer.
+ *
+ * 4. Populate the refentity_tracking_id_map in the AcisHistory object, with
+ * pairs, where each pair consists of a RefEntity pointer and it's associated
+ * tracking id, in #3.
+ *
+ * 5. Acis performs the operation(s), making callbacks into the
+ * attrib_history's overloaded functions. It does the following:
+ * -For split_owner callbacks, where A is split into A and B,
+ * put a history attrib on B and add A's tracking integer to B.
+ * -For merge_owner callbacks, where A and B are merged into A,
+ * add B's tracking id to A. Now A will have 2 tracking ids
+ * associated with it.
+ * -In the copying callback macros, if B has been copied from A, give B
+ * the tracking id that was in A.
+ * -For the other callbacks, replace_owner, lop_change_owner, and
+ * replace_owner_geometry, add an AcisEvent to the AcisHistory object's
+ * event list.
+ *
+ * 6. Once the operation has ended and TopologyBridges have been added
+ * to the new ENTITYs (populate_topology_bridges has been called), for
+ * each TopologyBridge, create a pair consisting of
+ * a set of tracking ids and a TopologyBridge pointer.
+ *
+ * 7. Find pairs in #6 that have any tracking id in common in their sets.
+ * If you find multiple pairs who's sets in size, you have a subdivision-absorption
+ * event (n->m). If you only find a single pair that has a set with
+ * multiple tracking ids in it, you have an absorption event (n->1). If you find
+ * multiple pairs that all have a single tracking id in their set, you have
+ * a subdivision event(1->n). And if you only find a single pair with a single
+ * tracking id in it's set, you have a geometry modified event.
+ *
+ * 8. Everytime you gather one of these pair group, in #7, you create a PortEvent
+ * which ties the original RefEntity pointer(s) to the new TopologyBridge(s).
+ */
+
+AcisHistory::AcisHistory()
+{
+ trackingId = -1;
+ highLevelCopying = false;
+}
+
+AcisHistory::~AcisHistory()
+{
+ ATTRIB_HISTORY::remove_all_attribs();
+}
+
+void AcisHistory::add_event( const AcisEvent &event )
+{
+ eventList.push_back( event );
+}
+
+void AcisHistory::add_refentity_tracking_id_pair( RefEntity *ref_ent, int tracking_id )
+{
+ refentity_tracking_id_map.push_back(
+ std::pair<RefEntity*, int>( ref_ent, tracking_id));
+}
+
+
+void AcisHistory::print()
+{
+ /*
+ std::vector<CGMEvent>::iterator iter = cgmEventList.begin();
+ for(; iter != cgmEventList.end(); iter++ )
+ {
+ CGMEvent cgm_event = *iter;
+ PRINT_INFO("Event type = %s RefEntities ", event_names[ cgm_event.eventType ]);
+
+ int i;
+ for( i=0; i<cgm_event.RefEnts.size(); i++ )
+ {
+ RefEntity *ref_ent = cgm_event.RefEnts[i];
+ PRINT_INFO(" %s %d ", ref_ent->class_name(), ref_ent->id() );
+ }
+ PRINT_INFO(" ---> ");
+ for( i=0; i<cgm_event.TopologyBridges.size(); i++ )
+ {
+ TopologyBridge *tb = cgm_event.TopologyBridges[i];
+ PRINT_INFO(" %p", tb );
+ }
+ PRINT_INFO("\n");
+ } */
+}
+
+int AcisHistory::generate_next_tracking_id()
+{
+ trackingId++;
+ return trackingId;
+}
+
+void AcisHistory::add_to_tracking_ids_tb_map( std::set<int> &tracking_ids, TopologyBridge *tb )
+{
+ tracking_ids_to_tb_map.push_back( std::pair< std::set<int>, TopologyBridge*>( tracking_ids, tb ) );
+}
+
+void AcisHistory::create_cgm_history_objects()
+{
+ //look for subdivision-absorption events.
+ //Look in tracking_ids_to_tb_map for a pair whose vector
+ //has multiple integers in it. If you find another pair with the
+ //same integers in it, you've found a subdivision-absorption event.
+
+ std::vector< std::pair< std::set<int>, TopologyBridge*> > unrelated_pairs;
+ std::list< std::pair< std::set<int>, TopologyBridge*> >::iterator iter;
+
+ if( highLevelCopying )
+ {
+ while( tracking_ids_to_tb_map.size() )
+ {
+ iter = tracking_ids_to_tb_map.begin();
+
+ std::pair< std::set<int>, TopologyBridge*> pair1 = *iter;
+
+ std::vector< std::pair< std::set<int>, TopologyBridge*> > found_pairs;
+ found_pairs.push_back( pair1 );
+
+ create_port_event( CGMHistory::COPY, found_pairs );
+ tracking_ids_to_tb_map.erase( iter++ );
+ }
+ }
+ else
+ {
+
+ while( tracking_ids_to_tb_map.size() )
+ {
+ iter = tracking_ids_to_tb_map.begin();
+
+ std::pair< std::set<int>, TopologyBridge*> pair1 = *iter;
+ std::set<int> set1 = pair1.first;
+
+ //find all pairs that have a vector that contains any integer in set1,
+ //and at the same time recursively do the same for the found pairs
+ //get back a 'found_pairs' list
+
+ std::vector< std::pair< std::set<int>, TopologyBridge*> > found_pairs;
+ found_pairs.push_back( pair1 );
+ tracking_ids_to_tb_map.erase( iter++ );
+ collect_relevant_pairs( set1, found_pairs );
+
+ //if the found_pairs just contains the original pair
+ //it's a simple absorption
+ std::vector< std::pair< std::set<int>, TopologyBridge*> >::iterator vec_iter;
+ std::pair< std::set<int>, TopologyBridge*> tmp_pair;
+ if( found_pairs.size() == 1 )
+ {
+ //if the single set contains multiple integers,
+ //it's a simple absorption
+
+ vec_iter = found_pairs.begin();
+ tmp_pair = *vec_iter;
+ std::set<int> tmp_set = tmp_pair.first;
+ if( tmp_set.size() > 1 )
+ create_port_event( CGMHistory::ABSORPTION, found_pairs );
+ else
+ unrelated_pairs.push_back( pair1 );
+ }
+ else
+ {
+ //if the found_pairs all have exactly one integer in their sets,
+ //it's a simple subdivision
+ vec_iter = found_pairs.begin();
+ tmp_pair = *vec_iter;
+ std::set<int> tmp_set = tmp_pair.first;
+ int size_of_set = tmp_set.size();
+ vec_iter++;
+ bool varying_sizes = false;
+ for(; vec_iter != found_pairs.end(); vec_iter++ )
+ {
+ tmp_pair = *vec_iter;
+ tmp_set = tmp_pair.first;
+ if( size_of_set != tmp_set.size() )
+ {
+ varying_sizes = true;
+ break;
+ }
+ }
+
+ if( varying_sizes )
+ create_port_event( CGMHistory::SUBDIVISION_ABSORPTION, found_pairs );
+ else
+ create_port_event( CGMHistory::SUBDIVISION, found_pairs );
+ }
+ }
+ }
+
+ std::vector< std::pair< std::set<int>, TopologyBridge*> >::iterator vec_iter1;
+ vec_iter1 = unrelated_pairs.begin();
+ for(; vec_iter1 != unrelated_pairs.end(); vec_iter1++ )
+ {
+ std::set<int> set1 = (*vec_iter1).first;
+ if( set1.size() == 0 )
+ continue;
+ int tracking_id = *set1.begin();
+
+ std::vector<AcisEvent>::iterator vec_iter2 = eventList.begin();
+ for(; vec_iter2 != eventList.end(); vec_iter2++ )
+ {
+ AcisEvent event = (*vec_iter2);
+ if( event.eventType == CGMHistory::GEOMETRY_CHANGED ||
+ event.eventType == CGMHistory::CUT )
+ {
+ int other_tracking_id = event.entities[0];
+
+ if( tracking_id == other_tracking_id )
+ {
+ TopologyBridge *tb = (*vec_iter1).second;
+ std::pair<RefEntity*, int> tmp_pair = refentity_tracking_id_map[tracking_id];
+ RefEntity* ref_ent = tmp_pair.first;
+ CGMHistory::PortEvent port_event( event.eventType );
+ port_event.RefEnts.push_back( ref_ent );
+ port_event.TopologyBridges.push_back( tb );
+ GeometryQueryTool::instance()->history().add_port_event( port_event );
+ break;
+ }
+ }
+ }
+ }
+}
+
+
+void AcisHistory::collect_relevant_pairs( std::set<int> &seed_set,
+ std::vector< std::pair< std::set<int>, TopologyBridge*> > &found_pairs )
+{
+
+ std::list< std::pair< std::set<int>, TopologyBridge*> >::iterator iter;
+ iter = tracking_ids_to_tb_map.begin();
+
+ for(; iter != tracking_ids_to_tb_map.end(); iter++ )
+ {
+ std::pair< std::set<int>, TopologyBridge*> my_pair1 = *iter;
+ std::set<int> set1 = my_pair1.first;
+
+ if( set1.empty() )
+ continue;
+
+ std::set<int>::iterator iter1, iter2;
+ //does set1 contain any integers that are in the seed set?
+ //if so, remove the pair from the list and add it to 'found_pairs'
+ iter1 = set1.begin();
+ bool pair_found = false;
+ for(; iter1 != set1.end(); iter1++ )
+ {
+ int int1 = *iter1;
+
+ for( iter2 = seed_set.begin(); iter2 != seed_set.end(); iter2++ )
+ {
+ int int2 = *iter2;
+
+ if( int2 == int1 )
+ {
+ //clear out the set
+ std::set<int> &tmp_set = (*iter).first;
+ tmp_set.clear();
+
+ found_pairs.push_back( my_pair1 );
+ //tracking_ids_to_tb_map.erase( iter++ );
+ collect_relevant_pairs( set1, found_pairs );
+ pair_found = true;
+ break;
+ }
+ }
+ if( pair_found )
+ break;
+ }
+// if( pair_found == false )
+// iter++;
+ }
+}
+
+
+void AcisHistory::create_port_event( CGMHistory::EventType event_type,
+ std::vector< std::pair< std::set<int>, TopologyBridge*> > &found_pairs )
+{
+ CGMHistory::PortEvent port_event( event_type );
+
+ //add all TBs to the event's TB list
+ std::vector< std::pair< std::set<int>, TopologyBridge*> >::iterator vec_iter;
+ vec_iter = found_pairs.begin();
+ std::pair< std::set<int>, TopologyBridge*> tmp_pair;
+ DLIList<RefEntity*> ref_ent_list;
+ DLIList<TopologyBridge*> tb_list;
+ for(; vec_iter != found_pairs.end(); vec_iter++ )
+ {
+ tmp_pair = *vec_iter;
+ TopologyBridge *tb = tmp_pair.second;
+ tb_list.append( tb );
+
+ std::set<int> tmp_set = tmp_pair.first;
+ std::set<int>::iterator iter=tmp_set.begin();
+ for(; iter != tmp_set.end(); iter++ )
+ {
+ int index = *iter;
+ std::pair<RefEntity*, int> pair2 = refentity_tracking_id_map[index];
+ RefEntity* ref_ent = pair2.first;
+ ref_ent_list.append( ref_ent );
+ }
+ }
+
+ //uniquify the lists...then append them to the CGMEvent's vector
+ ref_ent_list.uniquify_unordered();
+ tb_list.uniquify_unordered();
+
+ int i;
+ for(i=ref_ent_list.size(); i--; )
+ port_event.RefEnts.push_back( ref_ent_list.get_and_step() );
+ for(i=tb_list.size(); i--; )
+ port_event.TopologyBridges.push_back( tb_list.get_and_step() );
+
+ GeometryQueryTool::instance()->history().add_port_event( port_event );
+}
+
+
+void AcisHistory::add_ENTITY( ENTITY *entity )
+{
+ all_ents.push_back( entity );
+}
+
+void AcisHistory::remove_attributes()
+{
+ int i;
+ for( i=0; i<all_ents.size(); i++ )
+ {
+ ATTRIB_HISTORY *att = ATTRIB_HISTORY::get_history_attrib( all_ents[i], false );
+ if( att )
+ att->lose();
+ }
+}
+
+/*
+void AcisHistory::collect_events_and_find_resultant_uniqueids( int source_id,
+ DLIList<AcisEvent*> &events,
+ DLIList<int> &result_unique_ids )
+{
+ //get an AcisEvent w/ 'entity' in 'other_entities' list
+ std::vector<AcisEvent>::iterator iter;
+ bool found_entity = false;
+ for(iter=eventList.begin(); iter != eventList.end(); iter++ )
+ {
+ AcisEvent *tmp_event = &(*iter);
+
+ //ignore events that are already in the list
+ if( events.is_in_list( tmp_event ) )
+ continue;
+
+ //search 'entities' list
+ if( tmp_event->eventType == SUBDIVISION ||
+ tmp_event->eventType == ABSORPTION ||
+ tmp_event->eventType == COPY )
+ {
+ int k;
+ for(k=0; k<tmp_event->entities.size(); k++ )
+ {
+ if( source_id == tmp_event->entities[k] )
+ {
+ found_entity = true;
+ //we found the ENTITY...now get ents in 'entities' list
+ //and look for them
+ events.append( tmp_event );
+ int i;
+ for( i=0; i<tmp_event->other_entities.size(); i++ )
+ collect_events_and_find_resultant_uniqueids( tmp_event->other_entities[i],
+ events, result_unique_ids );
+ }
+ }
+ }
+ else if( tmp_event->eventType == GEOMETRY_CHANGED )
+ {
+ if( source_id == tmp_event->entities[0] )
+ {
+ events.append( tmp_event );
+ collect_events_and_find_resultant_uniqueids( tmp_event->entities[0],
+ events, result_unique_ids);
+ }
+ }
+ }
+
+ //so you can't go any further, traversing the events...see if this one is in
+ //the results list...if so, append it
+ if( false == found_entity )
+ {
+ if( resultUniqueIds.find( source_id ) != resultUniqueIds.end() )
+ result_unique_ids.append( source_id );
+ }
+} */
+
+
+/*
+void AcisHistory::collect_events_and_find_original_uniqueids( int source_id,
+ DLIList<AcisEvent*> &events,
+ DLIList<int> &original_unique_ids)
+{
+
+ //get an AcisEvent w/ 'entity' in 'other_entities' list
+ std::vector<AcisEvent>::iterator iter;
+ bool found_entity = false;
+ for(iter=eventList.begin(); iter != eventList.end(); iter++ )
+ {
+ AcisEvent *tmp_event = &(*iter);
+
+ //ignore events that are already in the list
+ if( events.is_in_list( tmp_event ) )
+ continue;
+
+ //search 'other_entities' list
+ if( tmp_event->eventType == SUBDIVISION ||
+ tmp_event->eventType == ABSORPTION ||
+ tmp_event->eventType == COPY )
+ {
+ int k;
+ for(k=0; k<tmp_event->other_entities.size(); k++ )
+ {
+ if( source_id == tmp_event->other_entities[k] )
+ {
+ found_entity = true;
+ //we found the ENTITY...now get ents in 'entities' list
+ //and look for them
+ events.append( tmp_event );
+ int i;
+ for( i=0; i<tmp_event->entities.size(); i++ )
+ collect_events_and_find_original_uniqueids( tmp_event->entities[i], events, original_unique_ids );
+ }
+ }
+ }
+ else if( tmp_event->eventType == GEOMETRY_CHANGED )
+ {
+ if( source_id == tmp_event->entities[0] )
+ {
+ events.append( tmp_event );
+ collect_events_and_find_original_uniqueids( tmp_event->entities[0], events, original_unique_ids );
+ }
+ }
+ }
+
+ if( false == found_entity )
+ original_unique_ids.append( source_id );
+} */
+
+
+/*
+void AcisHistory::map_back_to_ref_entity( TopologyBridge *topology_bridge,
+ RefEntity *ref_entity,
+ AcisHistory::EventType event_type )
+{
+
+ ENTITY *entity = AcisQueryEngine::instance()->get_ENTITY_of_entity( topology_bridge );
+
+ ATTRIB_HISTORY *tmp_attrib = ATTRIB_HISTORY::get_history_attrib( entity );
+ if( !tmp_attrib )
+ return;
+
+ int source_id = tmp_attrib->get_unique_id();
+
+ DLIList<AcisEvent*> events;
+ DLIList<int> original_unique_ids;
+
+ //starting from the result ENTITY, work your waying up the events,
+ // to the original ENTITY
+ collect_events_and_find_original_uniqueids( source_id, events, original_unique_ids );
+
+ //PRINT_INFO("source entity = %p ", entity );
+
+ //PRINT_INFO("target_ents = ");
+ int i;
+ //for( i=original_ents.size(); i--; )
+ // PRINT_INFO("%p ", original_ents.get_and_step() );
+ //PRINT_INFO("\n");
+
+
+ EventType my_event_type = NO_EVENT;
+ DLIList<RefEntity*> original_ref_ents;
+
+ //from the supposed original ENTITY,
+ //find the corresponding RefEntity in refentity_ENTITY_multimap
+ for( i=original_unique_ids.size(); i--; )
+ {
+ int original_id = original_unique_ids.get_and_step();
+
+ std::multimap<RefEntity*, int>::iterator iter = refentity_uniqueid_multimap.begin();
+ for( ; iter != refentity_uniqueid_multimap.end(); iter++ )
+ {
+ int tmp_id = (*iter).second;
+ if( original_id == tmp_id )
+ {
+ //determine what type of event you have
+ int j;
+ for( j=events.size(); j--; )
+ {
+ AcisEvent *event = events.get_and_step();
+
+ //ignore copy events for now
+ if( event->eventType != COPY &&
+ event->eventType != NO_EVENT )
+ {
+
+ //split events take priority over
+ if( event->eventType > my_event_type )
+ my_event_type = event->eventType;
+ }
+ }
+ RefEntity *original_ref_ent = (*iter).first;
+ original_ref_ents.append( original_ref_ent );
+ }
+ }
+ }
+
+ if( my_event_type != NO_EVENT )
+ {
+ PRINT_INFO("Event type = %s RefEntity = %s %d Result ENTITY = %p\n",
+ event_names[my_event_type], original_ref_ents.get()->class_name(),
+ original_ref_ents.get()->id(), entity );
+
+ CGMEvent tmp_event;
+ tmp_event.eventType = my_event_type;
+ for( i=original_ref_ents.size(); i--; )
+ tmp_event.RefEnts.push_back( original_ref_ents.get_and_step() );
+
+ tmp_event.TopologyBridges.push_back( topology_bridge );
+
+ cgmEventList.push_back( tmp_event );
+ }
+
+}*/
+
+/*Here's a brief description of how the history is created in the
+ * Acis port:
+ * 1. Create an AcisHistory object.
+ *
+ * 2. Create a RefEnity to ENTITY multimap in the AcisHistory object:
+ * TopologyBridges are given to the port for modification. From
+ * the TopologyBridges, get all associated parent and child TopologyBridges.
+ * From each TopologyBridge, get a) the corresponding RefEntity
+ * and b) the corresponding ENTITY(s). Put them in 'refentity_ENTITY_multimap',
+ * where the RefEntity is the key and the ENTITY(s) is the data.
+ *
+ * 3. Attach an attrib_history attribute to every Acis ENTITY.
+ *
+ * 4. Acis preforms the operation(s), making callbacks into the
+ * attrib_history's overloaded functions. Within these functions, AcisEvents are
+ * created and added to the AcisHistory object's event list.
+ *
+ * 5. Once the operation has ended and TopologyBridges have been added
+ * to the new ENTITYs, get all ENTITYs off the resulting BODYs and add them
+ * to the AcisHistory's 'resultENTITY's' list.
+ *
+ * 6. Remove (ignore) any SUBDIVISION events that don't result in multiple
+ * ENTITIYs in the result BODY.
+ *
+ * 7. For each TopologyBridge, trace your way back through the AcisEvents until
+ * you can't go any further. With this 'leaf' entity, try to find a corresponding
+ * RefEntity in the 'refentity_ENTITY_multimap'.
+ *
+ * 8. If you found a corresponding RefEntity, create a CGMEvent.
+ *
+ * 9. Consolidate CGMEvents of type SUBIDIVISION and ABSORPTION.
+ *
+ */
+
+
+
Copied: cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisHistory.hpp (from rev 3491, cgm/branches/cubit/geom/ACIS_SRC/AcisHistory.hpp)
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisHistory.hpp (rev 0)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisHistory.hpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -0,0 +1,125 @@
+
+
+#ifndef AcisHistory_hpp
+#define AcisHistory_hpp
+
+#include <map>
+#include <vector>
+#include <set>
+#include <list>
+#include "DLIList.hpp"
+#include "TopologyBridge.hpp"
+#include "CGMHistory.hpp"
+
+class RefEntity;
+class ENTITY;
+class ENTITY_LIST;
+
+class AcisHistory
+{
+ public:
+ AcisHistory();
+ ~AcisHistory();
+
+ /*
+ enum EventType
+ {
+ NO_EVENT,
+
+ // An entity is copied from another
+ // you may also get this when an unmerge happens in cgm
+ // this is a supplemental event such that other events completely
+ // describe the topology changes, but this event specifies where the
+ // copy occurred
+ COPY,
+
+ // The geometry of an entity is changed such that it might have been
+ // stretched, warped or other such changes where the topology may be the
+ // same. If child entities changed, they'll have their own event.
+ GEOMETRY_CHANGED,
+
+ // An entity is subdivided into multiple entities
+ // this is a supplemental event such that other events completely
+ // describe the topology changes, but this event specifies where the
+ // subdivision occurred
+ SUBDIVISION,
+
+ CUT,
+
+ // Multiple entities are absorbed into one entity
+ // this is a supplemental event such that other events completely
+ // describe the topology changes, but this event specifies where the
+ // absorption occurred
+ ABSORPTION,
+
+ // Multiple entities modified by a combination of subdivision and
+ // absorption, and intermediate entities don't exist by the time
+ // this history object is given to someone
+ // this is a supplemental event such that other events completely
+ // describe the topology changes, but this event specifies where the
+ // subdivision/absorption occurred
+ SUBDIVISION_ABSORPTION
+
+ }; */
+
+ //Event is a record of a change that occurred during an operation
+ struct AcisEvent
+ {
+ // the type of event this is
+ CGMHistory::EventType eventType;
+
+ // the entities this event applies to
+ std::vector<int> entities;
+
+ // extra data associated with event
+ std::vector<int> other_entities;
+ };
+
+ struct CGMEvent
+ {
+ // the type of event this is
+ CGMHistory::EventType eventType;
+
+ // the entities this event applies to
+ std::vector<RefEntity*> RefEnts;
+
+ // extra data associated with event
+ std::vector<TopologyBridge*> TopologyBridges;
+ };
+
+ // add an event to this history
+ void add_event( const AcisEvent &event );
+
+ // add a RefEntity, ENTITY pair
+ void add_refentity_tracking_id_pair( RefEntity *ref_ent, int tracking_id );
+ void add_to_tracking_ids_tb_map( std::set<int> &tracking_ids, TopologyBridge *tb );
+
+ void collect_relevant_pairs( std::set<int> &seed_set,
+ std::vector< std::pair< std::set<int>, TopologyBridge*> > &found_pairs );
+
+ int generate_next_tracking_id();
+
+ void print();
+
+ void create_cgm_history_objects();
+
+ void create_port_event( CGMHistory::EventType event_type,
+ std::vector< std::pair< std::set<int>, TopologyBridge*> > &found_pairs );
+
+ void add_ENTITY( ENTITY *ent );
+ void remove_attributes();
+
+ bool highLevelCopying;
+
+ private:
+ // the list of events
+ std::vector<AcisEvent> eventList;
+ std::vector< std::pair<RefEntity*, int> > refentity_tracking_id_map;
+ std::list< std::pair< std::set<int>, TopologyBridge* > > tracking_ids_to_tb_map;
+ std::vector<CGMEvent> cgmEventList;
+ int trackingId;
+ std::vector<ENTITY*> all_ents;
+};
+
+#endif
+
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisModifyEngine.cpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisModifyEngine.cpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisModifyEngine.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -19,22 +19,6 @@
// ********** END STANDARD INCLUDES **********
// ********** BEGIN ACIS INCLUDES **********
-#if CUBIT_ACIS_VERSION < 1100
-#include "kernel/acis.hxx"
-#include "kernel/kernutil/version/version.hxx"
-#include "operator/kernapi/api/operapi.hxx"
-#include "boolean/kernapi/api/boolapi.hxx"
-#include "constrct/kernapi/api/cstrapi.hxx"
-#include "constrct/sg_husk/utils/utils.hxx"
-#include "cover/kernapi/api/coverapi.hxx"
-#include "euler/kernapi/api/eulerapi.hxx"
-#include "intersct/kernapi/api/intrapi.hxx"
-#include "sbool/kernapi/api/sboolapi.hxx"
-#include "kernel/kernutil/law/generic_graph.hxx"
-#include "ct_husk/api/ctapi.hxx"
-#include "ct_husk/classes/cell.hxx"
-#include "boolean/sg_husk/sanity/err_ent.hxx"
-#else
#include "acis.hxx"
#include "version.hxx"
#include "operapi.hxx"
@@ -53,47 +37,11 @@
#include "acistype.hxx"
#include "entity_simplify.hxx"
#include "esplit.hxx"
-#endif
-
-#if CUBIT_ACIS_VERSION >= 800
-#if CUBIT_ACIS_VERSION < 1100
-#include "kernel/kernapi/api/acis_options.hxx"
-#else
+#include "ent_err_info.hxx"
+#include "stchapi.hxx"
+#include "err_info.hxx"
#include "acis_options.hxx"
-#endif
-#endif
-#if CUBIT_ACIS_VERSION < 1100
-#include "kernel/kernapi/api/api.hxx"
-#include "kernel/kernapi/api/kernapi.hxx"
-#include "sweep/kernapi/api/sweepapi.hxx"
-#include "intersct/sg_husk/query/ptentrel.hxx"
-#include "kernel/kerndata/geometry/getbox.hxx"
-#include "kernel/kerndata/data/debug.hxx"
-#include "kernel/kerndata/data/entity.hxx"
-#include "kernel/kerndata/data/datamsc.hxx"
-#include "kernel/kernapi/api/api.err"
-#include "kernel/kerndata/attrib/attrib.hxx"
-#include "kernel/kerndata/geom/pcurve.hxx"
-#include "kernel/kerndata/geom/point.hxx"
-#include "kernel/kerndata/geom/allcurve.hxx"
-#include "kernel/kerndata/geom/allsurf.hxx"
-#include "kernel/kerndata/geom/plane.hxx"
-#include "kernel/kerndata/geom/cone.hxx"
-#include "kernel/kerndata/geom/sphere.hxx"
-#include "kernel/kerndata/geom/torus.hxx"
-#include "kernel/kerndata/geom/spline.hxx"
-#include "kernel/kerndata/geom/transfrm.hxx"
-#include "kernel/kerndata/geom/surface.hxx"
-#include "kernel/kerndata/geometry/geometry.hxx"
-#include "intersct/kerndata/geometry/geomutil.hxx"
-#include "kernel/kerndata/lists/lists.hxx"
-#include "kernel/kerngeom/surface/surdef.hxx"
-#include "kernel/kerngeom/surface/allsfdef.hxx"
-#include "kernel/kerngeom/curve/curdef.hxx"
-#include "constrct/kernwire/sweeping/sweeping.hxx"
-#include "shl_husk/api/shl_api.hxx"
-#else
#include "api.hxx"
#include "kernapi.hxx"
#include "sweepapi.hxx"
@@ -125,45 +73,7 @@
#include "sweeping.hxx"
#include "shl_api.hxx"
#include "warp_api.hxx"
-#endif
-#if CUBIT_ACIS_VERSION < 800
-#include "sweep/kernwire/sweeping/piershee.hxx"
-#endif
-
-
-#if CUBIT_ACIS_VERSION < 1100
-#include "kernel/kernutil/tensor/tensor.hxx"
-#include "kernel/kerndata/top/alltop.hxx"
-#include "kernel/kerndata/top/wire.hxx"
-#include "kernel/kerndata/transent/transent.hxx"
-#include "faceter/api/af_api.hxx"
-#include "kernel/sg_husk/query/q_wire.hxx"
-#include "intersct/sg_husk/query/sgquery.hxx"
-#include "kernel/kernint/d3_chk/chk_stat.hxx"
-#include "intersct/kernint/d3_chk/chk.hxx"
-#include "kernel/sg_husk/api/sgapi.err"
-#include "faceter/meshmgr/ppm.hxx"
-#include "faceter/meshmgr/ppmface.hxx"
-#include "kernel/kerndata/savres/fileinfo.hxx"
-#include "kernel/spline/bs3_crv/sp3crtn.hxx"
-#include "kernel/spline/api/spl_api.hxx"
-#include "intersct/spline/bs3_crv/bs3cutil.hxx"
-#include "kernel/spline/bs2_crv/sp2crtn.hxx"
-#include "ga_husk/api/ga_api.hxx"
-#include "kernel/sg_husk/sweep/swp_spl.hxx"
-#include "kernel/geomhusk/copyent.hxx"
-#include "kernel/kerndata/geom/cnstruct.hxx"
-#include "skin/kernapi/api/skinapi.hxx"
-#include "offset/kernapi/api/ofstapi.hxx"
-#include "kernel/kernutil/law/law.hxx"
-#include "kernel/geomhusk/wire_qry.hxx"
-#include "kernel/kernint/intcucu/intcucu.hxx"
-#include "kernel/geomhusk/entwray.hxx"
-#include "constrct/geomhusk/wire_utl.hxx"
-#include "intersct/sg_husk/query/sgquertn.hxx"
-#include "kernel/kerndata/top/body.hxx"
-#else
#include "tensor.hxx"
#include "alltop.hxx"
#include "wire.hxx"
@@ -173,7 +83,6 @@
#include "sgquery.hxx"
#include "chk_stat.hxx"
#include "chk.hxx"
-//#include "sgapi.err"
#include "ppm.hxx"
#include "ppmface.hxx"
#include "fileinfo.hxx"
@@ -194,30 +103,13 @@
#include "wire_utl.hxx"
#include "sgquertn.hxx"
#include "body.hxx"
-#endif
+#include "mprop.hxx"
+#include "surextnd.hxx"
#ifdef ACIS_HEALER
-#if CUBIT_ACIS_VERSION < 1100
-#include "healhusk/heal_api/heal_api.hxx"
-#else
#include "heal_api.hxx"
#endif
-#endif
-#if CUBIT_ACIS_VERSION < 1100
-#include "kernel/geomhusk/getowner.hxx"
-#include "baseutil/vector/vector.hxx"
-#include "baseutil/vector/unitvec.hxx"
-#include "baseutil/vector/position.hxx"
-#include "baseutil/vector/transf.hxx"
-#include "baseutil/vector/box.hxx"
-#include "baseutil/errorsys/errmsg.hxx"
-#include "baseutil/logical.h"
-#include "baseutil/debug/module.hxx"
-#include "baseutil/option/option.hxx"
-#include "sweep/sg_husk/sweep/swp_opts.hxx"
-#include "kernel/geomhusk/getowner.hxx"
-#else
#include "getowner.hxx"
#include "vector.hxx"
#include "unitvec.hxx"
@@ -230,40 +122,28 @@
#include "option.hxx"
#include "swp_opts.hxx"
#include "getowner.hxx"
-#endif
+#include "stitch_progress_info.hxx"
+#include "skin_opts.hxx"
+#include "lop_opts.hxx"
+#include "lop_api.hxx"
+
#ifdef ACIS_IGES_TRANSLATOR
-#if CUBIT_ACIS_VERSION < 1100
- #include "igeshusk/igs_api/routines.hxx"
-#else
-#include "acisiges_api.hxx"
+//#include "acisiges_api.hxx"
#endif
+
+#ifdef ACIS_STEP_TRANSLATOR
+//#include "acisstep_api.hxx"
#endif
+
#ifdef ACIS_PROE_TRANSLATOR
#include "proe/proehusk/api/proeapi.hxx"
#endif
#ifdef ACIS_LOCAL_OPS
-#if CUBIT_ACIS_VERSION < 1100
-#include "rem_husk/api/rem_api.hxx"
-#else
#include "rem_api.hxx"
#endif
-#endif
-#ifdef ACIS_STEP_TRANSLATOR
-#if CUBIT_ACIS_VERSION < 1100
- #include "stephusk/include/acis_inc.hxx"
- #include "stephusk/include/stpapi.hxx"
- #include "stephusk/util/apiinit.hxx"
- #include "stephusk/stepwrit/api/apiwrite.hxx"
- #include "stephusk/stepread/api/apiread.hxx"
- #include "stephusk/util/stphead.hxx"
- #include "stephusk/util/stp_res.hxx"
-#else
-#include "acisstep_api.hxx"
-#endif
-#endif
// ********** END ACIS INCLUDES **********
@@ -291,6 +171,7 @@
#include "GeometryQueryTool.hpp"
#include "GeometryModifyTool.hpp"
+#include "AcisTopologyTool.hpp"
#include "AcisQueryEngine.hpp"
#include "AcisModifyEngine.hpp"
#include "AcisHealerTool.hpp"
@@ -298,6 +179,7 @@
#include "AcisSurfaceTool.hpp"
#include "AcisFacetManager.hpp"
#include "AcisEdgeTool.hpp"
+#include "AcisHistory.hpp"
#include "DoubleListItem.hpp"
@@ -310,6 +192,7 @@
#include "SurfaceOverlapTool.hpp"
#include "GeometryUtil.hpp"
#include "RefEntityFactory.hpp"
+#include "CGMHistory.hpp"
#include "DLIList.hpp"
@@ -320,9 +203,11 @@
#include "Body.hpp"
#include "attrib_snl_simple.hpp"
+#include "attrib_history.hpp"
// still need this for vertex-id-rearranging junk
#include "RefVertex.hpp"
+#include "RefFace.hpp"
// include the DagDrawingTool header FOR DEBUGGING PURPOSES
#include "DagDrawingTool.hpp"
@@ -330,9 +215,12 @@
// including the AcisDrawTool for debugging
#include "AcisDrawTool.hpp"
#include "GfxDebug.hpp"
+#include "GfxPreview.hpp"
AcisModifyEngine* AcisModifyEngine::instance_ = 0;
+int stitch_process_callback( stitch_progress_info *progress_info );
+
AcisModifyEngine::~AcisModifyEngine()
{
api_terminate_booleans();
@@ -591,6 +479,9 @@
{
BODY* new_BODY = make_planar_quad_BODY( p1, p2, p3, p4 );
+ if(!new_BODY)
+ return NULL;
+
// Build a VGI Body (i.e, the entire VGI structure) from this
// ACIS BODY.
BodySM *this_bodysm = AcisQueryEngine::instance()->populate_topology_bridges(new_BODY);
@@ -609,12 +500,22 @@
// Creation Date : 10/24/96
//-------------------------------------------------------------------------
-BodySM* AcisModifyEngine::copy_body ( BodySM* OSMEPtr) const
+BodySM* AcisModifyEngine::copy_body ( BodySM* body_sm ) const
{
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ history_object.highLevelCopying = true;
+ DLIList<TopologyBridge*> my_bridges(1);
+ TopologyBridge *tb = CAST_TO( body_sm, TopologyBridge );
+ my_bridges.append( tb );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
// Make sure that we have a valid pointer
- assert(OSMEPtr != NULL) ;
+ assert(body_sm != NULL) ;
- BodyACIS* bodyACISPtr = CAST_TO(OSMEPtr, BodyACIS) ;
+ BodyACIS* bodyACISPtr = CAST_TO(body_sm, BodyACIS) ;
// Make sure that we have a valid BodyACIS
assert(bodyACISPtr != NULL) ;
@@ -627,7 +528,15 @@
// Build a VGI Body and return it.
BodySM *this_bodysm = AcisQueryEngine::instance()->populate_topology_bridges(new_BODY_ptr);
- return this_bodysm;
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<BodySM*> new_bodies(1);
+ new_bodies.append( this_bodysm );
+ AcisModifyEngine::instance()->stop_tracking_history( new_bodies, history_object );
+ }
+
+ return this_bodysm;
}
CubitStatus AcisModifyEngine::imprint_BODYs (BODY* body1_ptr,
@@ -790,7 +699,8 @@
*/
// Also make sure that any healing attributes are removed from it
#ifdef ACIS_HEALER
- AcisHealerTool::instance()->end_BODY_for_healing( new_body_ptr );
+ if (new_body_ptr)
+ AcisHealerTool::instance()->end_BODY_for_healing( new_body_ptr );
#endif
return new_body_ptr;
}
@@ -1363,6 +1273,60 @@
}
//=============================================================================
+// Function : tweak_bend
+// Member Type: PUBLIC
+// Description: Bend solid bodies based on a bend radius and angle
+// Author : Sam Showman
+// Date : 06/23/08
+//=============================================================================
+CubitStatus AcisModifyEngine::tweak_bend(DLIList<BodySM*> &bend_bodies,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitVector& neutral_root,
+ CubitVector& bend_axis,
+ CubitVector& bend_direction,
+ double radius,
+ double angle,
+ DLIList<CubitVector*> bend_regions,
+ double width,
+ CubitBoolean center_bend,
+ int num_points,
+ CubitBoolean keep_old_body,
+ CubitBoolean preview ) const
+{
+
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( bend_bodies, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
+ CubitStatus status = AcisTweakTool::instance()->tweak_bend(
+ bend_bodies,
+ new_bodysm_list,
+ neutral_root,
+ bend_axis,
+ bend_direction,
+ radius,
+ angle,
+ bend_regions,
+ width,
+ center_bend,
+ num_points,
+ keep_old_body,
+ preview);
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ if( status )
+ AcisModifyEngine::instance()->stop_tracking_history( new_bodysm_list, history_object );
+ }
+
+ return status;
+}
+
+//=============================================================================
// Function : tweak_chamfer
// Member Type: PUBLIC
// Description: Chamfer curves on solid bodies. The left and right offsets are
@@ -1379,8 +1343,24 @@
CubitBoolean keep_old_body,
CubitBoolean preview )
{
- return AcisTweakTool::instance()->tweak_chamfer( curve_list, left_offset,
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( curve_list, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
+ CubitStatus status = AcisTweakTool::instance()->tweak_chamfer( curve_list, left_offset,
new_bodysm_list, right_offset, keep_old_body, preview );
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ if( status )
+ AcisModifyEngine::instance()->stop_tracking_history( new_bodysm_list, history_object );
+ }
+
+ return status;
}
//=============================================================================
@@ -1406,9 +1386,25 @@
CubitBoolean keep_old_body,
CubitBoolean preview )
{
- return AcisTweakTool::instance()->tweak_chamfer( ref_vertex_list, offset1,
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( ref_vertex_list, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
+ CubitStatus status = AcisTweakTool::instance()->tweak_chamfer( ref_vertex_list, offset1,
new_bodysm_list, edge1, offset2, edge2, offset3, edge3, keep_old_body,
preview );
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ if( status )
+ AcisModifyEngine::instance()->stop_tracking_history( new_bodysm_list, history_object );
+ }
+
+ return status;
}
//=============================================================================
@@ -1425,8 +1421,24 @@
CubitBoolean keep_old_body,
CubitBoolean preview )
{
- return AcisTweakTool::instance()->tweak_fillet( curve_list, radius,
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( curve_list, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
+ CubitStatus status = AcisTweakTool::instance()->tweak_fillet( curve_list, radius,
new_bodysm_list, keep_old_body, preview );
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ if( status )
+ AcisModifyEngine::instance()->stop_tracking_history( new_bodysm_list, history_object );
+ }
+
+ return status;
}
//=============================================================================
@@ -1445,8 +1457,29 @@
CubitBoolean keep_old_body,
CubitBoolean preview )
{
- return AcisTweakTool::instance()->tweak_fillet( curve_ptr, start_radius,
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges(1);
+ TopologyBridge *tb = CAST_TO( curve_ptr, TopologyBridge );
+ my_bridges.append( tb );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
+ CubitStatus status = AcisTweakTool::instance()->tweak_fillet( curve_ptr, start_radius,
end_radius, new_bodysm_ptr, keep_old_body, preview );
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ if( status )
+ {
+ DLIList<BodySM*> new_bodies(1);
+ new_bodies.append( new_bodysm_ptr );
+ AcisModifyEngine::instance()->stop_tracking_history( new_bodies, history_object );
+ }
+ }
+
+ return status;
}
//=============================================================================
@@ -1464,8 +1497,24 @@
CubitBoolean keep_old_body,
CubitBoolean preview )
{
- return AcisTweakTool::instance()->tweak_fillet( ref_vertex_list, radius,
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( ref_vertex_list, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
+ CubitStatus status = AcisTweakTool::instance()->tweak_fillet( ref_vertex_list, radius,
new_bodysm_list, keep_old_body, preview );
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ if( status )
+ AcisModifyEngine::instance()->stop_tracking_history( new_bodysm_list, history_object );
+ }
+
+ return status;
}
//=============================================================================
@@ -1481,8 +1530,24 @@
CubitBoolean keep_old_body,
CubitBoolean preview ) const
{
- return AcisTweakTool::instance()->tweak_move( surface_list, delta,
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( surface_list, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
+ CubitStatus status = AcisTweakTool::instance()->tweak_move( surface_list, delta,
new_bodysm_list, keep_old_body, preview );
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ if( status )
+ AcisModifyEngine::instance()->stop_tracking_history( new_bodysm_list, history_object );
+ }
+
+ return status;
}
//=============================================================================
@@ -1498,8 +1563,24 @@
CubitBoolean keep_old_body,
CubitBoolean preview ) const
{
- return AcisTweakTool::instance()->tweak_move( curve_list, delta,
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( curve_list, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
+ CubitStatus status = AcisTweakTool::instance()->tweak_move( curve_list, delta,
new_bodysm_list, keep_old_body, preview );
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ if( status )
+ AcisModifyEngine::instance()->stop_tracking_history( new_bodysm_list, history_object );
+ }
+
+ return status;
}
//=============================================================================
@@ -1512,12 +1593,31 @@
//=============================================================================
CubitStatus AcisModifyEngine::tweak_offset( DLIList<Surface*> &surface_list,
double offset_distance,
+ DLIList<Surface*> *add_surface_list_ptr,
+ DLIList<double> *add_offset_list_ptr,
DLIList<BodySM*> &new_bodysm_list,
CubitBoolean keep_old_body,
CubitBoolean preview ) const
{
- return AcisTweakTool::instance()->tweak_offset( surface_list,
- offset_distance, new_bodysm_list, keep_old_body, preview );
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( surface_list, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
+ CubitStatus status = AcisTweakTool::instance()->tweak_offset( surface_list,
+ offset_distance, add_surface_list_ptr, add_offset_list_ptr, new_bodysm_list,
+ keep_old_body, preview );
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ if( status )
+ AcisModifyEngine::instance()->stop_tracking_history( new_bodysm_list, history_object );
+ }
+
+ return status;
}
//=============================================================================
@@ -1530,12 +1630,31 @@
//=============================================================================
CubitStatus AcisModifyEngine::tweak_offset( DLIList<Curve*> &curve_list,
double offset_distance,
+ DLIList<Curve*> *add_curve_list_ptr,
+ DLIList<double> *add_offset_list_ptr,
DLIList<BodySM*> &new_bodysm_list,
CubitBoolean keep_old_body,
CubitBoolean preview ) const
{
- return AcisTweakTool::instance()->tweak_offset( curve_list, offset_distance,
- new_bodysm_list, keep_old_body, preview );
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( curve_list, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
+ CubitStatus status = AcisTweakTool::instance()->tweak_offset( curve_list, offset_distance,
+ add_curve_list_ptr, add_offset_list_ptr, new_bodysm_list, keep_old_body,
+ preview );
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ if( status )
+ AcisModifyEngine::instance()->stop_tracking_history( new_bodysm_list, history_object );
+ }
+
+ return status;
}
//=============================================================================
@@ -1549,12 +1668,27 @@
CubitStatus AcisModifyEngine::tweak_remove( DLIList<Surface*> &ref_face_list,
DLIList<BodySM*> &new_bodysm_list,
CubitBoolean extend_adjoining,
- CubitBoolean keep_surface,
CubitBoolean keep_old_body,
CubitBoolean preview ) const
{
- return AcisTweakTool::instance()->tweak_remove( ref_face_list,
- new_bodysm_list, extend_adjoining, keep_surface, keep_old_body, preview );
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( ref_face_list, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
+ CubitStatus status = AcisTweakTool::instance()->tweak_remove( ref_face_list,
+ new_bodysm_list, extend_adjoining, keep_old_body, preview );
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ if( status )
+ AcisModifyEngine::instance()->stop_tracking_history( new_bodysm_list, history_object );
+ }
+
+ return status;
}
//================================================================================
@@ -1568,8 +1702,24 @@
CubitBoolean keep_old_body,
CubitBoolean preview ) const
{
- return AcisTweakTool::instance()->tweak_remove( curve_list, new_bodysm_list,
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( curve_list, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
+ CubitStatus status = AcisTweakTool::instance()->tweak_remove( curve_list, new_bodysm_list,
keep_old_body, preview );
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ if( status )
+ AcisModifyEngine::instance()->stop_tracking_history( new_bodysm_list, history_object );
+ }
+
+ return status;
}
//=============================================================================
@@ -1583,12 +1733,30 @@
CubitStatus AcisModifyEngine::tweak_target( DLIList<Surface*> &surface_list,
DLIList<Surface*> &target_face_list,
DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean extend_flg,
+ CubitPlane *limit_plane,
CubitBoolean reverse_flg,
CubitBoolean keep_old_body,
CubitBoolean preview ) const
{
- return AcisTweakTool::instance()->tweak_target( surface_list, target_face_list,
- new_bodysm_list, reverse_flg, keep_old_body, preview );
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( surface_list, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
+ CubitStatus status = AcisTweakTool::instance()->tweak_target( surface_list, target_face_list,
+ new_bodysm_list, extend_flg, limit_plane, reverse_flg, keep_old_body, preview );
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ if( status )
+ AcisModifyEngine::instance()->stop_tracking_history( new_bodysm_list, history_object );
+ }
+
+ return status;
}
//=============================================================================
@@ -1603,12 +1771,32 @@
AcisModifyEngine::tweak_target( DLIList<Curve*> &curve_list,
DLIList<Surface*> &target_surf_list,
DLIList<BodySM*> &new_body_list,
+ CubitBoolean extend_flg,
+ CubitPlane *limit_plane,
CubitBoolean reverse_flg,
CubitBoolean keep_old_bodies,
- CubitBoolean preview ) const
+ CubitBoolean preview,
+ double max_area_increase /*= 0%*/ ) const
{
- return AcisTweakTool::instance()->tweak_target( curve_list, target_surf_list,
- new_body_list, reverse_flg, keep_old_bodies, preview );
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( curve_list, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
+ CubitStatus status = AcisTweakTool::instance()->tweak_target( curve_list, target_surf_list,
+ new_body_list, extend_flg, limit_plane, reverse_flg, keep_old_bodies, preview,
+ max_area_increase );
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ if( status )
+ AcisModifyEngine::instance()->stop_tracking_history( new_body_list, history_object );
+ }
+
+ return status;
}
//=============================================================================
@@ -1625,12 +1813,75 @@
AcisModifyEngine::tweak_target( DLIList<Curve*> &curve_list,
DLIList<Curve*> &target_curve_list,
DLIList<BodySM*> &new_body_list,
+ CubitBoolean extend_flg,
+ CubitPlane *limit_plane,
CubitBoolean reverse_flg,
CubitBoolean keep_old_bodies,
+ CubitBoolean preview,
+ double max_area_increase /*= 0*/ ) const
+{
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( curve_list, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
+ CubitStatus status = AcisTweakTool::instance()->tweak_target( curve_list, target_curve_list,
+ new_body_list, extend_flg, limit_plane, reverse_flg, keep_old_bodies, preview, max_area_increase );
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ if( status )
+ AcisModifyEngine::instance()->stop_tracking_history( new_body_list, history_object );
+ }
+
+ return status;
+}
+
+//=============================================================================
+// Function : tweak_target
+// Member Type: PUBLIC
+// Description: Tweak specified point of a sheet body to a given location. The
+// given point must be part of a planar surface or surfaces
+// attached to linear curves only. The user specified which of
+// those surfaces to actually modify. The given location will be
+// projected to be on the given planar surface(s) before being
+// used - this projected location must be the same on all surfaces.
+// Author : Steve Storm
+// Date : 09/09/08
+//=============================================================================
+CubitStatus
+AcisModifyEngine::tweak_target( Point *point_ptr,
+ DLIList<Surface*> &modify_surface_list,
+ CubitVector &target_loc,
+ BodySM *&new_bodysm_ptr,
+ CubitBoolean keep_old_body,
CubitBoolean preview ) const
{
- return AcisTweakTool::instance()->tweak_target( curve_list, target_curve_list,
- new_body_list, reverse_flg, keep_old_bodies, preview );
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( modify_surface_list, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
+ CubitStatus status = AcisTweakTool::instance()->tweak_target( point_ptr,
+ modify_surface_list, target_loc, new_bodysm_ptr, keep_old_body, preview );
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ if( status )
+ {
+ DLIList<BodySM*> new_body_list(1);
+ new_body_list.append( new_bodysm_ptr );
+ AcisModifyEngine::instance()->stop_tracking_history( new_body_list, history_object );
+ }
+ }
+
+ return status;
}
//================================================================================
@@ -1663,12 +1914,33 @@
// Author : Tyronne Lim
// Date : 08/18/03
//================================================================================
-CubitStatus AcisModifyEngine::create_offset_surface( Surface* ref_face_ptr, BodySM*& new_body, double offset_distance ) const
+CubitStatus AcisModifyEngine::create_offset_surface( Surface* surf_ptr,
+ BodySM*& new_body,
+ double offset_distance ) const
{
- return AcisSurfaceTool::instance()->create_offset_surface( ref_face_ptr, new_body, offset_distance );
+ return AcisSurfaceTool::instance()->create_offset_surface( surf_ptr, new_body,
+ offset_distance );
}
//================================================================================
+// Description: Creates an offset sheet.
+// Author : Steve Storm
+// Date : 05/04/08
+//================================================================================
+CubitStatus
+AcisModifyEngine::create_offset_sheet( DLIList<Surface*> &surface_list,
+ double offset_distance,
+ DLIList<Surface*> *add_surface_list_ptr,
+ DLIList<double> *add_offset_list_ptr,
+ DLIList<BodySM*> &new_body_list,
+ CubitBoolean preview ) const
+{
+ return AcisTweakTool::instance()->make_offset_sheet( surface_list,
+ offset_distance, add_surface_list_ptr, add_offset_list_ptr, new_body_list,
+ preview );
+}
+
+//================================================================================
// Description: Creates an offset body.
// Author : Tyronne Lim
// Date : 08/18/03
@@ -1683,9 +1955,10 @@
// Author : Tyronne Lim
// Date : 08/18/03
//================================================================================
-CubitStatus AcisModifyEngine::create_skin_surface( DLIList<Curve*>& curves, BodySM*& new_body ) const
+CubitStatus AcisModifyEngine::create_skin_surface( DLIList<Curve*>& curves, BodySM*& new_body,
+ DLIList<Curve*>& guides) const
{
- return AcisSurfaceTool::instance()->create_skin_surface( curves, new_body );
+ return AcisSurfaceTool::instance()->create_skin_surface( curves, new_body, guides );
}
//================================================================================
@@ -1733,6 +2006,13 @@
return AcisSurfaceTool::instance()->create_surface( vec_list, new_body, ref_face_ptr, project_points );
}
+
+CubitStatus AcisModifyEngine::create_surface( DLIList<Point*>& points,
+ BodySM *&new_body ) const
+{
+ return AcisSurfaceTool::instance()->create_surface( points, new_body );
+}
+
//================================================================================
// Description: Creates a weld surface.
// Author : Tyronne Lim
@@ -1904,6 +2184,27 @@
return CUBIT_SUCCESS;
}
+CubitBoolean AcisModifyEngine::bodies_interfering( BodySM *body1_ptr,
+ BodySM *body2_ptr) const
+{
+ BODY* BODY1 = AcisQueryEngine::get_BODY(body1_ptr);
+ BODY* BODY2 = AcisQueryEngine::get_BODY(body2_ptr);
+
+ SPAbox spa_box1, spa_box2;
+ spa_box1 = AcisQueryEngine::instance()->bounding_box( BODY1 );
+ spa_box2 = AcisQueryEngine::instance()->bounding_box( BODY2 );
+
+ CubitBox box1 = AcisQueryEngine::bounding_box( spa_box1 );
+ CubitBox box2 = AcisQueryEngine::bounding_box( spa_box2 );
+
+ double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS;
+
+ if( box1.overlap( tolerance, box2 ) )
+ return BODYs_interfering( BODY1, BODY2 );
+
+ return CUBIT_FALSE;
+}
+
//-------------------------------------------------------------------------
// Purpose : Determines whether the 2 input ACIS BODYs overlap
// in any way at all.
@@ -2008,24 +2309,8 @@
}
//stitch together to form a sheet body.
-#if CUBIT_ACIS_VERSION < 1100
-
- for( i=0; i<copied_FACES.count(); i++ )
- {
- result = api_unite((BODY*)copied_FACES[i], master );
- if( !result.ok() )
- {
- PRINT_ERROR("Problems stitching surfaces\n");
- //delete all other surface
- for(; i<copied_FACES.count(); i++)
- api_delent( copied_FACES[i]);
- return CUBIT_FAILURE;
- }
- }
-#else
exact_stitch_options stitch_opts;
result = api_stitch( master, copied_FACES, &stitch_opts );
-#endif
if( !result.ok() )
{
@@ -2581,6 +2866,7 @@
ACIS_sweep_options.set_draft_angle(draft_angle);
ACIS_sweep_options.set_gap_type(draft_type);
ACIS_sweep_options.set_rigid(rigid);
+ ACIS_sweep_options.set_solid(false);
EDGE *copied_EDGE_ptr = NULL;
result = api_edge( EDGE_ptr, copied_EDGE_ptr);
@@ -2852,6 +3138,7 @@
ACIS_sweep_options.set_draft_angle(draft_angle);
ACIS_sweep_options.set_gap_type(draft_type);
ACIS_sweep_options.set_rigid(rigid);
+ ACIS_sweep_options.set_solid(false);
EDGE *copied_EDGE_ptr = NULL;
result = api_edge( EDGE_ptr, copied_EDGE_ptr );
if( !result.ok() )
@@ -3308,6 +3595,7 @@
if(make_solid)
{
ACIS_sweep_options.set_close_to_axis(TRUE);
+ ACIS_sweep_options.set_solid(TRUE);
EDGE* EDGES[1];
EDGES[0] = copied_EDGE_ptr;
BODY* EDGE_BODY_ptr = NULL;
@@ -3322,6 +3610,8 @@
}
else {
+ ACIS_sweep_options.set_solid(FALSE);
+ ACIS_sweep_options.set_two_sided(TRUE);
result = api_sweep_with_options(copied_EDGE_ptr,
ACIS_point, ACIS_axis_unit_vector,
&ACIS_sweep_options, BODYptr);
@@ -4021,10 +4311,15 @@
// body that will result from this. The height of the cone
// is determined by a factor of the model limits currently
// in cubit.
-FACE* AcisModifyEngine::make_type_FACE( CONE *CONE_ptr ) const
+FACE* AcisModifyEngine::make_type_FACE( CONE *CONE_ptr, FACE *FACE_ptr,
+ CubitBox *limit_box ) const
{
//Given this lets create another face that is extended from it.
- CubitBox bounding_box = GeometryQueryTool::instance()->model_bounding_box();
+ CubitBox bounding_box;
+ if( !limit_box )
+ bounding_box = GeometryQueryTool::instance()->model_bounding_box();
+ else
+ bounding_box = *limit_box;
BODY *sheet_body;
CubitBoolean cylinder = CUBIT_FALSE;
@@ -4033,7 +4328,7 @@
double const end_ang = 2*CUBIT_PI;
double cost = CONE_ptr->cosine_angle();
double sint = CONE_ptr->sine_angle();
- if ( sint == 0.0 && fabs(cost) == 1.0 )
+ if( sint == 0.0 && fabs(cost) == 1.0 )
{
//This is a cylinder.
cylinder = CUBIT_TRUE;
@@ -4047,6 +4342,7 @@
CubitVector temp_norm( normal_a.x(), normal_a.y(), normal_a.z());
if ( !cylinder )
{
+ //forces cone direction vector to point towards the apex
if ( sint > 0.0 && cost > 0.0 )
{
sint = -sint;
@@ -4062,23 +4358,42 @@
double theta_rad = acos(cost);
elipse_radius.set(major_a.x(), major_a.y(), major_a.z() );
double old_radius = elipse_radius.length();
- double old_height = old_radius/tan(theta_rad);
-
- //make center of surface along axis, 1/2 height of
- //bounding box of entire model.
+ double old_height = fabs(old_radius/tan(theta_rad));
CubitVector root_vec( root.x(), root.y(), root.z() );
- center_vec = root_vec + (-0.5*height)*temp_norm;
- //calculate new radius
- double new_radius = (old_height+ 0.5*height) * tan (theta_rad );
+ //get the tip of the cone
+ CubitVector cone_point = root_vec + (temp_norm * old_height);
+
+ //----------CENTER--------
+ //get center of bbox of FACE
+ SPAbox bbox = AcisQueryEngine::instance()->bounding_box( FACE_ptr );
+ SPAposition tmp_center = bbox.mid();
+ CubitVector bbox_center( tmp_center.x(), tmp_center.y(), tmp_center.z() );
+ bbox_center -= root_vec;
+ double dot_prod = temp_norm % bbox_center;
+ center_vec = root_vec + temp_norm*dot_prod;
+ center_vec = center_vec - (temp_norm*(height*0.5));
+
+ CubitVector tmp_vec = center_vec - cone_point;
+ if( height > tmp_vec.length() )
+ {
+ //recalculate the center
+ center_vec = cone_point - (temp_norm*(height));
+ }
+
+ //----------RADIUS--------
+ tmp_vec = cone_point - center_vec;
+ double new_radius = tan(theta_rad)*tmp_vec.length();
elipse_radius.normalize();
elipse_radius *= new_radius;
}
else
{
CubitVector root_vec( root.x(), root.y(), root.z() );
- center_vec = .5*height*temp_norm;
- center_vec = root_vec - center_vec;
+ CubitVector cyl_root_to_box_center = bounding_box.center() - root_vec;
+ double dist_to_center_along_cyl_norm = cyl_root_to_box_center % temp_norm;
+ CubitVector new_center = root_vec + dist_to_center_along_cyl_norm * temp_norm;
+ center_vec = new_center - .5*height*temp_norm;
elipse_radius.set(major_a.x(), major_a.y(), major_a.z() );
}
SPAvector const major_axis(elipse_radius.x(), elipse_radius.y(), elipse_radius.z() );
@@ -4270,48 +4585,446 @@
return sheet_body->lump()->shell()->first_face();
}
+
+
+
+#if CUBIT_ACIS_VERSION < 1900
// This function will create a spline face using the info
// from the existing spline. It is actually a face or sheet
-// body that will result from this. The new spher face or sheet
-// will be the grand spline itself, not a section of it.
-FACE* AcisModifyEngine::make_type_FACE( SPLINE *SPLINE_ptr ) const
+// body that will result from this.
+FACE* AcisModifyEngine::make_type_FACE( SPLINE *SPLINE_ptr, CubitBox *limit_box_ptr ) const
{
- BODY *sheet_body;
- PRINT_WARNING("Extents of spline will be only as far as\n"
- "the spline definition, this really isn't an infinite surface.\n");
+ // Need to figure out how far to extend the surface out, in parameter space.
+ // This is a difficult problem... for now, we just try extending out a huge
+ // amount, and trim to the given input box. This is not guaranteed to work;
+ // if we fail, we just return the whole of the given spline surface (i.e.,
+ // extended out to current limits of UV, with 4 EDGEs max).
- //use the geometry to make the spline body.
- surface const *this_spline = &(SPLINE_ptr->equation());
+ // Get UV max/min of surface
+ //SPAbox *bbox = spline_FACE->bound();
+ SPAinterval u_face_range;
+ u_face_range = SPLINE_ptr->equation().param_range_u();
- //make a spline body then move it to the give place.
- outcome result = api_make_spline( *((spline*)this_spline), sheet_body );
- if (!result.ok() || sheet_body == NULL ||
- sheet_body->lump() == NULL ||
- sheet_body->lump()->shell() == NULL ||
- sheet_body->lump()->shell()->first_face() == NULL ||
- sheet_body->lump()->shell()->first_face()->geometry() == NULL )
- {
- PRINT_ERROR("In AcisModifyEngine::make_type_FACE(spline)\n"
- " ACIS api_make_spline function failed.\n\n");
- AcisQueryEngine::instance()->ACIS_API_error (result);
+ double u_min = u_face_range.start_pt();
+ double u_max = u_face_range.end_pt();
+
+ // Debug - check if it is bounded in U
+ if( DEBUG_FLAG(168) && u_face_range.bounded() )
+ {
+ PRINT_INFO( "U lower bound = %f\n", u_min );
+ PRINT_INFO( "U upper bound = %f\n", u_max );
+ }
+ else if( DEBUG_FLAG(168) )
+ PRINT_INFO( "Unbounded in U\n" );
+
+ SPAinterval v_face_range;
+ v_face_range = SPLINE_ptr->equation().param_range_v();
+
+ double v_min = v_face_range.start_pt();
+ double v_max = v_face_range.end_pt();
+
+ // Debug - check if it is bounded in V
+ if( DEBUG_FLAG(168) && v_face_range.bounded() )
+ {
+ PRINT_INFO( "V lower bound = %f\n", v_min );
+ PRINT_INFO( "V upper bound = %f\n", v_max );
+ }
+ else if( DEBUG_FLAG(168) )
+ PRINT_INFO( "Unbounded in V\n" );
+
+ // Try going out a huge amount (I feel really bad doing it this way - we need
+ // to find a better way).
+ double range_u = 1e5*fabs( u_max - u_min );
+ double range_v = 1e5*fabs( v_max - v_min );
+
+ // Setup the expansion each direction
+ SPAinterval u_interval( u_min-range_u, u_max+range_u );
+ SPAinterval v_interval( v_min-range_v, v_max+range_v );
+ SPApar_box pb( u_interval, v_interval );
+
+ double low_u = pb.low().u;
+ double high_u = pb.high().u;
+ double low_v = pb.low().v;
+ double high_v = pb.high().v;
+
+ PRINT_DEBUG_168( " Requested U range = %lf, %lf\n", low_u, high_u );
+ PRINT_DEBUG_168( " Requested V range = %lf, %lf\n", low_v, high_v );
+
+ BODY *new_BODY_ptr = NULL;
+ outcome result;
+
+ // Method
+ // 1. Copy the surface of the FACE
+ // 2. Extend the surface in place using the function extend_face in the
+ // header file surextnd.hxx. This function is not documented. It can
+ // possibly return a smaller parameter range than requested, for example,
+ // if the requested extension was found to be self-intersecting. This is
+ // goodness.
+ // 3. Make a new FACE from the extended surface.
+ // Different method from P_Face_Extend Scheme example from face_scm.cpp
+ //SPAtransf &strans=get_face_trans(spline_FACE);
+ //surface *tsurf = spline_FACE->geometry()->trans_surface(strans);
+ //SPApar_box testbox=extend_surface(*tsurf,pb);
+ //FACE *new_FACE_ptr = make_face_spline( *tsurf, *(curve const*)NULL_REF,
+ // *(curve const*)NULL_REF, *(curve const*)NULL_REF, *(curve const*)NULL_REF,
+ // testbox );
+
+ surface *new_surf_ptr = SPLINE_ptr->equation().make_copy();
+ SPApar_box achieved_parbox = extend_surface( *new_surf_ptr, pb );
+
+ low_u = achieved_parbox.low().u;
+ high_u = achieved_parbox.high().u;
+ low_v = achieved_parbox.low().v;
+ high_v = achieved_parbox.high().v;
+
+ PRINT_DEBUG_168( " Achieved U range = %lf to %lf\n", low_u, high_u );
+ PRINT_DEBUG_168( " Achieved V range = %lf to %lf\n", low_v, high_v );
+
+ CubitBoolean try_alt_method = CUBIT_FALSE;
+ FACE *new_FACE_ptr;
+ result = api_make_face_from_surface( new_surf_ptr, new_FACE_ptr );
+ ACIS_DELETE new_surf_ptr;
+ if( !result.ok() || new_FACE_ptr==NULL )
+ try_alt_method = CUBIT_TRUE;
+ else
+ {
+ // If no EDGEs need to try the alternate method
+ ENTITY_LIST EDGES;
+ api_get_edges( new_FACE_ptr, EDGES );
+ if( EDGES.count() == 0 )
+ {
+ try_alt_method = CUBIT_TRUE;
+ PRINT_DEBUG_168( "Got extended spline with zero edges - trying alternate method\n" );
+ api_delent( new_FACE_ptr );
+ }
+ }
+
+ // If we failed, try making a spline that just fits around the input FACE
+ if( try_alt_method == CUBIT_TRUE )
+ {
+ PRINT_DEBUG_168( "Using api_make_spline to extend spline surface\n" );
+ PRINT_WARNING("Extents of spline will be only as far as\n"
+ "the spline definition, this really isn't an infinite surface.\n");
+
+ // Use the geometry to make the spline body.
+ surface const *this_spline = &(SPLINE_ptr->equation());
+
+ // Make a spline body
+ outcome result = api_make_spline( *((spline*)this_spline), new_BODY_ptr );
+ if (!result.ok() || new_BODY_ptr == NULL ||
+ new_BODY_ptr->lump() == NULL ||
+ new_BODY_ptr->lump()->shell() == NULL ||
+ new_BODY_ptr->lump()->shell()->first_face() == NULL ||
+ new_BODY_ptr->lump()->shell()->first_face()->geometry() == NULL )
+ {
+ AcisQueryEngine::instance()->ACIS_API_error( result );
+ PRINT_ERROR("Unable to extend spline surface\n");
return (FACE *)NULL;
- }
- result = api_body_to_2d( sheet_body );
- if (!result.ok())
- {
- PRINT_ERROR("In AcisModifyEngine::make_type_FACE(spline)\n"
- " ACIS api_body_to_2d function failed.\n\n");
+ }
+ // We fail if we don't have any EDGEs
+ ENTITY_LIST EDGEs;
+ api_get_edges( new_FACE_ptr, EDGEs );
+ if( EDGEs.count() == 0 )
+ {
+ api_delent( new_BODY_ptr );
+ PRINT_ERROR("Couldn't create trimmed surface from extended spline\n");
+ return (FACE *)NULL;
+ }
+ }
+ else
+ {
+ // Convert to sheet BODY
+ FACE *FACE_list[1];
+ FACE_list[0] = new_FACE_ptr;
+ result = api_sheet_from_ff( 1, FACE_list, new_BODY_ptr );
+ if (!result.ok() || new_BODY_ptr == NULL || new_BODY_ptr->lump() == NULL
+ || new_BODY_ptr->lump()->shell() == NULL ||
+ new_BODY_ptr->lump()->shell()->first_face() == NULL )
+ {
+ api_delent( new_FACE_ptr );
AcisQueryEngine::instance()->ACIS_API_error (result);
return (FACE *)NULL;
- }
+ }
+ }
- return sheet_body->lump()->shell()->first_face();
+ // Make double sided
+ result = api_body_to_2d( new_BODY_ptr );
+ if (!result.ok())
+ {
+ api_delent( new_BODY_ptr );
+ AcisQueryEngine::instance()->ACIS_API_error(result);
+ return (FACE *)NULL;
+ }
+
+ // Trim to input bounding box
+ CubitBox cubit_super_box;
+ if( !limit_box_ptr )
+ {
+ cubit_super_box = GeometryQueryTool::instance()->model_bounding_box();
+ cubit_super_box *= 1.1; // Expand out 10%
+ limit_box_ptr = &cubit_super_box;
+ }
+ trim_BODY_to_box( new_BODY_ptr, *limit_box_ptr );
+
+ // Check result
+ if( new_BODY_ptr == NULL )
+ {
+ PRINT_ERROR( "Unable to extend spline surface\n" );
+ return (FACE *)NULL;
+ }
+
+ // Return the FACE
+ return new_BODY_ptr->lump()->shell()->first_face();
}
+#endif
+
+
+FACE* AcisModifyEngine::make_type_FACE( FACE *FACE_ptr, CubitBox *limit_box_ptr ) const
+{
+
+ CubitBox bounding_box;
+ if( !limit_box_ptr )
+ {
+ bounding_box = GeometryQueryTool::instance()->model_bounding_box();
+ bounding_box *= 1.1;
+ limit_box_ptr = &bounding_box;
+ }
+
+ FACE *face_list[1];
+ BODY *sheet_body = NULL;
+ face_list[0] = FACE_ptr;
+
+ // Make a FACE from copy_FACE.
+ outcome rc = api_sheet_from_ff(1, face_list, sheet_body);
+
+ if( rc.ok() )
+ {
+ ENTITY_LIST EDGES;
+ api_get_edges( sheet_body, EDGES );
+ double offset = limit_box_ptr->diagonal().length() * 0.5;
+
+ SPAposition bb_low( limit_box_ptr->min_x(),
+ limit_box_ptr->min_y(),
+ limit_box_ptr->min_z() );
+ SPAposition bb_high( limit_box_ptr->max_x(),
+ limit_box_ptr->max_y(),
+ limit_box_ptr->max_z() );
+
+ lop_options local_options;
+ rc = api_extend_sheetbody( EDGES, offset, bb_low, bb_high, &local_options );
+
+ if (!rc.ok())
+ sheet_body = NULL;
+ }
+
+ if( sheet_body )
+ {
+ rc = api_body_to_2d( sheet_body );
+ trim_BODY_to_box( sheet_body, *limit_box_ptr );
+ }
+
+ if( sheet_body )
+ return sheet_body->lump()->shell()->first_face();
+ else //do it the old, dangerous way.
+ {
+ //can only handle spline geometry
+ SURFACE *SURFACE_ptr = FACE_ptr->geometry();
+ int type = SURFACE_ptr->identity();
+
+ if( type != SPLINE_TYPE )
+ return NULL;
+
+ SPLINE *SPLINE_ptr = (SPLINE*)SURFACE_ptr;
+
+ // This is a difficult problem... for now, we just try extending out a huge
+ // amount, and trim to the given input box. This is not guaranteed to work;
+ // if we fail, we just return the whole of the given spline surface (i.e.,
+ // extended out to current limits of UV, with 4 EDGEs max).
+
+ // Get UV max/min of surface
+ //SPAbox *bbox = spline_FACE->bound();
+ SPAinterval u_face_range;
+ u_face_range = SPLINE_ptr->equation().param_range_u();
+
+ double u_min = u_face_range.start_pt();
+ double u_max = u_face_range.end_pt();
+
+ // Debug - check if it is bounded in U
+ if( DEBUG_FLAG(168) && u_face_range.bounded() )
+ {
+ PRINT_INFO( "U lower bound = %f\n", u_min );
+ PRINT_INFO( "U upper bound = %f\n", u_max );
+ }
+ else if( DEBUG_FLAG(168) )
+ PRINT_INFO( "Unbounded in U\n" );
+
+ SPAinterval v_face_range;
+ v_face_range = SPLINE_ptr->equation().param_range_v();
+
+ double v_min = v_face_range.start_pt();
+ double v_max = v_face_range.end_pt();
+
+ // Debug - check if it is bounded in V
+ if( DEBUG_FLAG(168) && v_face_range.bounded() )
+ {
+ PRINT_INFO( "V lower bound = %f\n", v_min );
+ PRINT_INFO( "V upper bound = %f\n", v_max );
+ }
+ else if( DEBUG_FLAG(168) )
+ PRINT_INFO( "Unbounded in V\n" );
+
+ // Try going out a huge amount (I feel really bad doing it this way - we need
+ // to find a better way).
+ double range_u = 1e5*fabs( u_max - u_min );
+ double range_v = 1e5*fabs( v_max - v_min );
+
+ // Setup the expansion each direction
+ SPAinterval u_interval( u_min-range_u, u_max+range_u );
+ SPAinterval v_interval( v_min-range_v, v_max+range_v );
+ SPApar_box pb( u_interval, v_interval );
+
+ double low_u = pb.low().u;
+ double high_u = pb.high().u;
+ double low_v = pb.low().v;
+ double high_v = pb.high().v;
+
+ PRINT_DEBUG_168( " Requested U range = %lf, %lf\n", low_u, high_u );
+ PRINT_DEBUG_168( " Requested V range = %lf, %lf\n", low_v, high_v );
+
+ BODY *new_BODY_ptr = NULL;
+ outcome result;
+
+ // Method
+ // 1. Copy the surface of the FACE
+ // 2. Extend the surface in place using the function extend_face in the
+ // header file surextnd.hxx. This function is not documented. It can
+ // possibly return a smaller parameter range than requested, for example,
+ // if the requested extension was found to be self-intersecting. This is
+ // goodness.
+ // 3. Make a new FACE from the extended surface.
+ // Different method from P_Face_Extend Scheme example from face_scm.cpp
+ //SPAtransf &strans=get_face_trans(spline_FACE);
+ //surface *tsurf = spline_FACE->geometry()->trans_surface(strans);
+ //SPApar_box testbox=extend_surface(*tsurf,pb);
+ //FACE *new_FACE_ptr = make_face_spline( *tsurf, *(curve const*)NULL_REF,
+ // *(curve const*)NULL_REF, *(curve const*)NULL_REF, *(curve const*)NULL_REF,
+ // testbox );
+
+ surface *new_surf_ptr = SPLINE_ptr->equation().make_copy();
+ SPApar_box achieved_parbox = extend_surface( *new_surf_ptr, pb );
+
+ low_u = achieved_parbox.low().u;
+ high_u = achieved_parbox.high().u;
+ low_v = achieved_parbox.low().v;
+ high_v = achieved_parbox.high().v;
+
+ PRINT_DEBUG_168( " Achieved U range = %lf to %lf\n", low_u, high_u );
+ PRINT_DEBUG_168( " Achieved V range = %lf to %lf\n", low_v, high_v );
+
+ CubitBoolean try_alt_method = CUBIT_FALSE;
+ FACE *new_FACE_ptr;
+ result = api_make_face_from_surface( new_surf_ptr, new_FACE_ptr );
+ ACIS_DELETE new_surf_ptr;
+ if( !result.ok() || new_FACE_ptr==NULL )
+ try_alt_method = CUBIT_TRUE;
+ else
+ {
+ // If no EDGEs need to try the alternate method
+ ENTITY_LIST EDGES;
+ api_get_edges( new_FACE_ptr, EDGES );
+ if( EDGES.count() == 0 )
+ {
+ try_alt_method = CUBIT_TRUE;
+ PRINT_DEBUG_168( "Got extended spline with zero edges - trying alternate method\n" );
+ api_delent( new_FACE_ptr );
+ }
+ }
+
+ // If we failed, try making a spline that just fits around the input FACE
+ if( try_alt_method == CUBIT_TRUE )
+ {
+ PRINT_DEBUG_168( "Using api_make_spline to extend spline surface\n" );
+ PRINT_WARNING("Extents of spline will be only as far as\n"
+ "the spline definition, this really isn't an infinite surface.\n");
+
+ // Use the geometry to make the spline body.
+ surface const *this_spline = &(SPLINE_ptr->equation());
+
+ // Make a spline body
+ outcome result = api_make_spline( *((spline*)this_spline), new_BODY_ptr );
+ if (!result.ok() || new_BODY_ptr == NULL ||
+ new_BODY_ptr->lump() == NULL ||
+ new_BODY_ptr->lump()->shell() == NULL ||
+ new_BODY_ptr->lump()->shell()->first_face() == NULL ||
+ new_BODY_ptr->lump()->shell()->first_face()->geometry() == NULL )
+ {
+ AcisQueryEngine::instance()->ACIS_API_error( result );
+ PRINT_ERROR("Unable to extend spline surface\n");
+ return (FACE *)NULL;
+ }
+ // We fail if we don't have any EDGEs
+ ENTITY_LIST EDGEs;
+ api_get_edges( new_FACE_ptr, EDGEs );
+ if( EDGEs.count() == 0 )
+ {
+ api_delent( new_BODY_ptr );
+ PRINT_ERROR("Couldn't create trimmed surface from extended spline\n");
+ return (FACE *)NULL;
+ }
+ }
+ else
+ {
+ // Convert to sheet BODY
+ FACE *FACE_list[1];
+ FACE_list[0] = new_FACE_ptr;
+ result = api_sheet_from_ff( 1, FACE_list, new_BODY_ptr );
+ if (!result.ok() || new_BODY_ptr == NULL || new_BODY_ptr->lump() == NULL
+ || new_BODY_ptr->lump()->shell() == NULL ||
+ new_BODY_ptr->lump()->shell()->first_face() == NULL )
+ {
+ api_delent( new_FACE_ptr );
+ AcisQueryEngine::instance()->ACIS_API_error (result);
+ return (FACE *)NULL;
+ }
+ }
+
+ // Make double sided
+ result = api_body_to_2d( new_BODY_ptr );
+ if (!result.ok())
+ {
+ api_delent( new_BODY_ptr );
+ AcisQueryEngine::instance()->ACIS_API_error(result);
+ return (FACE *)NULL;
+ }
+
+ // Trim to input bounding box
+ CubitBox cubit_super_box;
+ if( !limit_box_ptr )
+ {
+ cubit_super_box = GeometryQueryTool::instance()->model_bounding_box();
+ cubit_super_box *= 1.1; // Expand out 10%
+ limit_box_ptr = &cubit_super_box;
+ }
+ trim_BODY_to_box( new_BODY_ptr, *limit_box_ptr );
+
+ // Check result
+ if( new_BODY_ptr == NULL )
+ {
+ PRINT_ERROR( "Unable to extend spline surface\n" );
+ return (FACE *)NULL;
+ }
+
+ // Return the FACE
+ return new_BODY_ptr->lump()->shell()->first_face();
+ }
+}
+
// This function will create a plane face using the info
// from the existing plane. It is actually a face or sheet
-// body that will result from this. The new spher face or sheet
+// body that will result from this. The new face or sheet
// will be the grand plane itself, not a section of it.
-FACE* AcisModifyEngine::make_type_FACE( PLANE *PLANE_ptr ) const
+FACE* AcisModifyEngine::make_type_FACE( PLANE *PLANE_ptr,
+ CubitBox *limit_box ) const
{
//first lets find 3 points.
SPAposition point_1, point_2, point_3;
@@ -4322,8 +5035,14 @@
PLANE_ptr->equation().eval( pos_2, point_2 );
PLANE_ptr->equation().eval( pos_3, point_3 );
- CubitBox cubit_super_box = GeometryQueryTool::instance()->model_bounding_box();
- SPAbox super_box = AcisQueryEngine::bounding_box(cubit_super_box);
+ SPAbox super_box;
+ if( !limit_box )
+ {
+ CubitBox cubit_super_box = GeometryQueryTool::instance()->model_bounding_box();
+ super_box = AcisQueryEngine::bounding_box(cubit_super_box);
+ }
+ else
+ super_box = AcisQueryEngine::bounding_box( *limit_box );
CubitVector vec_1( point_1.x(), point_1.y(), point_1.z() );
CubitVector vec_2( point_2.x(), point_2.y(), point_2.z() );
@@ -4355,7 +5074,8 @@
// Creation Date : 10/6/97
//-------------------------------------------------------------------------
FACE* AcisModifyEngine::make_FACE(FACE* FACE_ptr,
- CubitBoolean extended_from) const
+ CubitBoolean extended_from,
+ CubitBox *limit_box_ptr ) const
{
if (FACE_ptr == NULL)
return NULL;
@@ -4367,15 +5087,21 @@
SURFACE *SURFACE_ptr = FACE_ptr->geometry();
int type = SURFACE_ptr->identity();
if (type == CONE_TYPE)
- return make_type_FACE((CONE*)SURFACE_ptr);
+ return make_type_FACE((CONE*)SURFACE_ptr, FACE_ptr, limit_box_ptr);
else if (type == SPHERE_TYPE)
return make_type_FACE((SPHERE*)SURFACE_ptr);
else if (type == TORUS_TYPE)
return make_type_FACE((TORUS*)SURFACE_ptr);
else if (type == SPLINE_TYPE)
- return make_type_FACE((SPLINE*)SURFACE_ptr);
+ {
+#if CUBIT_ACIS_VERSION < 1900
+ return make_type_FACE((SPLINE*)SURFACE_ptr, limit_box_ptr);
+#else
+ return make_type_FACE( FACE_ptr, limit_box_ptr );
+#endif
+ }
else if (type == PLANE_TYPE)
- return make_type_FACE((PLANE*)SURFACE_ptr);
+ return make_type_FACE((PLANE*)SURFACE_ptr, limit_box_ptr);
else
return NULL;
}
@@ -4420,6 +5146,41 @@
}
//-------------------------------------------------------------------------
+// Purpose : This function creates a sheet body by extending out a
+// set of surfaces. The sheet body is a double sided face
+// with no volume.
+//
+// Special Notes :
+//
+// Creator : Steve Storm
+//
+// Creation Date : 2/27/08
+//-------------------------------------------------------------------------
+BODY*
+AcisModifyEngine::make_extended_sheet( DLIList<FACE*> &FACE_list,
+ CubitBox *clip_box_ptr,
+ bool suppress_errors /* = false */) const
+{
+ CubitBox clip_box;
+ if( !clip_box_ptr )
+ {
+ // Setup a default clipping box - 10% larger than Cubit model
+ clip_box = GeometryQueryTool::instance()->model_bounding_box();
+ clip_box *= 1.1;
+ clip_box_ptr = &clip_box;
+ }
+
+ BODY *ext_BODY_ptr;
+ if( AcisTweakTool::instance()->make_extended_sheet( FACE_list, ext_BODY_ptr,
+ clip_box_ptr, suppress_errors ) == CUBIT_FAILURE )
+ {
+ return NULL;
+ }
+
+ return ext_BODY_ptr;
+}
+
+//-------------------------------------------------------------------------
// Purpose : Creates an ACIS FACE, given the type of surface geometry
// and an ordered list of bounding EDGEs.
//
@@ -4780,66 +5541,66 @@
// This will reactivate all the RefEntities that need to be kept.
mark_owners_deactivated_flag(FACE_ptr, CUBIT_FALSE, CUBIT_TRUE);
- // Where coincident vertices were merged by ACIS,
- // make sure the lower ID is used.
- input_EDGE_list.reset();
-
+ DLIList<VERTEX*> old_vertices;
for (i = 0; i < input_EDGE_list.size(); i++)
{
- // get the copy and original EDGE
- EDGE* cur_EDGE_new = EDGEs[i];
- EDGE* cur_EDGE_old = input_EDGE_list.get_and_step();
+ ENTITY_LIST tmp_list;
+ api_get_vertices( input_EDGE_list.get_and_step(), tmp_list );
+
+ old_vertices.append_unique( (VERTEX*)tmp_list[0] );
- // If the original start RefVertex is deactivated,
- // see if we need to swap it with the replacement RefVertex
- VERTEX* cur_VERT_new = cur_EDGE_new->start();
- VERTEX* cur_VERT_old = cur_EDGE_old->start();
+ if( tmp_list.count() > 1 )
+ old_vertices.append_unique( (VERTEX*)tmp_list[1] );
+ }
+
+ //the following while loop attempts to put the lowest ids
+ //from the original vertices of the edges onto the new
+ //vertices of the surface. It's done spatially.
+ ENTITY_LIST new_vertices;
+ api_get_vertices( wire_BODY, new_vertices );
+ ENTITY *tmp_ent = NULL;
+ while( (tmp_ent=new_vertices.next())!=NULL )
+ {
+ VERTEX *new_VERTEX = (VERTEX*)tmp_ent;
- for (int j = 2; j--; )
+ //find another vertex in 'old_vertices' that has same xyz
+ //position as new_vertex
+ SPAposition pos = new_VERTEX->geometry()->coords();
+ CubitVector new_pos( pos.x(), pos.y(), pos.z() );
+
+ for( i=old_vertices.size(); i--; )
{
- RefVertex* ref_vert_old =
- CAST_TO(ATTRIB_CUBIT_OWNER::get_topology_entity(cur_VERT_old),
- RefVertex);
+ VERTEX *old_VERTEX = old_vertices.get_and_step();
+ pos = old_VERTEX->geometry()->coords();
+ CubitVector old_pos( pos.x(), pos.y(), pos.z() );
- AcisBridge* bridge = ATTRIB_CUBIT_OWNER::cubit_owner(cur_VERT_old);
-
- if (ref_vert_old && bridge_deactivated(bridge))
+ if( new_pos.distance_between( old_pos ) < 0.0001 )
{
- RefVertex* ref_vert_new =
- CAST_TO(ATTRIB_CUBIT_OWNER::get_topology_entity(cur_VERT_new),
- RefVertex);
- if (ref_vert_new && ref_vert_old->id() < ref_vert_new->id())
- {
- int id_old = ref_vert_old->id();
- int id_new = ref_vert_new->id();
- ref_vert_old->set_id(0);
- ref_vert_new->set_id(id_old);
- ref_vert_old->set_id(id_new);
- }
- }
+ RefVertex* ref_vert_old = CAST_TO(ATTRIB_CUBIT_OWNER::
+ get_topology_entity(old_VERTEX),RefVertex);
+ AcisBridge* bridge = ATTRIB_CUBIT_OWNER::cubit_owner(old_VERTEX);
-/*
- PointACIS* ref_vert_old =
- CAST_TO(ATTRIB_CUBIT_OWNER::cubit_owner(cur_VERT_old),PointACIS);
-
- if (ref_vert_old && bridge_deactivated(ref_vert_old) && ref_vert_old->owner())
- {
- //RefVertex* ref_vert_new =
- // CAST_TO(ATTRIB_CUBIT_OWNER::get_topology_entity(cur_VERT_new),
- // RefVertex);
- PointACIS* ref_vert_new =
- CAST_TO(ATTRIB_CUBIT_OWNER::cubit_owner(cur_VERT_new),PointACIS);
- if (ref_vert_new)
+ if (ref_vert_old && bridge_deactivated(bridge))
{
- ref_vert_old->owner()->swap_bridge(ref_vert_old,ref_vert_new,true);
+ RefVertex* ref_vert_new =
+ CAST_TO(ATTRIB_CUBIT_OWNER::get_topology_entity(new_VERTEX),
+ RefVertex);
+ if (ref_vert_new && ref_vert_old->id() < ref_vert_new->id())
+ {
+ int id_old = ref_vert_old->id();
+ int id_new = ref_vert_new->id();
+ ref_vert_old->set_id(0);
+ ref_vert_new->set_id(id_old);
+ ref_vert_old->set_id(id_new);
+ }
}
}
-*/
- cur_VERT_new = cur_EDGE_new->end();
- cur_VERT_old = cur_EDGE_old->end();
}
}
+
+
+
// Get rid of the stuff we aren't using. This will delete the RefVertices
// that correspond to the VERTEXes deleted by ACIS in api_make_ewire.
// We also delete the original ACIS EDGEs since they are no longer
@@ -5447,6 +6208,7 @@
// Start by going through each LUMP, if LUMPs are being used.
LUMP* start_LUMP = cur_LUMP;
CURVE *geometry = NULL;
+ CURVE *weak_match = NULL;
do
{
PRINT_DEBUG_18( "**New Lump check**\n");
@@ -5460,19 +6222,24 @@
COEDGE* start_COEDGE = cur_WIRE->coedge();
cur_COEDGE = start_COEDGE;
// Check it and loop through the rest
+ COEDGE *last_COEDGE = NULL;
do
{
PRINT_DEBUG_18( " **New CoEdge check**\n");
cur_EDGE = cur_COEDGE->edge();
+ SPAinterval curve_range = cur_EDGE->param_range();
+ if(cur_EDGE->sense() == REVERSED)
+ curve_range.negate();
geometry = cur_EDGE->geometry();
// See if this is close enough to
// the start and end points
if (geometry != NULL)
{
SPAposition new_point;
+ SPAparameter param1, param2;
// Make sure start vertex is on curve
geometry->equation().point_perp(from_VERTEX->geometry()->coords(),
- new_point);
+ new_point, *(SPAparameter*)NULL_REF, param1);
PRINT_DEBUG_18( "\n\tNew Point 1: (%g, %g, %g)\n"
"\t From Vert: (%g, %g, %g)\n",
new_point.x(),
@@ -5486,7 +6253,7 @@
{
// Make sure end vertex is on curve
geometry->equation().point_perp(to_VERTEX->geometry()->coords(),
- new_point);
+ new_point, *(SPAparameter*)NULL_REF, param2);
PRINT_DEBUG_18( "\tNew Point 2: (%g, %g, %g)\n"
"\t To Vert: (%g, %g, %g) \n",
new_point.x(),
@@ -5498,16 +6265,21 @@
if (AcisQueryEngine::instance()->about_spatially_equal(to_VERTEX->geometry()->coords(),
new_point, 1.0))
{
- // You found it!!!
- cur_WIRE = NULL;
- start_LUMP = NULL;
- break;
+ weak_match = geometry;
+ if(curve_range >> param1 && curve_range >> param2)
+ {
+ // You found it!!!
+ cur_WIRE = NULL;
+ start_LUMP = NULL;
+ break;
+ }
}
}
}
+ last_COEDGE = cur_COEDGE;
cur_COEDGE = cur_COEDGE->next();
geometry = NULL; // Make sure you indicate we haven't found geom
- }while (cur_COEDGE != NULL && cur_COEDGE != start_COEDGE);
+ }while (cur_COEDGE != NULL && cur_COEDGE != start_COEDGE && cur_COEDGE != last_COEDGE);
// You break out of this do-while loop when
// a) You find the correct EDGE
// b) There are no more COEDGEs in this WIRE
@@ -5573,6 +6345,9 @@
PRINT_INFO("Exit loop for Other Reason!!!\n");
}
+ if(!geometry && weak_match)
+ geometry = weak_match;
+
// Make sure you found something valid
if ( geometry == NULL )
{
@@ -5780,6 +6555,15 @@
DLIList<BODY*> old_BODY_list;
DLIList<BodySM*> old_BodySM_list;
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges(1);
+ TopologyBridge *tmp_bridge = CAST_TO( bodysms.get(), TopologyBridge );
+ my_bridges.append( tmp_bridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
BodySM* BodySMPtr = bodysms.get_and_step();
BODY* BODYPtr = AcisQueryEngine::get_BODY(BodySMPtr);
old_BodySM_list.append(BodySMPtr);
@@ -5809,10 +6593,9 @@
outcome result = api_boolean_chop_body(tool_BODY, blank_BODY, nonreg,outside_BODY, leftovers_BODY);
if (!result.ok() || blank_BODY == NULL ||
- tool_BODY == NULL || blank_BODY->lump() == NULL )
+ tool_BODY == NULL || blank_BODY->lump() == NULL ||
+ outside_BODY->lump() == NULL )
{
-
-
if( !result.ok() )
{
PRINT_ERROR("In AcisModifyEngine::chop\n");
@@ -5834,6 +6617,17 @@
AcisQueryEngine::instance()->delete_ACIS_BODY(outside_BODY, CUBIT_TRUE);
}
+ if( outside_BODY->lump() == NULL )
+ {
+ PRINT_ERROR("tool body completely encloses blank.\n");
+ if (blank_BODY != NULL)
+ AcisQueryEngine::instance()->delete_ACIS_BODY(blank_BODY, CUBIT_TRUE);
+ if (leftovers_BODY != NULL)
+ AcisQueryEngine::instance()->delete_ACIS_BODY(leftovers_BODY, CUBIT_TRUE);
+ if (outside_BODY != NULL)
+ AcisQueryEngine::instance()->delete_ACIS_BODY(outside_BODY, CUBIT_TRUE);
+ }
+
return CUBIT_FAILURE;
}
@@ -5842,6 +6636,14 @@
BodySM* outsideBody = get_new_Body(old_BodySM_list, old_BODY_list, outside_BODY, keep_old);
outsideBodies.append( outsideBody );
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<BodySM*> new_bodies;
+ new_bodies.append( intersectBody );
+ new_bodies.append( outsideBody );
+ AcisModifyEngine::instance()->stop_tracking_history( new_bodies, history_object );
+ }
+
return CUBIT_SUCCESS;
}
@@ -5857,7 +6659,6 @@
//-------------------------------------------------------------------------
CubitStatus
AcisModifyEngine::flip_normals( DLIList<Surface*>& ref_face_list ) const
-
{
bool delete_attribs =
(GeometryModifyTool::instance()->get_new_ids() != 0);
@@ -5878,21 +6679,20 @@
while( copied_ref_face_list.size() )
{
BODY *copied_BODY_ptr;
-#ifdef BOYD07
- DLIList<SurfaceACIS*> reverse_face_list;
-#endif
DLIList<FACE*> reverse_FACE_list;
if( get_copied_FACES_of_body( copied_ref_face_list, reverse_FACE_list,
copied_BODY_ptr ) == CUBIT_FAILURE )
break;
// Get original Body and BODY
- BodySM *body_ptr = AcisQueryEngine::instance()->get_body_sm_of_ENTITY( copied_BODY_ptr );
+ BodySM *body_ptr = AcisQueryEngine::instance()->
+ get_body_sm_of_ENTITY( copied_BODY_ptr );
BODY *BODY_ptr = AcisQueryEngine::get_BODY(body_ptr);
// Now cleanout the owner attributes from the copied BODY, if required
if( delete_attribs )
- AcisQueryEngine::instance()->remove_cubit_owner_attrib_in_BODY(copied_BODY_ptr);
+ AcisQueryEngine::instance()->
+ remove_cubit_owner_attrib_in_BODY(copied_BODY_ptr);
reverse_FACE_list.reset();
for( i=reverse_FACE_list.size(); i--; )
@@ -5909,18 +6709,7 @@
}
}
- BodySM* new_body_ptr = get_new_Body( body_ptr, BODY_ptr, copied_BODY_ptr, CUBIT_FALSE );
-
- if( new_body_ptr!=NULL && new_body_ptr!=body_ptr )
- {
- PRINT_INFO( "Created new volume\n" );
- }
- else if( new_body_ptr!=NULL && new_body_ptr==body_ptr )
- {
- PRINT_INFO( "Modified volume\n" );
- }
- else
- PRINT_WARNING( "Volume was not modified\n" );
+ get_new_Body( body_ptr, BODY_ptr, copied_BODY_ptr, CUBIT_FALSE );
}
return CUBIT_SUCCESS;
@@ -6130,7 +6919,75 @@
#endif
}
+void AcisModifyEngine::get_possible_invalid_tbs(DLIList<TopologyBridge*> &bridges_in,
+ DLIList<TopologyBridge*> &bridges_out)
+{
+ int i, j;
+ DLIList<ENTITY*> old_ENTITIES;
+ for(j=bridges_in.size(); j--;)
+ {
+ AcisBridge *ab = dynamic_cast<AcisBridge*>(bridges_in.get_and_step());
+ if(ab)
+ {
+ ENTITY *top_ENTITY = ab->ENTITY_ptr();
+ if(top_ENTITY)
+ {
+ ENTITY_LIST ENTITIES;
+ // vertices
+ api_get_vertices( top_ENTITY, ENTITIES);
+ for (i = 0; i < ENTITIES.count(); i++)
+ {
+ ab = ATTRIB_CUBIT_OWNER::cubit_owner(ENTITIES[i]);
+ TopologyBridge *tb = dynamic_cast<TopologyBridge*>(ab);
+ if(tb)
+ {
+ TopologyBridge *tb_owner = dynamic_cast<TopologyBridge*>(tb->owner());
+ if(tb_owner)
+ bridges_out.append(tb_owner);
+ else
+ bridges_out.append(tb);
+ }
+ }
+ ENTITIES.clear();
+
+ // edges
+ api_get_edges( top_ENTITY, ENTITIES);
+ for (i = 0; i < ENTITIES.count(); i++)
+ {
+ ab = ATTRIB_CUBIT_OWNER::cubit_owner(ENTITIES[i]);
+ TopologyBridge *tb = dynamic_cast<TopologyBridge*>(ab);
+ if(tb)
+ {
+ TopologyBridge *tb_owner = dynamic_cast<TopologyBridge*>(tb->owner());
+ if(tb_owner)
+ bridges_out.append(tb_owner);
+ else
+ bridges_out.append(tb);
+ }
+ }
+ ENTITIES.clear();
+ // faces
+ api_get_faces( top_ENTITY, ENTITIES);
+ for (i = 0; i < ENTITIES.count(); i++)
+ {
+ ab = ATTRIB_CUBIT_OWNER::cubit_owner(ENTITIES[i]);
+ TopologyBridge *tb = dynamic_cast<TopologyBridge*>(ab);
+ if(tb)
+ {
+ TopologyBridge *tb_owner = dynamic_cast<TopologyBridge*>(tb->owner());
+ if(tb_owner)
+ bridges_out.append(tb_owner);
+ else
+ bridges_out.append(tb);
+ }
+ }
+ }
+ }
+ }
+ bridges_out.uniquify_ordered();
+}
+
//-------------------------------------------------------------------------
// Purpose : Boolean Operation of a list of Bodies: unite
//
@@ -6142,7 +6999,7 @@
//-------------------------------------------------------------------------
CubitStatus AcisModifyEngine::unite(DLIList<BodySM*> &bodies,
DLIList<BodySM*> &newBodies,
- bool keep_old) const
+ bool keep_old) const
{
// Union all bodies in the bodies list into a single body.
if (bodies.size() <= 1)
@@ -6151,26 +7008,31 @@
return CUBIT_FAILURE;
}
- // Create new acis bodies that are copies of the original acis bodies.
- // If something goes wrong in the unioning, we can then delete our copies
- // and the originals are intact. If everything goes fine, we will delete
- // the originals at that time.
+ // Create new acis bodies that are copies of the original acis bodies.
+ // If something goes wrong in the unioning, we can then delete our copies
+ // and the originals are intact. If everything goes fine, we will delete
+ // the originals at that time.
- // pass in keep_old to the delete_owner_attrib flag; if we're not keeping
- // old bodies, we want to keep the owner attrib, so we can pick up entities
- // that didn't change
- bool delete_attribs =
- (GeometryModifyTool::instance()->get_new_ids() || keep_old);
+ // pass in keep_old to the delete_owner_attrib flag; if we're not keeping
+ // old bodies, we want to keep the owner attrib, so we can pick up entities
+ // that didn't change
+ bool delete_attribs = (GeometryModifyTool::instance()->get_new_ids() || keep_old);
- // check if the boolean operation is regularized or nonregularized
- BOOL_TYPE bool_type = UNION;
- CubitBoolean boolean_regularize = GeometryModifyTool::instance()->boolean_regularize();
+ // check if the boolean operation is regularized or nonregularized
+ BOOL_TYPE bool_type = UNION;
+ CubitBoolean boolean_regularize = GeometryModifyTool::instance()->boolean_regularize();
- if (boolean_regularize == FALSE)
- {
- bool_type = NONREG_UNION;
- }
+ if(boolean_regularize == FALSE)
+ bool_type = NONREG_UNION;
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( bodies, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
DLIList<BODY*> old_BODY_list;
DLIList<BodySM*> old_Body_list;
@@ -6181,9 +7043,7 @@
BODY *master = this->copy_BODY(BODYPtr, delete_attribs);
if (master == NULL)
- {
return CUBIT_FAILURE; // Nothing to clean up at this point.
- }
// Note: one iteration less because we already pulled out one body above
@@ -6200,15 +7060,13 @@
}
- // Do the union of the master and the copy.
+ // Do the union of the master and the copy.
// If this is successful, the result is master and copy will be deleted
// outcome result = api_unite(copy, master);
- // replaced with the api_boolean call in order to do nonregularize boolean operation
+ // replaced with the api_boolean call in order to do nonregularize boolean operation
- outcome result = api_boolean (copy,master,bool_type);
+ outcome result = api_boolean (copy,master,bool_type);
-
-
if (!result.ok() || (master && master->lump() == NULL))
{
// If there are no LUMPs in the resulting BODY, return with a failure
@@ -6228,58 +7086,57 @@
old_Body_list.append(BodyPtr);
old_BODY_list.append(BODYPtr);
}
+
+ //For nonregularized boolean, find all internal surfaces and delete
- //For nonregularized boolean, find all internal surfaces and delete
+ if( bool_type == NONREG_UNION)
+ {
+ outcome result1;
+ // ENTITY_LIST FACES;
+ DLIList<FACE*> FACE_list ;
+ FACE *this_FACE;
+ AcisQueryEngine::instance()->get_FACEs(master,FACE_list);
+ // loop through all faces
+ for( int i = 0; i< FACE_list.size(); i++)
+ {
+ this_FACE = FACE_list.get_and_step();
+ assert( this_FACE != NULL );
+ // Make sure this is a DOUBLE_SIDED FACE
+ if (this_FACE->sides() == DOUBLE_SIDED)
+ {
+ if (this_FACE->cont()==BOTH_INSIDE)
+ {
+ // found internal faces
+ // Now we have the FACE - unhook it from the BODY. Keep track of new
+ // BODIES that are created as this is done.
+ PRINT_INFO( " Unhooking and deleting each internal surface...\n" );
+ BODY *new_BODY_ptr;
+ result1 = api_unhook_face( this_FACE, new_BODY_ptr );
+ if( !result1.ok() )
+ {
+ AcisModifyEngine::instance()->get_acis_query_engine()->ACIS_API_error( result1 );
+ PRINT_ERROR( " Face unhooking during rebuild of volume didn't work\n" );
+ return CUBIT_FAILURE;
+ }
+ AcisQueryEngine::instance()->delete_ACIS_BODY (new_BODY_ptr);
+ }
+ }
+ }
- if ( bool_type == NONREG_UNION)
- {
- outcome result1;
- // ENTITY_LIST FACES;
- DLIList<FACE*> FACE_list ;
- FACE *this_FACE;
- AcisQueryEngine::instance()->get_FACEs(master,FACE_list);
- // loop through all faces
- for( int i = 0; i< FACE_list.size(); i++)
- {
- this_FACE = FACE_list.get_and_step();
- assert( this_FACE != NULL );
- // Make sure this is a DOUBLE_SIDED FACE
- if (this_FACE->sides() == DOUBLE_SIDED)
- {
- if (this_FACE->cont()==BOTH_INSIDE)
- {
- // found internal faces
- // Now we have the FACE - unhook it from the BODY. Keep track of new
- // BODIES that are created as this is done.
- PRINT_INFO( " Unhooking and deleting each internal surface...\n" );
- BODY *new_BODY_ptr;
- result1 = api_unhook_face( this_FACE, new_BODY_ptr );
- if( !result1.ok() )
- {
- AcisModifyEngine::instance()->get_acis_query_engine()->ACIS_API_error( result1 );
- PRINT_ERROR( " Face unhooking during rebuild of volume didn't work\n" );
- return CUBIT_FAILURE;
- }
- AcisQueryEngine::instance()->delete_ACIS_BODY (new_BODY_ptr);
- }
- }
- }
-
- // heal the leftover body
+// heal the leftover body
//
-// PRINT_INFO(" Healing the leftover volume...\n");
-// if( AcisHealerTool::instance()->init_BODY_for_healing( master ) == CUBIT_SUCCESS )
-// {
-// int percent_before, percent_after, number_splines_simplified;
-// if( AcisHealerTool::instance()->heal_BODY( master, percent_before,
-// percent_after, number_splines_simplified ) == CUBIT_FAILURE )
-// PRINT_ERROR( "Error healing the combined volume\n" );
-// else
-// PRINT_INFO( "Successfully healed the combined volume!\n" );
-// AcisHealerTool::instance()->end_BODY_for_healing( master );
-// }
- }
-
+// PRINT_INFO(" Healing the leftover volume...\n");
+// if( AcisHealerTool::instance()->init_BODY_for_healing( master ) == CUBIT_SUCCESS )
+// {
+// int percent_before, percent_after, number_splines_simplified;
+// if( AcisHealerTool::instance()->heal_BODY( master, percent_before,
+// percent_after, number_splines_simplified ) == CUBIT_FAILURE )
+// PRINT_ERROR( "Error healing the combined volume\n" );
+// else
+// PRINT_INFO( "Successfully healed the combined volume!\n" );
+// AcisHealerTool::instance()->end_BODY_for_healing( master );
+// }
+ }
}
AcisQueryEngine::instance()->clear_bounding_box( master );
@@ -6288,6 +7145,9 @@
BodySM *newBodyPtr = get_new_Body(old_Body_list, old_BODY_list, master, keep_old);
newBodies.append( newBodyPtr );
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ AcisModifyEngine::instance()->stop_tracking_history( newBodies, history_object );
+
return CUBIT_SUCCESS;
}
@@ -6304,27 +7164,25 @@
(GeometryModifyTool::instance()->get_new_ids() || keep_old);
// check if the boolean operation is regularized or nonregularized
- BOOL_TYPE bool_type = SUBTRACTION;
- CubitBoolean boolean_regularize = GeometryModifyTool::instance()->boolean_regularize();
+ BOOL_TYPE bool_type = SUBTRACTION;
+ CubitBoolean boolean_regularize = GeometryModifyTool::instance()->boolean_regularize();
- if (boolean_regularize == FALSE)
- {
- bool_type = NONREG_SUBTRACTION;
- }
+ if(boolean_regularize == FALSE)
+ bool_type = NONREG_SUBTRACTION;
int ii;
DLIList<CubitBox*> tool_boxes;
CubitBox tool_box;
-
DLIList<BODY*> tool_BODY_list;
DLIList<BODY*> tool_BODY_list_copy;
// get acis bodies, and copy them
tool_body_list.reset();
- for (ii = tool_body_list.size(); ii > 0; ii--) {
+ for (ii = tool_body_list.size(); ii > 0; ii--)
+ {
CubitBox *temp_box = new CubitBox(
AcisQueryEngine::instance()->bounding_box(tool_body_list.get()));
tool_boxes.append(temp_box);
@@ -6343,6 +7201,13 @@
return CUBIT_FAILURE;
}
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( from_bodies, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
DLIList<BODY*> from_BODY_list;
DLIList<BODY*> from_BODY_list_copy;
@@ -6350,7 +7215,8 @@
// get acis bodies, and copy them
from_bodies.reset();
- for (ii = from_bodies.size(); ii > 0; ii--) {
+ for (ii = from_bodies.size(); ii > 0; ii--)
+ {
BODY *BODYPtr1 = AcisQueryEngine::get_BODY(from_bodies.get_and_step());
from_BODY_list.append(BODYPtr1);
@@ -6365,7 +7231,6 @@
return CUBIT_FAILURE;
}
-
// now, subtract the tool from the list of bodies
tool_BODY_list.reset();
tool_BODY_list_copy.reset();
@@ -6455,55 +7320,54 @@
tool_BODY_list_copy.change_to(tool_BODY_copy);
}
- //For nonregularized boolean, find all internal surfaces and delete
-
+ //For nonregularized boolean, find all internal surfaces and delete
if ( bool_type == NONREG_SUBTRACTION)
{
- outcome result1;
+ outcome result1;
// ENTITY_LIST FACES;
DLIList<FACE*> FACE_list ;
- FACE *this_FACE;
+ FACE *this_FACE;
AcisQueryEngine::instance()->get_FACEs(from_BODY_copy,FACE_list);
- // loop through all faces
- for( int i = 0; i< FACE_list.size(); i++)
- {
- this_FACE = FACE_list.get_and_step();
- assert( this_FACE != NULL );
- // Make sure this is a DOUBLE_SIDED FACE
- if (this_FACE->sides() == DOUBLE_SIDED)
- {
- if (this_FACE->cont()==BOTH_INSIDE)
- {
- // found internal faces
- // Now we have the FACE - unhook it from the BODY. Keep track of new
- // BODIES that are created as this is done.
- PRINT_INFO( " Unhooking and deleting each internal surface...\n" );
- BODY *new_BODY_ptr;
- result1 = api_unhook_face( this_FACE, new_BODY_ptr );
- if( !result1.ok() )
- {
- AcisModifyEngine::instance()->get_acis_query_engine()->ACIS_API_error( result1 );
- PRINT_ERROR( " Face unhooking during rebuild of volume didn't work\n" );
- return CUBIT_FAILURE;
- }
- AcisQueryEngine::instance()->delete_ACIS_BODY (new_BODY_ptr);
- }
- }
- }
+ // loop through all faces
+ for( int i = 0; i< FACE_list.size(); i++)
+ {
+ this_FACE = FACE_list.get_and_step();
+ assert( this_FACE != NULL );
+ // Make sure this is a DOUBLE_SIDED FACE
+ if (this_FACE->sides() == DOUBLE_SIDED)
+ {
+ if (this_FACE->cont()==BOTH_INSIDE)
+ {
+ // found internal faces
+ // Now we have the FACE - unhook it from the BODY. Keep track of new
+ // BODIES that are created as this is done.
+ PRINT_INFO( " Unhooking and deleting each internal surface...\n" );
+ BODY *new_BODY_ptr;
+ result1 = api_unhook_face( this_FACE, new_BODY_ptr );
+ if( !result1.ok() )
+ {
+ AcisModifyEngine::instance()->get_acis_query_engine()->ACIS_API_error( result1 );
+ PRINT_ERROR( " Face unhooking during rebuild of volume didn't work\n" );
+ return CUBIT_FAILURE;
+ }
+ AcisQueryEngine::instance()->delete_ACIS_BODY (new_BODY_ptr);
+ }
+ }
+ }
- // heal the leftover body
+ // heal the leftover body
//
-// PRINT_INFO(" Healing the leftover volume...\n");
-// if( AcisHealerTool::instance()->init_BODY_for_healing( master ) == CUBIT_SUCCESS )
-// {
-// int percent_before, percent_after, number_splines_simplified;
-// if( AcisHealerTool::instance()->heal_BODY( master, percent_before,
-// percent_after, number_splines_simplified ) == CUBIT_FAILURE )
-// PRINT_ERROR( "Error healing the combined volume\n" );
-// else
-// PRINT_INFO( "Successfully healed the combined volume.\n" );
-// AcisHealerTool::instance()->end_BODY_for_healing( master );
-// }
+// PRINT_INFO(" Healing the leftover volume...\n");
+// if( AcisHealerTool::instance()->init_BODY_for_healing( master ) == CUBIT_SUCCESS )
+// {
+// int percent_before, percent_after, number_splines_simplified;
+// if( AcisHealerTool::instance()->heal_BODY( master, percent_before,
+// percent_after, number_splines_simplified ) == CUBIT_FAILURE )
+// PRINT_ERROR( "Error healing the combined volume\n" );
+// else
+// PRINT_INFO( "Successfully healed the combined volume.\n" );
+// AcisHealerTool::instance()->end_BODY_for_healing( master );
+// }
}
// done with this j iteration; write out count, if necessary
@@ -6534,20 +7398,20 @@
from_BODY_list.reset();
from_bodies.reset();
- for (ii = 0; ii< from_BODY_list_copy.size(); ii++)
+ for(ii = 0; ii< from_BODY_list_copy.size(); ii++)
{
- BODY *old_BODY = from_BODY_list.get();
- BODY *new_BODY = from_BODY_list_copy.get();
+ BODY *old_BODY = from_BODY_list.get();
+ BODY *new_BODY = from_BODY_list_copy.get();
- BodySM *new_body = NULL;
- if (old_BODY != new_BODY)
- new_body = get_new_Body(from_bodies.get(), old_BODY, new_BODY, keep_old);
+ BodySM *new_body = NULL;
+ if(old_BODY != new_BODY)
+ new_body = get_new_Body(from_bodies.get(), old_BODY, new_BODY, keep_old);
- if (new_body)
- {
- new_from_bodies.append(new_body);
- from_bodies.change_to(NULL);
- }
+ if (new_body)
+ {
+ new_from_bodies.append(new_body);
+ from_bodies.change_to(NULL);
+ }
// now step all the lists
from_BODY_list.step();
@@ -6559,6 +7423,9 @@
from_bodies.reset();
new_from_bodies.reset();
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ AcisModifyEngine::instance()->stop_tracking_history( new_from_bodies, history_object );
+
for(ii = tool_BODY_list_copy.size(); ii>0; ii--)
AcisQueryEngine::instance()->delete_ACIS_BODY(tool_BODY_list_copy.get_and_step(), CUBIT_TRUE);
@@ -7384,6 +8251,14 @@
if (from_BODY_list.is_in_list(NULL))
return CUBIT_FAILURE;
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( from_body_list, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
// set the free_edges acis option
if ( GeometryModifyTool::get_all_edges_imprint() )
{
@@ -7567,12 +8442,14 @@
}
}
-
PRINT_INFO("Group imprint finished.\n");
// reset the free_edges acis option
api_set_int_option("all_free_edges", FALSE );
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ AcisModifyEngine::instance()->stop_tracking_history( new_from_body_list, history_object );
+
return success;
}
@@ -7604,7 +8481,8 @@
SPAtransf t= get_owner_transf(EDGE_in_ptr);
in_crv = EDGE_in_ptr->geometry()->trans_curve(t);
}
-
+
+ API_BEGIN
if(in_crv && in_srf)
{
// create the curve
@@ -7648,6 +8526,7 @@
// make the edge
new_EDGE= ACIS_NEW EDGE(svert,evert,the_curve,FORWARD,EDGE_cvty_unknown,in_range);
}
+ API_END
if(in_crv)
ACIS_DELETE in_crv;
@@ -7741,8 +8620,22 @@
project_edges(ref_face_list, ref_edge_list_in, ref_edge_list_new);
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> bridges;
+ for( int i=ref_face_list.size(); i--; )
+ bridges.append( ref_face_list.get_and_step()->bodysm() );
+ bridges.uniquify_unordered();
+ AcisModifyEngine::instance()->start_tracking_history( bridges, history_object );
+ }
+
// imprint Surface with curves
- status = imprint(ref_face_list, ref_edge_list_new, new_body_list, keep_old_body );
+ DLIList<TopologyBridge*> temporary_bridges;
+ status = imprint(ref_face_list, ref_edge_list_new, temporary_bridges, new_body_list, keep_old_body );
+ temporary_bridges.uniquify_ordered();
+ while(temporary_bridges.size())
+ delete temporary_bridges.pop();
if (keep_free_edges)
return status;
@@ -7762,6 +8655,15 @@
"due to\n this unsuccessful deletion.\n" );
}
}
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ if( CUBIT_FAILURE == status )
+ AcisModifyEngine::instance()->stop_tracking_history( new_body_list, history_object );
+ else
+ history_object.remove_attributes();
+ }
+
return status;
}
@@ -7789,8 +8691,22 @@
project_edges(ref_face_list, ref_edge_list_in, ref_edge_list_new);
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> bridges;
+ for( int i=ref_face_list.size(); i--; )
+ bridges.append( ref_face_list.get_and_step()->bodysm() );
+ bridges.uniquify_unordered();
+ AcisModifyEngine::instance()->start_tracking_history( bridges, history_object );
+ }
+
// imprint bodies with curves
- status = imprint(body_list,ref_edge_list_new,new_body_list, keep_old_body );
+ DLIList<TopologyBridge*> temporary_bridges;
+ status = imprint(body_list,ref_edge_list_new,new_body_list, temporary_bridges, keep_old_body );
+ temporary_bridges.uniquify_ordered();
+ while(temporary_bridges.size())
+ delete temporary_bridges.pop();
if (keep_free_edges)
return status;
@@ -7810,6 +8726,15 @@
"due to\n this unsuccessful deletion.\n" );
}
}
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ if( CUBIT_FAILURE == status )
+ AcisModifyEngine::instance()->stop_tracking_history( new_body_list, history_object );
+ else
+ history_object.remove_attributes();
+ }
+
return status;
}
@@ -7833,7 +8758,6 @@
bool delete_attribs =
(GeometryModifyTool::instance()->get_new_ids() || keep_old);
-
int ii;
CubitBox tool_box = AcisQueryEngine::instance()->bounding_box(tool_body);
@@ -7843,7 +8767,16 @@
// get acis bodies, and copy them
from_bodies.reset();
- for (ii = from_bodies.size(); ii > 0; ii--) {
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( from_bodies, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
+ for (ii = from_bodies.size(); ii > 0; ii--)
+ {
BODY *BODYPtr1 = AcisQueryEngine::get_BODY(from_bodies.get_and_step());
from_BODY_list.append(BODYPtr1);
BODYPtr1 = this->copy_BODY(BODYPtr1, delete_attribs);
@@ -7858,9 +8791,7 @@
CubitBoolean boolean_regularize = GeometryModifyTool::instance()->boolean_regularize();
if (boolean_regularize == FALSE)
- {
bool_type = NONREG_INTERSECTION;
- }
// now, intersect the tool with the list of bodies
from_BODY_list.reset();
@@ -7870,7 +8801,8 @@
CubitStatus int_stat = CUBIT_SUCCESS;
// intersect the tool body with each body in the list
- for (ii = 1; ii <= from_BODY_list.size(); ii++) {
+ for (ii = 1; ii <= from_BODY_list.size(); ii++)
+ {
BODY *from_BODY = from_BODY_list.get();
BODY *from_BODY_copy = from_BODY_list_copy.get();
BodySM *from_Body = from_bodies.get();
@@ -7878,21 +8810,19 @@
// first, check bounding SPAbox; if they don't intersect, don't do the intersection
- if (from_Body == tool_body) {
+ if (from_Body == tool_body)
PRINT_ERROR("Can't intersect volume with itself.\n");
- }
- else if (tool_box.overlap(SPAresabs, box1)) {
-
- // the bodies overlap; proceed with the intersect
+ else if (tool_box.overlap(SPAresabs, box1))
+ {
+ // the bodies overlap; proceed with the intersect
BODY* tool_BODY = AcisQueryEngine::get_BODY(tool_body);
BODY *tool_BODY_copy = this->copy_BODY(tool_BODY);
+ // Intersect body1 with body2.
+ //outcome result = api_intersect( tool_BODY_copy, from_BODY_copy );
+ outcome result = api_boolean(tool_BODY_copy, from_BODY_copy, bool_type );
- // Intersect body1 with body2.
- //outcome result = api_intersect( tool_BODY_copy, from_BODY_copy );
- outcome result = api_boolean(tool_BODY_copy, from_BODY_copy, bool_type );
-
// We may or may not get an error if the resulting BODY is
// empty
// Also check the result.
@@ -7908,17 +8838,14 @@
//I might need to take this out. Not sure. CDE 10/17/2003
if (tool_BODY_copy != NULL)
- {
AcisQueryEngine::instance()->delete_ACIS_BODY(tool_BODY_copy, CUBIT_TRUE);
- }
}
else
PRINT_ERROR("Intersection operation failed.\n"
" Empty volume created and will be deleted.\n");
+
if (from_BODY_copy != NULL)
- {
AcisQueryEngine::instance()->delete_ACIS_BODY(from_BODY_copy, CUBIT_TRUE);
- }
// we had an error, so put the original body into the copy list
from_BODY_list_copy.change_to(from_BODY);
@@ -7926,52 +8853,52 @@
if ( bool_type == NONREG_INTERSECTION)
{
- outcome result1;
- // ENTITY_LIST FACES;
- DLIList<FACE*> FACE_list ;
- FACE *this_FACE;
- AcisQueryEngine::instance()->get_FACEs(from_BODY_copy,FACE_list);
- // loop through all faces
- for( int i = 0; i< FACE_list.size(); i++)
- {
- this_FACE = FACE_list.get_and_step();
- assert( this_FACE != NULL );
- // Make sure this is a DOUBLE_SIDED FACE
- if (this_FACE->sides() == DOUBLE_SIDED)
- {
- if (this_FACE->cont()==BOTH_INSIDE)
- {
- // found internal faces
- // Now we have the FACE - unhook it from the BODY. Keep track of new
- // BODIES that are created as this is done.
- PRINT_INFO( " Unhooking and deleting each internal surface...\n" );
- BODY *new_BODY_ptr;
- result1 = api_unhook_face( this_FACE, new_BODY_ptr );
- if( !result1.ok() )
- {
- AcisModifyEngine::instance()->get_acis_query_engine()->ACIS_API_error( result1 );
- PRINT_ERROR( " Face unhooking during rebuild of volume didn't work\n" );
- return CUBIT_FAILURE;
- }
- AcisQueryEngine::instance()->delete_ACIS_BODY (new_BODY_ptr);
- }
- }
- }
+ outcome result1;
+ // ENTITY_LIST FACES;
+ DLIList<FACE*> FACE_list ;
+ FACE *this_FACE;
+ AcisQueryEngine::instance()->get_FACEs(from_BODY_copy,FACE_list);
+ // loop through all faces
+ for( int i = 0; i< FACE_list.size(); i++)
+ {
+ this_FACE = FACE_list.get_and_step();
+ assert( this_FACE != NULL );
+ // Make sure this is a DOUBLE_SIDED FACE
+ if (this_FACE->sides() == DOUBLE_SIDED)
+ {
+ if (this_FACE->cont()==BOTH_INSIDE)
+ {
+ // found internal faces
+ // Now we have the FACE - unhook it from the BODY. Keep track of new
+ // BODIES that are created as this is done.
+ PRINT_INFO( " Unhooking and deleting each internal surface...\n" );
+ BODY *new_BODY_ptr;
+ result1 = api_unhook_face( this_FACE, new_BODY_ptr );
+ if( !result1.ok() )
+ {
+ AcisModifyEngine::instance()->get_acis_query_engine()->ACIS_API_error( result1 );
+ PRINT_ERROR( " Face unhooking during rebuild of volume didn't work\n" );
+ return CUBIT_FAILURE;
+ }
+ AcisQueryEngine::instance()->delete_ACIS_BODY (new_BODY_ptr);
+ }
+ }
+ }
- // heal the leftover body
+ // heal the leftover body
//
-// PRINT_INFO(" Healing the leftover volume...\n");
-// if( AcisHealerTool::instance()->init_BODY_for_healing( master ) == CUBIT_SUCCESS )
-// {
-// int percent_before, percent_after, number_splines_simplified;
-// if( AcisHealerTool::instance()->heal_BODY( master, percent_before,
-// percent_after, number_splines_simplified ) == CUBIT_FAILURE )
-// PRINT_ERROR( "Error healing the combined volume\n" );
-// else
-// PRINT_INFO( "Successfully healed the combined volume.\n" );
-// AcisHealerTool::instance()->end_BODY_for_healing( master );
-// }
- }
+// PRINT_INFO(" Healing the leftover volume...\n");
+// if( AcisHealerTool::instance()->init_BODY_for_healing( master ) == CUBIT_SUCCESS )
+// {
+// int percent_before, percent_after, number_splines_simplified;
+// if( AcisHealerTool::instance()->heal_BODY( master, percent_before,
+// percent_after, number_splines_simplified ) == CUBIT_FAILURE )
+// PRINT_ERROR( "Error healing the combined volume\n" );
+// else
+// PRINT_INFO( "Successfully healed the combined volume.\n" );
+// AcisHealerTool::instance()->end_BODY_for_healing( master );
+// }
+ }
// done with this j iteration; write out count, if necessary
// if (from_bodies.size() > 1) {
@@ -7983,7 +8910,8 @@
// }
}
- else {
+ else
+ {
AcisQueryEngine::instance()->delete_ACIS_BODY(from_BODY_copy, CUBIT_TRUE);
from_BODY_list_copy.change_to(from_BODY);
}
@@ -8001,21 +8929,23 @@
from_BODY_list.reset();
from_bodies.reset();
- for (ii = from_BODY_list_copy.size(); ii > 0; ii--) {
-
+ for (ii = from_BODY_list_copy.size(); ii > 0; ii--)
+ {
BODY *old_BODY = from_BODY_list.get();
BODY *new_BODY = from_BODY_list_copy.get();
BodySM *new_body = NULL;
if (old_BODY != new_BODY)
new_body = get_new_Body(from_bodies.get(), old_BODY, new_BODY, keep_old);
- else if (!keep_old && int_stat == CUBIT_SUCCESS) {
+ else if (!keep_old && int_stat == CUBIT_SUCCESS)
+ {
//GeometryQueryTool::instance()->delete_Body(from_bodies.get());
AcisQueryEngine::instance()->delete_solid_model_entities(from_bodies.get());
from_bodies.change_to(NULL);
}
- if (new_body) {
+ if (new_body)
+ {
new_from_bodies.append(new_body);
from_bodies.change_to(NULL);
}
@@ -8030,6 +8960,9 @@
from_bodies.reset();
new_from_bodies.reset();
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ AcisModifyEngine::instance()->stop_tracking_history( new_from_bodies, history_object );
+
if (int_stat == CUBIT_SUCCESS && !keep_old )
//GeometryQueryTool::instance()->delete_Body(tool_body);
AcisQueryEngine::instance()->delete_solid_model_entities(tool_body);
@@ -9621,6 +10554,237 @@
return sweep_status;
}
+//-------------------------------------------------------------------------
+// Purpose : Perform a face sweep operation to a target body
+//
+// Special Notes :
+//
+// Creator : Derek Quam
+//
+// Creation Date : 12/01/08
+//-------------------------------------------------------------------------
+CubitStatus AcisModifyEngine::sweep_to_body(Surface *source_surface,
+ BodySM *target_body,
+ CubitVector distance,
+ DLIList<BodySM*> &new_bodies) const
+{
+ // Declare local variables
+ BodyACIS *target_acis;
+ sweep_options *opts = new sweep_options();
+ outcome result;
+ BODY *new_body;
+
+ // Make sure we have an ACIS body
+ target_acis = dynamic_cast<BodyACIS*>(target_body);
+ if (!target_acis)
+ {
+ PRINT_ERROR("Target must be an Acis body!\n");
+ return CUBIT_FAILURE;
+ }
+
+ // Set the sweep vector
+ SPAvector vec(distance.x(), distance.y(), distance.z());
+
+ // Copy the ACIS BODY because it will be deleted at the sweep
+ BODY *target = AcisModifyEngine::instance()->copy_BODY(target_acis->get_BODY_ptr());
+
+ // Set the target and whether solids will be created
+ opts->set_sweep_to_body(target);
+
+ SurfaceACIS *temp = dynamic_cast<SurfaceACIS*>(source_surface);
+
+ // Make sure the curves are ACIS curves
+ if (!temp)
+ {
+ PRINT_ERROR("Profile must be an Acis surface!\n");
+ return CUBIT_FAILURE;
+ }
+
+ // Copy the original face
+ ENTITY *copy;
+ result = api_down_copy_entity((ENTITY*)temp->get_FACE_ptr(), copy);
+ if (!result.ok())
+ {
+ PRINT_ERROR("Failed to copy FACE.\n");
+ AcisQueryEngine::instance()->ACIS_API_error(result);
+ return CUBIT_FAILURE;
+ }
+
+ // Perform the sweep
+ PRINT_INFO("Sweeping surface %d\n", temp->get_saved_id());
+ result = api_sweep_with_options(copy, vec, opts, new_body);
+ if (!result.ok())
+ {
+ PRINT_ERROR("Surface failed to sweep!\n");
+ AcisQueryEngine::instance()->ACIS_API_error(result);
+ return CUBIT_FAILURE;
+ }
+
+ copy = new_body->lump()->shell()->first_face();
+
+ // Add the new BodySM to the return list
+ new_bodies.append(AcisQueryEngine::instance()->populate_topology_bridges(new_body));
+
+ return CUBIT_SUCCESS;
+}
+
+//-------------------------------------------------------------------------
+// Purpose : Perform a curve sweep operation to a target body
+//
+// Special Notes : As of right now (12/01/08), this will result in sheet
+// bodies. You also cannot sweep to a solid body. This
+// method attempts to create a WIRE out of the given EDGEs
+// and sweep that. If that fails, it passes the paramters
+// to ??? to try and perform the sweep.
+//
+// Creator : Derek Quam
+//
+// Creation Date : 11/21/08
+//-------------------------------------------------------------------------
+CubitStatus AcisModifyEngine::sweep_to_body(DLIList<Curve*> curve_list,
+ BodySM *target_body,
+ CubitVector distance,
+ DLIList<BodySM*> &new_bodies,
+ bool unite) const
+{
+ // Declare local variables
+ outcome result;
+ BodyACIS *target_acis;
+ BODY *new_body;
+ sweep_options *opts = new sweep_options();
+ DLIList<BODY*> unite_bodies;
+
+ // Make sure we have an ACIS body
+ target_acis = dynamic_cast<BodyACIS*>(target_body);
+ if (!target_acis)
+ {
+ PRINT_ERROR("Target must be an Acis body!\n");
+ return CUBIT_FAILURE;
+ }
+
+ // Set the sweep vector
+ SPAvector vec(distance.x(), distance.y(), distance.z());
+
+ for (int i = 0; i < curve_list.size(); i++)
+ {
+ // Copy the ACIS BODY because it will be deleted at the sweep
+ BODY *target = AcisModifyEngine::instance()->copy_BODY(target_acis->get_BODY_ptr());
+
+ // Set the target and whether sheets will be created
+ opts->set_sweep_to_body(target);
+ if (target_acis->is_sheet_body())
+ {
+ opts->set_two_sided(TRUE);
+ opts->set_solid(FALSE);
+ }
+
+ // Copy the edge
+ EDGE *copy;
+ Curve *cur = curve_list.get_and_step();
+ result = api_edge(((CurveACIS*)cur)->get_EDGE_ptr(), copy);
+ if (!result.ok())
+ {
+ PRINT_ERROR("ACIS EDGE failed to copy.\n");
+ AcisQueryEngine::instance()->ACIS_API_error(result);
+ return CUBIT_FAILURE;
+ }
+
+ // Perform the sweep
+ result = api_sweep_with_options((ENTITY*)copy, vec, opts, new_body);
+ if (!result.ok())
+ {
+ PRINT_ERROR("Curve %d failed to sweep!\n", cur->get_saved_id());
+ AcisQueryEngine::instance()->ACIS_API_error(result);
+ return CUBIT_FAILURE;
+ }
+
+ // Add the new BodySM to the return list or unite list
+ if (new_body)
+ {
+ if (unite)
+ unite_bodies.append(new_body);
+ else
+ new_bodies.append(AcisQueryEngine::instance()->populate_topology_bridges(new_body));
+ }
+ }
+ for (int i = 1; i < unite_bodies.size(); i++)
+ {
+ result = api_unite(unite_bodies[i], unite_bodies[0]);
+ if (!result.ok())
+ {
+ PRINT_ERROR("Failed to unite swept bodies. Try sweeping with the unite flag off.\n");
+ AcisQueryEngine::instance()->ACIS_API_error(result);
+ return CUBIT_FAILURE;
+ }
+ }
+ if (unite_bodies.size() > 0)
+ new_bodies.append(AcisQueryEngine::instance()->populate_topology_bridges(unite_bodies[0]));
+ return CUBIT_SUCCESS;
+/*
+ if (curve_list.size() > 1)
+ {
+ // Declare the EDGE array
+ const int num_edges = curve_list.size();
+ EDGE **edges = ACIS_NEW EDGE*[num_edges];
+
+ // Fill the EDGE array
+ for (int i = 0; i < num_edges; i++)
+ {
+ // Copy the edge
+ EDGE *copy;
+ result = api_edge(((CurveACIS*)curve_list.get_and_step())->get_EDGE_ptr(), copy);
+
+ // Check the copy operation
+ if (!result.ok())
+ {
+ PRINT_ERROR("ACIS EDGE failed to copy.\n");
+ AcisQueryEngine::instance()->ACIS_API_error(result);
+ return CUBIT_FAILURE;
+ }
+ edges[i] = copy;
+ }
+
+ // Create the WIRE
+ result = api_make_ewires(num_edges, edges, n_bodies, wire_body);
+
+ if (!result.ok())
+ {
+ PRINT_ERROR("Failed to build WIRE! Try sweeping one curve at a time.\n");
+ AcisQueryEngine::instance()->ACIS_API_error(result);
+ return CUBIT_FAILURE;
+ }
+
+ PRINT_INFO("%d WIRE(s) created.\n", n_bodies);
+
+ // Copy the ACIS BODY because it will be deleted at the sweep
+ BODY *target = AcisModifyEngine::instance()->copy_BODY(target_acis->get_BODY_ptr());
+
+ // Set the target and whether sheets will be created
+ opts->set_sweep_to_body(target);
+ if (target_acis->is_sheet_body())
+ {
+ opts->set_two_sided(TRUE);
+ opts->set_solid(FALSE);
+ }
+
+ // Perform the sweep
+ result = api_sweep_with_options((ENTITY*)wire_body[0], vec, opts, new_body);
+ if (!result.ok())
+ {
+ PRINT_ERROR("Curve failed to sweep!\n");
+ AcisQueryEngine::instance()->ACIS_API_error(result);
+ return CUBIT_FAILURE;
+ }
+
+ // Add the new BodySM to the return list
+ if (new_body)
+ new_bodies.append(AcisQueryEngine::instance()->populate_topology_bridges(new_body));
+ else
+ new_bodies.append(AcisQueryEngine::instance()->populate_topology_bridges(wire_body[0]));
+ }
+*/
+}
+
//-------------------------------------------------------------------------
// Purpose : Sections the list of bodies (cuts in half). This is
// when trying to see a cross section of the model.
@@ -9672,6 +10836,14 @@
return CUBIT_FAILURE;
}
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( section_body_list, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
// Copy BODYs
i = section_body_list.size();
DLIList<BODY*> tool_BODY_list(i);
@@ -9767,8 +10939,6 @@
if( body_acis )
{
BodySM *body_sm = CAST_TO(body_acis, BodySM );
- TopologyEntity *topo_entity = body_sm->topology_entity();
- RefEntity *ref_entity = CAST_TO(topo_entity, RefEntity);
section_body_list.remove( body_sm );
}
}
@@ -9843,6 +11013,9 @@
new_body_list,
keep_old );
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ AcisModifyEngine::instance()->stop_tracking_history( new_body_list, history_object );
+
return CUBIT_SUCCESS;
}
@@ -9862,8 +11035,10 @@
const CubitVector &vecVertex1,
const CubitVector &vecVertex2,
const CubitVector &vecVertex3,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*>& results_list,
- bool imprint ) const
+ ImprintType imprint_type,
+ bool preview) const
{
//int webcut_debug_flag = 18;
//int webcut_debug_flag_on = DEBUG_FLAG(webcut_debug_flag);
@@ -9902,13 +11077,30 @@
else
{
+ AcisHistory history_object;
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( webcut_body_list, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
// Use the BODY to perform webcut
CubitStatus stat =
- this->webcut(webcut_body_list, cutting_tool_ptr, results_list, imprint) ;
+ this->webcut(webcut_body_list, cutting_tool_ptr,
+ neighbor_imprint_list,
+ results_list, imprint_type, preview) ;
// Delete the BODY that was created to be used as a tool
AcisQueryEngine::instance()->delete_ACIS_BODY(cutting_tool_ptr, CUBIT_TRUE) ;
cutting_tool_ptr = NULL;
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ if( stat )
+ AcisModifyEngine::instance()->stop_tracking_history( results_list, history_object );
+ }
return stat ;
}
@@ -9927,8 +11119,10 @@
//-------------------------------------------------------------------------
CubitStatus AcisModifyEngine::webcut( DLIList<BodySM*>& webcut_body_list,
BodySM const* tool_body,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*>& results_list,
- bool imprint ) const
+ ImprintType imprint_type,
+ bool preview) const
{
// check the tool body if it is made of AcisModifyEngine
if( !is_modify_engine(tool_body))
@@ -9950,51 +11144,81 @@
return CUBIT_FAILURE;
}
- return this->webcut( webcut_body_list, tool_BODY, results_list, imprint );
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( webcut_body_list, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
+ CubitStatus status = this->webcut( webcut_body_list, tool_BODY,
+ neighbor_imprint_list,
+ results_list, imprint_type, preview );
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ if( CUBIT_SUCCESS == status )
+ AcisModifyEngine::instance()->stop_tracking_history( results_list, history_object );
+ }
+
+ return status;
}
- //-------------------------------------------------------------------------
- // Purpose : webcuts a list of bodies using another Body as the tool.
- // The newly created bodies are merged and imprinted
- // depending on the respective flags.
- // Special Notes :
- //
- // Creator : Jihong Ma
- //
- // Creation Date : 12/17/96
- //-------------------------------------------------------------------------
- CubitStatus AcisModifyEngine::webcut(
- DLIList<BodySM*>& webcut_body_list,
- BODY* tool_BODY,
- DLIList<BodySM*>& results_list,
- bool imprint) const
- {
- CubitBoolean delete_bodies = (GeometryModifyTool::instance()->get_new_ids() ?
- CUBIT_FALSE : CUBIT_TRUE);
+//-------------------------------------------------------------------------
+// Purpose : webcuts a list of bodies using another Body as the tool.
+// The newly created bodies are merged and imprinted
+// depending on the respective flags.
+// Special Notes :
+//
+// Creator : Jihong Ma
+//
+// Creation Date : 12/17/96
+//-------------------------------------------------------------------------
+CubitStatus AcisModifyEngine::webcut( DLIList<BodySM*>& webcut_body_list,
+ BODY* tool_BODY,
+ DLIList<BodySM*>& neighbor_imprint_list,
+ DLIList<BodySM*>& results_list,
+ ImprintType imprint_type,
+ bool preview) const
+{
- // Number of bodies that were webcut
- int count = 0 ;
+ // preview the tool
+ if (preview)
+ {
+ GfxPreview::clear();
+ AcisDrawTool::instance()->draw_ENTITY( tool_BODY, CUBIT_BLUE, CUBIT_TRUE, CUBIT_FALSE );
+ GfxPreview::flush();
+ return CUBIT_SUCCESS;
+ }
+
+ CubitBoolean delete_bodies = (GeometryModifyTool::instance()->get_new_ids() ?
+ CUBIT_FALSE : CUBIT_TRUE);
+
+ // Number of bodies that were webcut
+ int count = 0 ;
+
bool cutting_with_sheet = BodyACIS::is_sheet_body(tool_BODY);
BodySM* Body_to_be_webcut = NULL;
BODY* BODY_to_be_webcut = NULL;
- // List to maintain thew newly created BODYs
- DLIList<BODY*> new_webcut_BODY_list;
+ // List to maintain thew newly created BODYs
+ DLIList<BODY*> new_webcut_BODY_list;
- // List of old bodies that did get webcut
- DLIList<BodySM*> old_body_list;
- DLIList<BODY*> old_BODY_list;
+ // List of old bodies that did get webcut
+ DLIList<BodySM*> old_body_list;
+ DLIList<BODY*> old_BODY_list;
- // Variables to get the results of webcut from another routine.
- BODY* BODY_result1 = NULL;
- BODY* BODY_result2 = NULL;
+ // Variables to get the results of webcut from another routine.
+ BODY* BODY_result1 = NULL;
+ BODY* BODY_result2 = NULL;
- // For each Body in the input list, make sure that it is associated
- // with AGE before the webcutting is done.
- CubitStatus status = CUBIT_FAILURE;
- webcut_body_list.reset() ;
- int i;
+ // For each Body in the input list, make sure that it is associated
+ // with AGE before the webcutting is done.
+ CubitStatus status = CUBIT_FAILURE;
+ webcut_body_list.reset() ;
+ int i;
// step 1: bodies taken from webcut_body_list and webcut; if
// successful, the old Body and BODY are put on old_Body(BODY)_list
@@ -10054,123 +11278,24 @@
results_list.append_unique( Body_to_be_webcut );
}
}
+
+ finish_webcut( NULL, old_body_list, old_BODY_list,
+ new_webcut_BODY_list, neighbor_imprint_list,
+ imprint_type, results_list );
- // A list to hold the newly created Bodies due to imprint operations
- // on the remaining Bodys in the Model. The new Bodys replace the old
- // Bodys if any of the new BODYs created by webcutting imprint
- // on the old Bodys.
- DLIList<BodySM*> new_webcut_body_list;
+ // Return CUBIT_SUCCESS as long as one body is webcut, earlier failures should
+ // return CUBIT_FAILURE independently of these return statments
+ if (count>0)
+ {
+ return CUBIT_SUCCESS;
+ }
+ else
+ {
+ return CUBIT_FAILURE;
+ }
+}
- DLIList<BODY*> just_webcut_list;
- // A list to get the BODY's created that were webcut from the imprint
- // operation.
-
- // Perform the imprinting operations, if required. Note that this
- // operation needs to be performed *after* the model has been cleared of
- // Bodies that were already webcut. Also, note that it returns a list
- // of all the new Bodies created during the imprint operation. This
- // list is then enhanced by adding any new Bodies created due to the
- // actual cutting of an old Body, before it is sent into the webcut_merge
- // procedure. This is the list of Bodies that is "merged".
- if (new_webcut_BODY_list.size() > 0)
- {
- DLIList<BODY*> old_model_BODY_list;
- DLIList<BodySM*> old_model_Body_list;
-
- if ( imprint == CUBIT_TRUE )
- {
- // Work-in-progress message
- PRINT_INFO (" Performing the imprint operations...\n");
-
- // Imprint away :)
- webcut_imprint(tool_BODY, old_body_list, new_webcut_BODY_list,
- just_webcut_list, results_list,
- old_model_Body_list, old_model_BODY_list) ;
- }
- if ( just_webcut_list.size() == 0 )
- just_webcut_list = new_webcut_BODY_list;
-
- // Work-in-progress message
- PRINT_INFO (" Creating the new (webcut) volumes...\n");
-
- // Now create the new Bodies from the ACIS BODYs that were created
- // by webcutting the original BODYs using the Cutting Tool.
- BodySM* new_body_ptr = NULL;
- BODY* webcut_BODY_ptr = NULL;
- new_webcut_BODY_list.reset();
- old_body_list.reset();
- old_BODY_list.reset();
- old_model_Body_list.reset();
- old_model_BODY_list.reset();
-
- for ( i = 0 ; i < new_webcut_BODY_list.size(); i++ )
- {
- DLIList<BODY*> temp_BODY_list;
- DLIList<BodySM*> temp_body_list;
- BodySM *old_Body;
- BODY *old_BODY;
-
- webcut_BODY_ptr = new_webcut_BODY_list.get_and_step();
- temp_BODY_list.append(webcut_BODY_ptr);
- // in call to get_new_Body, don't delete old bodies if
- // they were successfully webcut (need to do it that way to
- // preserve name propagation as before); otherwise, delete the
- // imprinted bodies
- if (imprint == CUBIT_FALSE || just_webcut_list.move_to(webcut_BODY_ptr)) {
- webcut_BODY_ptr = new_webcut_BODY_list.get_and_step();
- temp_BODY_list.append(webcut_BODY_ptr);
- i++;
- old_Body = old_body_list.get_and_step();
- old_BODY = old_BODY_list.get_and_step();
- status = get_new_Body( old_Body, old_BODY, temp_BODY_list, temp_body_list,
- false, delete_bodies );
- }
- else {
- old_Body = old_model_Body_list.get_and_step();
- old_BODY = old_model_BODY_list.get_and_step();
- BodySM* new_Body = get_new_Body( old_Body, old_BODY, webcut_BODY_ptr,
- false, true, true );
- status = CUBIT_SUCCESS;
- if (new_Body)
- temp_body_list.append(new_Body);
- }
-
- if (status == CUBIT_FAILURE) {
- PRINT_ERROR("Failed to build new volume in AGE::webcut.\n");
- }
-
- // if we didn't get any new bodies back from get_new_Body,
- // that means that an imprinted body wasn't really imprinted
- if (temp_body_list.size() > 0) {
- temp_BODY_list.reset();
- temp_body_list.reset();
- for (int j = 0; j < temp_BODY_list.size(); j++) {
- webcut_BODY_ptr = temp_BODY_list.get_and_step();
- new_body_ptr = temp_body_list.get_and_step();
-
- new_webcut_body_list.append(new_body_ptr);
- results_list.append_unique(new_body_ptr);
- }
- }
- else
- new_webcut_body_list.append(old_Body);
-
- }
- }
- // Return CUBIT_SUCCESS as long as one body is webcut, earlier failures should
- // return CUBIT_FAILURE independently of these return statments
- if (count>0)
- {
- return CUBIT_SUCCESS;
- }
- else
- {
- return CUBIT_FAILURE;
- }
- }
-
-
//-------------------------------------------------------------------------
// Purpose : This function creates a Point, given coordinates. The
// particular type of Point object that is created depends on
@@ -10216,6 +11341,18 @@
"Possible incompatible geometry engines.\n");
return (Curve *)NULL;
}
+
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ history_object.highLevelCopying = true;
+ DLIList<TopologyBridge*> my_bridges(1);
+ TopologyBridge *tb = CAST_TO( curve_ptr, TopologyBridge );
+ my_bridges.append( tb );
+ bool ignore_parents = true;
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object, ignore_parents );
+ }
+
EDGE_ptr = curve_ACIS->get_EDGE_ptr();
outcome result = api_edge( EDGE_ptr, new_EDGE_ptr );
@@ -10229,7 +11366,16 @@
// Create a new CurveACIS object
// Use the new EDGE to create a new CurveACIS
- return AcisQueryEngine::instance()->populate_topology_bridges(new_EDGE_ptr);
+ Curve *new_curve = AcisQueryEngine::instance()->populate_topology_bridges(new_EDGE_ptr);
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> new_curves(1);
+ new_curves.append( new_curve );
+ AcisModifyEngine::instance()->stop_tracking_history( new_curves, history_object );
+ }
+
+ return new_curve;
}
//-------------------------------------------------------------------------
@@ -10306,6 +11452,91 @@
}
//-------------------------------------------------------------------------
+// Purpose : This function creates a spline with the given vectors
+// in point_list. point_tangents can be used to specify
+// curvature of the spline.
+//
+// Special Notes : size of point list and tangents must be the same.
+// values in the tangent list may be null.
+//
+// Creator :
+//
+// Creation Date : 04/14/2009
+//-------------------------------------------------------------------------
+Curve* AcisModifyEngine::make_Curve( DLIList<CubitVector*>& point_list,
+ DLIList<CubitVector*>& point_tangents) const
+{
+ if (point_list.size() != point_tangents.size())
+ {
+ PRINT_ERROR("AcisModifyEngine::make_Curve\n"
+ " point list and tangent list must have same size\n");
+ return (Curve *)NULL;
+ }
+
+ DLIList<Curve*> new_curves;
+
+
+ DLIList<CubitVector*> points;
+ CubitVector* point1_vector;
+ CubitVector* start_vector = NULL;
+ CubitVector* end_vector = NULL;
+ CubitVector* tangent_vector;
+ int i = 0;
+ for (i = 0; i < point_list.size(); i++)
+ {
+ point1_vector = point_list.get_and_step();
+ tangent_vector = point_tangents.get_and_step();
+
+
+ points.append(point1_vector);
+ if (tangent_vector != NULL)
+ {
+ start_vector = end_vector;
+ end_vector = tangent_vector;
+
+ if (start_vector != NULL && end_vector != NULL)
+ {
+ EDGE* new_EDGE_ptr = NULL;
+ new_EDGE_ptr = instance()->make_spline_EDGE(points, start_vector, end_vector);
+
+ if (new_EDGE_ptr == NULL)
+ {
+ PRINT_ERROR("In AcisModifyEngine::make_Curve\n"
+ " Cannot make Curve object.\n");
+ Curve* tmp_curve_ptr = NULL;
+ CurveACIS* tmp_acis_curve = NULL;
+ EDGE* tmp_EDGE_ptr = NULL;
+ for (i = 0; i < new_curves.size(); i++)
+ {
+ tmp_curve_ptr = new_curves.get_and_step();
+ tmp_acis_curve = CAST_TO(tmp_curve_ptr, CurveACIS);
+ tmp_EDGE_ptr = tmp_acis_curve->get_EDGE_ptr();
+ api_delent( tmp_EDGE_ptr );
+ }
+ return (Curve *)NULL;
+ }
+
+ Curve* curve_ptr = AcisQueryEngine::instance()->populate_topology_bridges(new_EDGE_ptr);
+ new_curves.append(curve_ptr);
+
+ // reset point array to keep track of the next 2 points
+ points.clean_out();
+ points.append(point1_vector);
+ }
+ }
+ }
+
+ // combine new EDGE* into single curve
+ Curve* new_curve_ptr = NULL;
+ CubitStatus result;
+ result = AcisEdgeTool::instance()->create_curve_combine(new_curves, new_curve_ptr);
+ if (result)
+ return new_curve_ptr;
+ else
+ return (Curve *)NULL;
+}
+
+//-------------------------------------------------------------------------
// Purpose : This function creates a Curve of type, curve_type,
// given the end points of the curve and an intermediate
// point. The particular type of Curve object that is
@@ -10499,44 +11730,125 @@
bool extended_from) const
{
//Get the surface ACIS.
- SurfaceACIS *surf_ACIS = CAST_TO(old_surface_ptr, SurfaceACIS );
- if (surf_ACIS == NULL)
- {
- PRINT_ERROR("surface is not created from acis.\n");
- return (Surface*) NULL;
- }
- //Get the acis face.
- FACE *FACE_ptr = surf_ACIS->get_FACE_ptr();
-
- //use this to make a FACE.
- if (FACE_ptr == NULL )
- {
+ SurfaceACIS *surf_ACIS = CAST_TO(old_surface_ptr, SurfaceACIS );
+ if (surf_ACIS == NULL)
+ {
PRINT_ERROR("surface is not created from acis.\n");
return (Surface*) NULL;
- }
- FACE *new_FACE_ptr = NULL;
+ }
- new_FACE_ptr = make_FACE( FACE_ptr, extended_from );
- if (new_FACE_ptr == NULL)
- {
- PRINT_ERROR("In AcisModifyEngine::make_Surface\n"
- " Cannot make Surface object.\n");
- return (Surface *)NULL;
- }
+ //Get the acis face.
+ FACE *FACE_ptr = surf_ACIS->get_FACE_ptr();
- //populate the bridges from the body
- BODY *body_ptr = AcisQueryEngine::instance()->get_BODY_of_ENTITY(new_FACE_ptr);
- BodySM *body_sm = AcisQueryEngine::instance()->populate_topology_bridges( body_ptr );
- DLIList<Surface*> surfs;
- body_sm->surfaces( surfs );
- Surface *surface = surfs.get();
+ //use this to make a FACE.
+ if (FACE_ptr == NULL )
+ {
+ PRINT_ERROR("surface is not created from acis.\n");
+ return (Surface*) NULL;
+ }
+ FACE *new_FACE_ptr = NULL;
- return surface;
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() && !extended_from )
+ {
+ history_object.highLevelCopying = true;
+ DLIList<TopologyBridge*> my_bridges(1);
+ TopologyBridge *tb = CAST_TO( old_surface_ptr, TopologyBridge );
+ my_bridges.append( tb );
+ bool ignore_parents = true;
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object, ignore_parents );
+ }
+ new_FACE_ptr = make_FACE( FACE_ptr, extended_from );
+ if (new_FACE_ptr == NULL)
+ {
+ PRINT_ERROR("In AcisModifyEngine::make_Surface\n"
+ " Cannot make Surface object.\n");
+ return (Surface *)NULL;
+ }
+
+ //populate the bridges from the body
+ BODY *body_ptr = AcisQueryEngine::instance()->get_BODY_of_ENTITY(new_FACE_ptr);
+ BodySM *body_sm = AcisQueryEngine::instance()->populate_topology_bridges( body_ptr );
+ DLIList<Surface*> surfs;
+ body_sm->surfaces( surfs );
+ Surface *surface = surfs.get();
+
+ if( GeometryQueryTool::instance()->history().is_tracking() && !extended_from )
+ {
+ DLIList<BodySM*> new_bodies(1);
+ new_bodies.append( body_sm );
+ AcisModifyEngine::instance()->stop_tracking_history( new_bodies, history_object );
+ }
+
+ return surface;
}
//-------------------------------------------------------------------------
+// Purpose : This function creates a sheet body by extending out a
+// set of surfaces. The sheet body is a double sided face
+// with no volume.
+//
+// Special Notes :
+//
+// Creator : Steve Storm
+//
+// Creation Date : 2/27/08
+//-------------------------------------------------------------------------
+
+BodySM* AcisModifyEngine::make_extended_sheet( DLIList<Surface*> &surface_list,
+ CubitBox *clip_box_ptr,
+ bool preview ) const
+{
+ // Get the FACE list
+ int i;
+ Surface *surf_ptr;
+ SurfaceACIS *surfACIS_ptr;
+ FACE *FACE_ptr;
+ DLIList<FACE*> FACE_list;
+ surface_list.reset() ;
+ for( i=surface_list.size(); i--; )
+ {
+ surf_ptr = surface_list.get_and_step() ;
+ surfACIS_ptr = CAST_TO(const_cast<Surface*>(surf_ptr), SurfaceACIS) ;
+
+ // Make sure that we don't get NULL pointers after the cast down.
+ if ( surfACIS_ptr == NULL )
+ {
+ PRINT_ERROR("In AcisModifyEngine::make_extended_sheet\n"
+ " Got a NULL pointer to SurfaceACIS\n") ;
+ assert ( surfACIS_ptr != NULL ) ;
+ }
+
+ // Get the FACE
+ FACE_ptr = surfACIS_ptr->get_FACE_ptr() ;
+
+ // Add the FACE to the list of FACEs to be used to make a FACE
+ FACE_list.append(FACE_ptr);
+ }
+
+ // Do the work
+ BODY *ext_BODY_ptr = make_extended_sheet( FACE_list, clip_box_ptr );
+
+ if( !ext_BODY_ptr )
+ return 0;
+
+ if( preview )
+ {
+ GfxPreview::clear();
+ AcisDrawTool::instance()->draw_ENTITY( ext_BODY_ptr, CUBIT_BLUE, CUBIT_TRUE,
+ CUBIT_TRUE );
+
+ api_delent( ext_BODY_ptr );
+ return 0;
+ }
+
+ // Return a BodySM
+ return AcisQueryEngine::instance()->populate_topology_bridges(ext_BODY_ptr);
+}
+
+//-------------------------------------------------------------------------
// Purpose : This function creates a Surface of type,
// surface_type, given the list of curves.
//
@@ -10552,10 +11864,12 @@
bool check_edges ) const
{
DLIList<RefEdge*> copied_ref_edges;
+ DLIList<Curve*> curve_copies;
int i;
if( check_edges )
{
DLIList<RefEdge*> edge_list;
+ curve_list.reset();
for( i=curve_list.size(); i--; )
{
RefEdge *tmp_ref_edge = NULL;
@@ -10572,6 +11886,9 @@
//also pick up the case where edges already belong to a face.
DLIList<RefEdge*> vtx_edges;
DLIList<RefVertex*> vtx_list;
+ DLIList<Curve*> curves_to_make_surface;
+ curve_list.reset();
+ edge_list.reset();
for ( i = edge_list.size(); i > 0; i-- )
{
RefEdge *ref_edge = edge_list.get();
@@ -10595,28 +11912,22 @@
if ( other_edge || (ref_edge->get_parents() > 0) )
{
- RefEdge *replacement_edge = GeometryModifyTool::instance()->make_RefEdge( ref_edge );
- if (!replacement_edge)
- {
- PRINT_WARNING("Creation of Surface Unsuccessful\n");
- return (Surface *)NULL;
- }
- edge_list.change_to( replacement_edge );
- copied_ref_edges.append( replacement_edge );
+ Curve *new_curve = make_Curve( curve_list.get() );
+ curve_copies.append( new_curve );
+ curves_to_make_surface.append( new_curve );
}
+ else
+ {
+ curves_to_make_surface.append( curve_list.get() );
+ }
+
edge_list.step();
+ curve_list.step();
}
curve_list.clean_out();
- for( i=edge_list.size(); i--; )
- {
- Curve *tmp_curve = NULL;
- tmp_curve =
- CAST_TO( edge_list.get_and_step()->bridge_manager()->topology_bridge(), Curve);
- if( tmp_curve )
- curve_list.append( tmp_curve );
- }
- }
+ curve_list += curves_to_make_surface;
+ }
DLIList<EDGE*> EDGE_list ;
// List of EDGEs to use to create the FACE from which we can make
@@ -10626,10 +11937,8 @@
Curve const* curve_ptr = NULL ;
CurveACIS* curveACIS_ptr = NULL ;
EDGE* EDGE_ptr = NULL ;
-
+
curve_list.reset() ;
-
-
for ( i = 0 ; i < curve_list.size() ; i++ )
{
curve_ptr = curve_list.get_and_step() ;
@@ -10647,8 +11956,9 @@
EDGE_ptr = curveACIS_ptr->get_EDGE_ptr() ;
// Add the EDGE to the list of EDGEs to be used to make a FACE
- EDGE_list.append(EDGE_ptr) ;
+ EDGE_list.append(EDGE_ptr);
}
+
// Use the EDGEs to make a FACE
FACE* FACE_ptr = this->make_FACE(surface_type, EDGE_list,
@@ -10656,9 +11966,8 @@
if (FACE_ptr == NULL)
{
- //delete all the copied ref edges...copied just for creating this surface
- for(i=copied_ref_edges.size(); i--; )
- GeometryQueryTool::instance()->delete_RefEdge( copied_ref_edges.get_and_step() );
+ for( i=curve_copies.size(); i--; )
+ AcisQueryEngine::instance()->delete_solid_model_entities( curve_copies.get_and_step() );
PRINT_ERROR("In AcisModifyEngine::make_Surface\n"
" Cannot make Surface object.\n");
@@ -10903,7 +12212,6 @@
BODY *acis_BODY = this->copy_BODY(old_BODY, new_ids);
outcome result = api_clean_entity( (ENTITY*) acis_BODY);
- //outcome result = api_regularise_entity( (ENTITY*) acis_BODY);
if (!result.ok() || acis_BODY == NULL ||
acis_BODY->lump() == NULL )
{
@@ -11030,7 +12338,7 @@
AcisQueryEngine::instance()->ACIS_API_error (result);
AcisQueryEngine::instance()->delete_ACIS_BODY(copied_BODY_ptr, not_new_ids);
return CUBIT_FAILURE;
- }
+ }
}
// clean VERTEX
@@ -11047,12 +12355,179 @@
return CUBIT_FAILURE;
}
}
+
//rebuild the cubit geometry
new_body_ptr = get_new_Body( body_ptr, BODY_ptr , copied_BODY_ptr , false);
if (new_body_ptr) return CUBIT_SUCCESS;
else return CUBIT_FAILURE;
}
+CubitStatus AcisModifyEngine::test_regularize_entity( GeometryEntity *old_refentity_ptr)
+{
+ CubitBoolean new_ids = GeometryModifyTool::instance()->get_new_ids();
+ CubitBoolean not_new_ids = (new_ids ? CUBIT_FALSE : CUBIT_TRUE);
+
+ BODY *copied_BODY_ptr;
+ SurfaceACIS *ref_face = CAST_TO(old_refentity_ptr, SurfaceACIS);
+ CurveACIS *ref_edge= CAST_TO(old_refentity_ptr, CurveACIS);
+ PointACIS *ref_vertex= CAST_TO(old_refentity_ptr, PointACIS);
+
+ DLIList<SurfaceACIS*> reg_face_list;
+ DLIList<FACE*> FACE_list;
+
+ DLIList<CurveACIS*> reg_edge_list;
+ DLIList<EDGE*> EDGE_list;
+
+ DLIList<PointACIS*> reg_vertex_list;
+ DLIList<VERTEX*> VERTEX_list;
+
+ // get the copied_BODY_ptr and FACE_list to clean
+ if (ref_face)
+ {
+ reg_face_list.append(ref_face);
+ if (get_copied_FACES_of_body( reg_face_list, FACE_list, copied_BODY_ptr )== CUBIT_FAILURE )
+ {
+ return CUBIT_FAILURE;
+ }
+ }
+
+// get the copied_BODY_ptr and EDGE_list to clean
+ if (ref_edge)
+ {
+ reg_edge_list.append(ref_edge);
+ if(get_copied_EDGES_of_body( reg_edge_list, EDGE_list, copied_BODY_ptr )== CUBIT_FAILURE )
+ {
+ return CUBIT_FAILURE;
+ }
+ }
+
+ if (ref_vertex)
+ {
+ reg_vertex_list.append(ref_vertex);
+ if (get_copied_VERTICES_of_body( reg_vertex_list, VERTEX_list, copied_BODY_ptr )== CUBIT_FAILURE )
+ {
+ return CUBIT_FAILURE;
+ }
+ }
+
+ if (!ref_face && !ref_edge && !ref_vertex)
+ {
+ AcisQueryEngine::instance()->delete_ACIS_BODY(copied_BODY_ptr, not_new_ids);
+ return CUBIT_FAILURE;
+ }
+
+ int i;
+ FACE *acis_FACE;
+ EDGE *acis_EDGE;
+ VERTEX *acis_VERTEX;
+
+ //clean FACE
+ for (i=0;i<FACE_list.size();i++)
+ {
+ acis_FACE = FACE_list.get_and_step();
+ outcome result = api_clean_entity( (ENTITY*) acis_FACE);
+ if (!result.ok() || acis_FACE == NULL )
+ {
+ AcisQueryEngine::instance()->delete_ACIS_BODY(copied_BODY_ptr, not_new_ids);
+ return CUBIT_FAILURE;
+ }
+ }
+
+ // clean EDGE
+ for (i=0;i<EDGE_list.size();i++)
+ {
+ acis_EDGE = EDGE_list.get_and_step();
+ ENTITY_LIST verts, edges;
+ /*
+ int j, num_verts;
+ api_get_vertices(acis_EDGE, verts);
+ num_verts = verts.count();
+ int prev_num_edges = 0;
+ int new_num_edges = 0;
+ int expected_diff = 2;
+ if(num_verts == 1)
+ expected_diff = 1;
+ for(j=0; j<num_verts; j++)
+ {
+ edges.clear();
+ api_get_edges(verts[j], edges);
+ prev_num_edges += edges.count();
+ }
+ */
+ api_get_edges(copied_BODY_ptr, edges);
+ int prev_size = edges.count();
+ outcome result = api_clean_entity( (ENTITY*) acis_EDGE);
+ edges.clear();
+ api_get_edges(copied_BODY_ptr, edges);
+ int new_size = edges.count();
+ /*
+ for(j=0; j<num_verts; j++)
+ {
+ edges.clear();
+ api_get_edges(verts[j], edges);
+ new_num_edges += edges.count();
+ }
+ */
+
+ if (!result.ok() || acis_EDGE == NULL || prev_size == new_size )
+ {
+ AcisQueryEngine::instance()->delete_ACIS_BODY(copied_BODY_ptr, not_new_ids);
+ return CUBIT_FAILURE;
+ }
+ }
+
+ // clean VERTEX
+ for (i=0;i<VERTEX_list.size();i++)
+ {
+ acis_VERTEX = VERTEX_list.get_and_step();
+ outcome result = api_clean_entity( (ENTITY*) acis_VERTEX);
+ if (!result.ok() || acis_VERTEX == NULL )
+ {
+ AcisQueryEngine::instance()->delete_ACIS_BODY(copied_BODY_ptr, not_new_ids);
+ return CUBIT_FAILURE;
+ }
+ }
+
+ AcisQueryEngine::instance()->delete_ACIS_BODY(copied_BODY_ptr, not_new_ids);
+ return CUBIT_SUCCESS;
+}
+
+
+CubitStatus AcisModifyEngine::split_free_curve( Curve *curve,
+ CubitVector &split_location,
+ DLIList<Curve*> &new_curves )
+{
+ //get the acis curve
+ EDGE* EDGE_ptr = AcisQueryEngine::get_EDGE( curve );
+
+ //make a copy of the curve
+ EDGE* copied_EDGE_ptr;
+ outcome result = api_edge( EDGE_ptr, copied_EDGE_ptr );
+
+ //call the ACIS api for curve splitting
+ SPAposition split_point( split_location.x(), split_location.y(), split_location.z() );
+ ENTITY_LIST new_edges;
+ result = api_split_curve( copied_EDGE_ptr, &split_point, NULL, new_edges );
+
+ if( !result.ok() )
+ {
+ AcisQueryEngine::instance()->ACIS_API_error (result);
+ PRINT_ERROR( "Unable to split curve\n" );
+ api_delent( copied_EDGE_ptr );
+ return CUBIT_FAILURE;
+ }
+
+ int i;
+ for( i=0; i<new_edges.count(); i++ )
+ {
+ Curve *curve_ptr = AcisQueryEngine::instance()->populate_topology_bridges( (EDGE*)new_edges[i] );
+ new_curves.append( curve_ptr );
+ }
+
+ return CUBIT_SUCCESS;
+}
+
+
CubitStatus AcisModifyEngine::split_body( BodySM *body_ptr,
DLIList<BodySM*> &new_bodies )
{
@@ -11078,12 +12553,149 @@
for (int i = 0; i < n_body; i++)
new_BODYs.append(new_BODY_list[i]);
+ ACIS_DELETE [] STD_CAST new_BODY_list;
+
CubitStatus status = get_new_Body(body_ptr, old_BODY,
new_BODYs, new_bodies,
CUBIT_FALSE);
return status;
}
+CubitStatus AcisModifyEngine::separate_surfaces( DLIList<Surface*> &surface_list,
+ DLIList<BodySM*> &new_bodies )
+{
+ DLIList<SurfaceACIS*> copied_surface_list(surface_list.size());
+ CAST_LIST(surface_list, copied_surface_list, SurfaceACIS);
+ if (surface_list.size() != copied_surface_list.size())
+ {
+ PRINT_ERROR("Found a non-ACIS surface where ACIS was expected\n" );
+ return CUBIT_FAILURE;
+ }
+
+ // Loop on FACEs. We will work on separating surfaces from one body at a time.
+ copied_surface_list.reset();
+ while( copied_surface_list.size() )
+ {
+ BODY *copied_BODY_ptr1;
+ DLIList<FACE*> separate_FACE_list1;
+ DLIList<SurfaceACIS*> separate_surface_list1;
+ if( get_copied_FACES_of_body( copied_surface_list, separate_FACE_list1,
+ separate_surface_list1, copied_BODY_ptr1 ) == CUBIT_FAILURE )
+ return CUBIT_FAILURE;
+
+ // Get original Body and BODY
+ BodySM *body_ptr = AcisQueryEngine::instance()->
+ get_body_sm_of_ENTITY( copied_BODY_ptr1 );
+ BODY *BODY_ptr = AcisQueryEngine::get_BODY(body_ptr);
+
+ // Check for special case where all FACEs are being separated from a given
+ // BODY. In this case we do want to separate the BODY but that is it.
+ DLIList<FACE*> tmp_FACE_list;
+ AcisQueryEngine::instance()->get_FACEs( copied_BODY_ptr1, tmp_FACE_list );
+ if( separate_FACE_list1.size() == tmp_FACE_list.size() )
+ {
+ // Just separate this BODY and continue
+ api_delent( copied_BODY_ptr1 );
+
+ if( split_body( body_ptr, new_bodies ) == CUBIT_FAILURE )
+ {
+ // Bomb out since we had an error
+ return new_bodies.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
+ }
+ continue;
+ }
+
+ // Make a second copy of the BODY
+ BODY *copied_BODY_ptr2;
+ DLIList<FACE*> separate_FACE_list2;
+ if( get_copied_FACES_of_body( separate_surface_list1, separate_FACE_list2,
+ copied_BODY_ptr2 ) == CUBIT_FAILURE )
+ {
+ api_delent( copied_BODY_ptr1 );
+ break;
+ }
+
+ // Remove separate_FACE_list1 from BODY_ptr1
+ if( remove_FACEs_from_BODY( copied_BODY_ptr1, separate_FACE_list1 )
+ == CUBIT_FAILURE )
+ {
+ api_delent( copied_BODY_ptr1 );
+ api_delent( copied_BODY_ptr2 );
+ return new_bodies.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
+ }
+
+ // Remove all but separate_FACE_list2 from BODY_ptr2
+ if( remove_FACEs_from_BODY_except( copied_BODY_ptr2, separate_FACE_list2 )
+ == CUBIT_FAILURE )
+ {
+ api_delent( copied_BODY_ptr1 );
+ api_delent( copied_BODY_ptr2 );
+ return new_bodies.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
+ }
+
+ // Remove duplicate Cubit owner attributes from copied_BODY_ptr2
+ remove_dup_owners( copied_BODY_ptr1, copied_BODY_ptr2 );
+
+ // Separate the BODIES
+ BODY **new_BODY_arr = 0;
+ int n_body;
+ bool old_flg = ATTRIB_CUBIT_OWNER::set_split_copy( true );
+ outcome result = api_separate_body( copied_BODY_ptr1, n_body, new_BODY_arr );
+ ATTRIB_CUBIT_OWNER::set_split_copy( old_flg );
+ if (!result.ok())
+ {
+ api_delent( copied_BODY_ptr1 );
+ api_delent( copied_BODY_ptr2 );
+ PRINT_ERROR("problem in separating the new sheet bodies.\n");
+ return CUBIT_FAILURE;
+ }
+
+ int i;
+ DLIList<BODY*> new_BODY_list;
+ for( i=0; i<n_body; i++ )
+ new_BODY_list.append( new_BODY_arr[i] );
+
+ ACIS_DELETE [] STD_CAST new_BODY_arr;
+ new_BODY_arr = 0;
+ n_body = 0;
+
+ ATTRIB_CUBIT_OWNER::set_split_copy( true );
+ result = api_separate_body( copied_BODY_ptr2, n_body, new_BODY_arr );
+ ATTRIB_CUBIT_OWNER::set_split_copy( old_flg );
+ if (!result.ok())
+ {
+ while( new_BODY_list.size() )
+ api_delent( new_BODY_list.pop() );
+ api_delent( copied_BODY_ptr2 );
+ PRINT_ERROR("problem in separating the new sheet bodies.\n");
+ return CUBIT_FAILURE;
+ }
+
+ for( i=0; i<n_body; i++ )
+ new_BODY_list.append( new_BODY_arr[i] );
+
+ ACIS_DELETE [] STD_CAST new_BODY_arr;
+
+ // Cleanup duplicate BODY owners
+ if( new_BODY_list.size() > 1 )
+ {
+ new_BODY_list.reset();
+ BODY *ref_BODY_ptr = new_BODY_list.get_and_step();
+ for( i=1; i<new_BODY_list.size(); i++ )
+ {
+ BODY *tmp_BODY_ptr = new_BODY_list.get_and_step();
+ remove_dup_owners( ref_BODY_ptr, tmp_BODY_ptr, BODY_TYPE );
+ }
+ }
+
+ if( get_new_Body(body_ptr, BODY_ptr, new_BODY_list, new_bodies,
+ CUBIT_FALSE ) == CUBIT_FAILURE )
+ return CUBIT_FAILURE;
+ }
+
+ return CUBIT_SUCCESS;
+}
+
CubitStatus AcisModifyEngine::split_periodic( BodySM *body_ptr,
BodySM *&new_body)
{
@@ -11120,6 +12732,14 @@
EDGE *
AcisModifyEngine::make_spline_EDGE( DLIList<CubitVector*> &vec_list )
{
+ return make_spline_EDGE(vec_list, NULL, NULL);
+}
+
+EDGE *
+AcisModifyEngine::make_spline_EDGE( DLIList<CubitVector*> &vec_list,
+ CubitVector* start_direction,
+ CubitVector* end_direction)
+{
int i;
EDGE *new_EDGE_ptr = NULL;
@@ -11138,7 +12758,19 @@
vec_list.step();
}
- outcome result = api_curve_spline(num_pnts, pos_array, NULL, NULL, new_EDGE_ptr);
+ SPAunit_vector* start_ptr = NULL;
+ SPAunit_vector* end_ptr = NULL;
+
+ if (start_direction != NULL && end_direction != NULL)
+ {
+ SPAunit_vector start(start_direction->x(), start_direction->y(), start_direction->z());
+ SPAunit_vector end(end_direction->x(), end_direction->y(), end_direction->z());
+
+ start_ptr = &start;
+ end_ptr = &end;
+ }
+
+ outcome result = api_curve_spline(num_pnts, pos_array, start_ptr, end_ptr, new_EDGE_ptr);
delete [] pos_array;
if( !result.ok() || new_EDGE_ptr == NULL )
{
@@ -11165,12 +12797,18 @@
if (!body_ptr)
return CUBIT_FAILURE;
+ BodyACIS* acis_body = dynamic_cast<BodyACIS*>(body_to_reverse);
+
outcome result = api_reverse_body( body_ptr );
if (!result.ok())
{
AcisQueryEngine::instance()->ACIS_API_error( result, "reversing BODY." );
return CUBIT_FAILURE;
}
+ //api_reverse_body turns sheet body to 1D...
+ //change it back to 2D
+ if( !acis_body->is_sheet_body() )
+ api_body_to_2d( body_ptr );
return CUBIT_SUCCESS;
}
@@ -11195,289 +12833,7 @@
}
-void AcisModifyEngine::webcut_imprint(
- BODY* cutting_tool_BODY_ptr,
- DLIList<BodySM*> &old_body_list,
- DLIList<BODY*>& new_webcut_BODY_list,
- DLIList<BODY*>& just_webcut_BODY_list,
- DLIList<BodySM*>& results_list,
- DLIList<BodySM*> &imprinted_Body_from_Model_list,
- DLIList<BODY*> &imprinted_BODY_from_Model_list) const
-{
- // This procedure takes care of the imprint operations that are required
- // by the webcut operation. Each of the BODYs in the new_webcut_BODY_list
- // is tested against every other BODY in the model as well as every other
- // BODY in the same list for interference. If interference exists, then
- // the BODYs are imprinted with each other and new (corresponding) Bodies
- // are created. Pointers to these new Bodies are inserted into the list,
- // new_webcut_body_list.
- // MJP Note:
- // Note that this procedure takes care of imprinting the existing Bodies
- // (i.e., the ones in the model) and creating new Bodies when necessary
- // to replace these. However, new Body's are *not* created from the list
- // of ACIS BODYs in the input list, new_webcut_BODY_list. These are simply
- // returned to the calling routine, where it is expected that new Bodies
- // will be created, as required.
-
- int webcut_debug_flag = 18;
- int webcut_debug_flag_on = DEBUG_FLAG(webcut_debug_flag);
-
- int i = 0;
- int j = 0;
-
- // Make copies of the input BODYs
- DLIList<BODY*> copy_new_webcut_BODY_list ;
- DLIList<BODY*> new_results_BODYS;
- new_webcut_BODY_list.reset() ;
- for (i = 0; i < new_webcut_BODY_list.size() ; i++)
- {
- BODY* old_BODY = new_webcut_BODY_list.get_and_step() ;
- BODY* new_BODY = this->copy_BODY(old_BODY,
- GeometryModifyTool::instance()->get_new_ids()) ;
-
- // Make sure the the new BODY is a valid BODY
- assert( new_BODY != NULL) ;
-
- // Add the new BODY to the backup list
- copy_new_webcut_BODY_list.append(new_BODY) ;
- }
-
- // Loop over each of the new BODYs and imprint it with any other new BODY
- // that touches it.
- BODY* first_BODY_ptr = NULL;
- BODY* second_BODY_ptr = NULL;
- copy_new_webcut_BODY_list.reset() ;
- for (i = 0; i < (copy_new_webcut_BODY_list.size() - 1); i++)
- {
- // Get the first BODY
- first_BODY_ptr = copy_new_webcut_BODY_list.get_and_step();
-
- for (j = (i + 1); j < copy_new_webcut_BODY_list.size(); j++)
- {
- // Get the second BODY
- second_BODY_ptr = copy_new_webcut_BODY_list.get_and_step();
-
- // If these BODYs touch, then imprint them
- CubitBoolean result_interfer =
- BODYs_interfering( first_BODY_ptr,second_BODY_ptr );
-
- if ( result_interfer == CUBIT_TRUE )
- {
- CubitStatus resultImprint =
- imprint_BODYs( first_BODY_ptr, second_BODY_ptr );
-
- if( resultImprint == CUBIT_FAILURE )
- {
- PRINT_WARNING ("Imprint operation failed.\n"
- " Going back to the previous state");
-
- // Delete the new BODYs and return.
- copy_new_webcut_BODY_list.reset() ;
- for (int k = 0 ; k < copy_new_webcut_BODY_list.size() ; k++)
- {
- first_BODY_ptr = copy_new_webcut_BODY_list.get_and_step() ;
- AcisQueryEngine::instance()->delete_ACIS_BODY(first_BODY_ptr) ;
- }
- return ;
- }
- }
- }
-
- // Go to the (i+1)th element of the list
- copy_new_webcut_BODY_list.reset() ;
- copy_new_webcut_BODY_list.step(i+1) ;
-
- }
-
-/*
- CDE-- commented out this code. For now, we've decided that when webcutting
- with the 'imprint' option, the imprint should occur between bodies involved
- in the webcut. This code was imprinting all resulting pieces of the webcut
- with all the other Bodies in the model.
-
- // Get the Bodys in the Model
- DLIList<Body*> Body_in_Model_list_tmp;
- GeometryQueryTool::instance()->bodies(Body_in_Model_list_tmp);
- DLIList<BodySM*> Body_in_Model_list;
- Body_in_Model_list_tmp.reset();
- for (i = Body_in_Model_list_tmp.size(); i--; )
- Body_in_Model_list.append( Body_in_Model_list_tmp.get_and_step()->get_body_sm_ptr());
-
- // Loop over each of the new BODYs and imprint it with any of the
- // BODYs already existing in the model, if they touch.
-
- // List of new imprinted BODYs -- Bodies need to be created from these
- DLIList<BODY*> copy_imprinted_BODY_from_Model_list;
-
- BodySM* model_Body_ptr = NULL;
- BODY* model_BODY_ptr = NULL;
- BODY* new_model_BODY_ptr = NULL;
- BODY* new_BODY_ptr = NULL ;
- int copy_made = CUBIT_FALSE;
-
- Body_in_Model_list.reset();
- // Loop over all the existing Bodies
- for (i = 0; i < Body_in_Model_list.size(); i++)
- {
- // Get this existing Body's parent ACIS BODY
- model_Body_ptr = Body_in_Model_list.get_and_step() ;
- model_BODY_ptr = AcisQueryEngine::get_BODY(model_Body_ptr) ;
-
- // Make sure that model_BODY_ptr is not the Cutting Tool as the
- // user is allowed to use an existing Body as a Cutting Tool.
- // If this is the case, then don't involve it in the imprint
- // operations.
- if (model_BODY_ptr == cutting_tool_BODY_ptr || old_body_list.move_to(model_Body_ptr))
- {
- // Don't do anything
- continue;
- }
-
- // Loop over all the newly created (by webcutting) ACIS BODYs and test
- // the existing Body against them (for imprinting purposes, if there
- // is interference)
- copy_made = CUBIT_FALSE;
- new_model_BODY_ptr = NULL;
- copy_new_webcut_BODY_list.reset();
-
- for (j = 0; j < copy_new_webcut_BODY_list.size(); j++)
- {
- // Get the BODY that we're going to test the existing Body against
- new_BODY_ptr = copy_new_webcut_BODY_list.get_and_step() ;
-
- // DEBUG stuff
- if (webcut_debug_flag_on)
- {
- //Save the two BODYs
- AcisQueryEngine::instance()->save_ENTITY_as_sat_file(new_BODY_ptr, "BODY1.sat", "w");
- AcisQueryEngine::instance()->save_ENTITY_as_sat_file(model_BODY_ptr, "BODY2.sat", "w");
- }
-
- // If these BODYs touch, then ...
- if ( BODYs_interfering(new_BODY_ptr, model_BODY_ptr) == CUBIT_TRUE )
- {
- // DEBUG stuff
- if (webcut_debug_flag_on)
- {
- AcisQueryEngine::instance()->save_ENTITY_as_sat_file(new_BODY_ptr,
- "BODY1_after_test.sat",
- "w");
- AcisQueryEngine::instance()->save_ENTITY_as_sat_file(new_model_BODY_ptr,
- "BODY2_after_test.sat",
- "w");
- }
-
- // Because of the fact that the RefEntity datastructure is
- // nonmanifold and hence shares underlying ACIS ENTITYs, I have to:
- // a) make a copy of the parent ACIS BODY of the Body being
- // deactivated (this is done only once for the inner loop)
- // b) then all imprinting is done with this copy instead of
- // with the original parent ACIS BODY.
- // deactivateRefStructure takes care of detaching the RefEntities
- // and their associated ACIS ENTITYs (removing the double links
- // between them).
- if (!copy_made) // Make this copy at most once per outer loop iteration
- {
- // Make a copy of the parent ACIS BODY.
- new_model_BODY_ptr = this->copy_BODY(model_BODY_ptr,
- GeometryModifyTool::instance()->get_new_ids());
-
- // Make sure a valid copy was made. If not, then we need to exit
- // this loop (i.e., stop testing this Body for imprinting
- // and go on to the next one).
- if (new_model_BODY_ptr == NULL)
- {
- PRINT_ERROR("Cannot test imprinting for volume.\n" );
- break;
- }
- else
- {
- copy_made = CUBIT_TRUE;
- if ( results_list.move_to(model_Body_ptr) )
- new_results_BODYS.append( new_model_BODY_ptr );
- imprinted_Body_from_Model_list.append(model_Body_ptr) ;
- imprinted_BODY_from_Model_list.append(model_BODY_ptr) ;
- copy_imprinted_BODY_from_Model_list.append(new_model_BODY_ptr) ;
- }
- }
-
- // Imprint the BODYs (use the new copied BODY). If the imprint
- // operation fails, the state of these BODYs is left unchanged.
- if (imprint_BODYs(new_BODY_ptr, new_model_BODY_ptr) == CUBIT_SUCCESS )
- {
- // DEBUG stuff, if the imprint operation succeeded.
- if (webcut_debug_flag_on)
- {
- AcisQueryEngine::instance()->save_ENTITY_as_sat_file(new_BODY_ptr,
- "BODY1_after_imprint.sat",
- "w");
- AcisQueryEngine::instance()->save_ENTITY_as_sat_file(new_model_BODY_ptr,
- "BODY2_after_imprint.sat",
- "w");
- }
- }
-
- else
- {
- PRINT_WARNING ("Imprint operation failed.\n"
- " Going back to the previous state");
-
- // Delete the new BODYs and return.
- copy_new_webcut_BODY_list.reset() ;
- int k;
- for (k = 0 ; k < copy_new_webcut_BODY_list.size() ; k++)
- {
- new_BODY_ptr = copy_new_webcut_BODY_list.get_and_step() ;
- AcisQueryEngine::instance()->delete_ACIS_BODY(first_BODY_ptr) ;
- }
-
- copy_imprinted_BODY_from_Model_list.reset() ;
- for (k = 0 ; k < copy_imprinted_BODY_from_Model_list.size() ; k++)
- {
- new_model_BODY_ptr = copy_imprinted_BODY_from_Model_list.get_and_step() ;
- AcisQueryEngine::instance()->delete_ACIS_BODY(new_model_BODY_ptr) ;
- }
-
- return ;
- }
- }
- } // Loop over the new (webcut) BODYs
-
- } // Loop over the existing Bodies in Model
-*/
- // Now that we have come so far successfully, create the final list
- // of new BODYs that will be used to create VGI Bodys.
- new_webcut_BODY_list.clean_out() ;
-
- // First the BODYs that were copies of the webcut BODYs
- BODY* new_BODY_ptr = NULL ;
- copy_new_webcut_BODY_list.reset() ;
- for (i = 0 ; i < copy_new_webcut_BODY_list.size() ; i++)
- {
- new_BODY_ptr = copy_new_webcut_BODY_list.get_and_step() ;
- new_webcut_BODY_list.append(new_BODY_ptr) ;
- }
- just_webcut_BODY_list = new_webcut_BODY_list;
-
-/*
- // Then the BODYs that were copies of Model BODYs
- copy_imprinted_BODY_from_Model_list.reset() ;
- for (i = 0 ; i < copy_imprinted_BODY_from_Model_list.size() ; i++)
- {
- new_BODY_ptr = copy_imprinted_BODY_from_Model_list.get_and_step() ;
- new_webcut_BODY_list.append(new_BODY_ptr) ;
- }
-*/
- // now, two important lists:
- // a) just_webcut_BODY_list: bodies in original bodies-to-be-webcut list
- // that were modified, either by webcut or by imprint
- // b) new_webcut_BODY_list: all bodies modified by webcut or imprint,
- // including model bodies affected by imprint
-
- return;
-}
-
BODY* AcisModifyEngine::create_infinite_plane_cutting_tool(
const CubitVector &input_p1,
const CubitVector &input_p2,
@@ -11714,7 +13070,8 @@
CubitStatus AcisModifyEngine::create_solid_bodies_from_surfs( DLIList<Surface*> &ref_face_list,
DLIList<BodySM*> &new_bodies,
bool keep_old,
- bool heal ) const
+ bool heal,
+ bool sheet ) const
{
int ii;
Surface* ref_face;
@@ -11900,7 +13257,6 @@
// BODY *new_master = master;
if ( heal )
{
-
// Now heal the combined body
PRINT_INFO(" Healing the combined volume...\n");
if( AcisHealerTool::instance()->init_BODY_for_healing( master ) == CUBIT_SUCCESS )
@@ -11950,6 +13306,27 @@
return CUBIT_FAILURE;
}
+ //sheet options says that the caller is ok with an open body
+ //being created
+ if( sheet == false )
+ {
+ //make sure that body has volume
+ mass_props_options mp_options;
+ mp_options.set_level( VOLUME_ONLY );
+ mass_props tmp_mass_props;
+ api_body_mass_props( new_master, tmp_mass_props, &mp_options );
+
+ if( tmp_mass_props.get_volume() < GEOMETRY_RESABS )
+ {
+ PRINT_ERROR("Failing because resulting body has no volume.\n"
+ " Examine your set of surfaces to make sure\n"
+ " there are no gaps and none are overlapping\n");
+ api_delent( new_master );
+
+ return CUBIT_FAILURE;
+ }
+ }
+
//separate the bodies so that you have no multi-volume bodies
ENTITY_LIST separated_bodies;
BODY **new_BODY_list;
@@ -11961,8 +13338,7 @@
for( i=0; i<n_bodies; i++ )
new_BODIES.append( new_BODY_list[i] );
- CubitStatus success =
- get_new_Body(old_entities, new_BODIES, new_bodies, keep_old);
+ get_new_Body(old_entities, new_BODIES, new_bodies, keep_old);
if ( new_bodies.size() == 0 )
{
@@ -11978,7 +13354,9 @@
Surface* top_surf_ptr,
Surface* bottom_surf_ptr,
DLIList<BodySM*>& ,
- bool ) const
+ DLIList<BodySM*>& ,
+ ImprintType imprint_type,
+ bool /*preview*/) const
{
CubitVector top_orig, top_norm, bottom_orig, bottom_norm;
double top_orig_pnt[3], top_norm_vec[3], bottom_orig_pnt[3], bottom_norm_vec[3];
@@ -12188,6 +13566,7 @@
CubitStatus AcisModifyEngine::imprint( DLIList<BodySM*> &body_list,
DLIList<Curve*> &ref_edge_list,
DLIList<BodySM*>& new_body_list,
+ DLIList<TopologyBridge*> &temporary_bridges,
bool keep_old_body,
bool show_messages) const
{
@@ -12196,6 +13575,14 @@
CubitStatus status = CUBIT_SUCCESS;
CubitBoolean imprint_worked = CUBIT_FALSE;
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( body_list, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
Curve* ref_edge_ptr;
BodySM *body_ptr;
@@ -12300,10 +13687,47 @@
status = CUBIT_FAILURE;
}
else
- imprint_worked = CUBIT_TRUE;
+ {
+ imprint_worked = CUBIT_TRUE;
+ ENTITY_LIST tmp_edges;
+ api_get_edges((ENTITY*)wire_BODY_ptr, tmp_edges);
+ ENTITY *tmp_ent;
+ tmp_edges.init();
+ while((tmp_ent = tmp_edges.next()))
+ {
+ Curve *new_curve = AcisQueryEngine::instance()->populate_topology_bridges((EDGE*)tmp_ent);
+ if(new_curve)
+ temporary_bridges.append(new_curve);
+ }
+ }
}
if( imprint_worked )
{
+
+ //examine all the edges in the new body for CSA's
+ ENTITY_LIST corey_edges;
+ api_get_edges(copied_BODY_ptr, corey_edges);
+
+ int kk;
+ for( kk=0; kk<corey_edges.count(); kk++ )
+ {
+ EDGE *tmp_edge = (EDGE*)corey_edges[kk];
+
+ ATTRIB_SNL_SIMPLE *attribute =
+ (ATTRIB_SNL_SIMPLE *) find_attrib( tmp_edge,
+ ATTRIB_SNL_TYPE,
+ ATTRIB_SNL_SIMPLE_TYPE);
+ for(;attribute != NULL;attribute = (ATTRIB_SNL_SIMPLE *)
+ find_next_attrib(attribute,
+ ATTRIB_SNL_TYPE,
+ ATTRIB_SNL_SIMPLE_TYPE))
+ {
+ CubitSimpleAttrib *csa = attribute->get_CSA();
+ PRINT_INFO("I have this attrib after on an edge:\n");
+ csa->print();
+ }
+ }
+
api_set_int_option("all_free_edges", FALSE );
DLIList<EDGE*> new_edges = AcisModifyEngine::instance()->find_new_EDGES(copied_BODY_ptr);
@@ -12324,10 +13748,16 @@
}
}
}
+
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ AcisModifyEngine::instance()->stop_tracking_history( new_body_list, history_object );
+
// Free memory
+ /*
for( i=0; i<ewire_list.size(); i++ )
api_delent( ewire_list.get_and_step() );
+ */
if ( imprint_worked && status != CUBIT_SUCCESS )
status = CUBIT_SUCCESS;
return status;
@@ -12340,6 +13770,7 @@
// a body, but the curves just have to be valid ACIS EDGEs.
CubitStatus AcisModifyEngine::imprint( DLIList<Surface*> &surface_list,
DLIList<Curve*> &curve_list,
+ DLIList<TopologyBridge*> &temporary_bridges,
DLIList<BodySM*>& new_body_list,
bool keep_old_body ) const
{
@@ -12402,6 +13833,14 @@
EDGE_list.append( copied_EDGE_ptr );
}
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( surface_list, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
// Loop on FACEs. We will work on imprinting surfaces from one body at a time.
copied_surface_list.reset();
while( copied_surface_list.size() )
@@ -12420,7 +13859,7 @@
if( delete_attribs )
AcisQueryEngine::instance()->remove_cubit_owner_attrib_in_BODY(copied_BODY_ptr);
- if( imprint( copied_BODY_ptr, imprint_FACE_list, EDGE_list ) == CUBIT_FAILURE )
+ if( imprint( copied_BODY_ptr, imprint_FACE_list, EDGE_list, temporary_bridges ) == CUBIT_FAILURE )
{
// This only fails if there is a serious error - delete the copied Body
api_delent( copied_BODY_ptr );
@@ -12446,6 +13885,9 @@
}
}
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ AcisModifyEngine::instance()->stop_tracking_history( new_body_list, history_object );
+
// Free the memory allocated when copying edges
for( i=0; i<EDGE_list.size(); i++ )
{
@@ -12460,7 +13902,8 @@
// are modified but EDGEs are not.
CubitStatus AcisModifyEngine::imprint( BODY *BODY_ptr,
DLIList<FACE*> &FACE_list,
- DLIList<EDGE*> &EDGE_list ) const
+ DLIList<EDGE*> &EDGE_list,
+ DLIList<TopologyBridge*> &temporary_bridges) const
{
// Imprint the edges to the surfaces on this body
outcome result;
@@ -12487,7 +13930,7 @@
// Get the FACE to imprint to
FACE_ptr = FACE_list.get_and_step();
- if( imprint( BODY_ptr, FACE_ptr, EDGE_ptr ) == CUBIT_FAILURE )
+ if( imprint( BODY_ptr, FACE_ptr, EDGE_ptr, temporary_bridges ) == CUBIT_FAILURE )
{
PRINT_ERROR( "Unable to imprint EDGE to FACE\n" );
continue;
@@ -12528,131 +13971,297 @@
CubitStatus AcisModifyEngine::imprint( BODY *BODY_ptr,
FACE *FACE_ptr,
- EDGE *EDGE_ptr ) const
+ EDGE *EDGE_ptr,
+ DLIList<TopologyBridge*> &temporary_bridges,
+ bool expand ) const
{
outcome result;
-
+
BODY* tbody = NULL;
BODY* bbody = NULL; // Blank body
FACE* bface = NULL; // Blank face
surface* tsurf = NULL; // Tool surface
EDGE* edge = NULL;
- //EXCEPTION_TRY
-
bbody = BODY_ptr;
bface = FACE_ptr;
edge = EDGE_ptr;
- // Get the geometry of the blank face.
- surface const& bsurf = bface->geometry()->equation();
-
- // Create an empty tool body
- tbody = ACIS_NEW BODY( (LUMP*) NULL );
-
- // Create the tool body which consists of a single face
- // with a "cross surface" geometric support and no loops.
- const curve &temp_cur = edge->geometry()->equation();
- SPAinterval cur_range = temp_cur.param_range();
- SPAinterval edge_range = edge->param_range();
- if (edge->sense() == REVERSED)
- edge_range = -edge_range;
- if (edge_range == cur_range)
- tsurf = cross_surface( edge->geometry()->equation(),
- bsurf, *(pcurve*) NULL_REF);
+ surface const & surf_to_trim = bface->geometry()->equation();
+ SPAposition pos;
+ SPAunit_vector normal;
+ CubitBoolean planar = surf_to_trim.planar(pos, normal);
+
+ if (!planar)
+ {
+ // AcisDrawTool::instance()->draw_EDGE( edge, CUBIT_YELLOW, true );
+ //AcisDrawTool::instance()->draw_FACE( bface, CUBIT_BLUE, true );
+ // GfxDebug::mouse_xforms();
+
+
+ BODY *wire_body_orig;
+ EDGE *edge_list[1];
+ edge_list[0] = edge;
+ result = api_make_ewire(1, edge_list, wire_body_orig);
+ if( !result.ok())
+ {
+ //AcisQueryEngine::instance()->ACIS_API_error(result);
+ PRINT_ERROR( "Could not create wire\n");
+ return CUBIT_FAILURE;
+ }
+
+ // copy the edge
+ BODY *wire_body1 = NULL;
+ BODY *wire_body3 = NULL;
+ result = api_copy_body( wire_body_orig, wire_body1 );
+ if( !result.ok())
+ {
+ //AcisQueryEngine::instance()->ACIS_API_error(result);
+ PRINT_ERROR( "Could not copy wire\n");
+ return CUBIT_FAILURE;
+ }
+ result = api_copy_body( wire_body_orig, wire_body3 );
+ if( !result.ok())
+ {
+ //AcisQueryEngine::instance()->ACIS_API_error(result);
+ PRINT_ERROR( "Could not copy wire\n");
+ return CUBIT_FAILURE;
+ }
+
+ // get center point of the curve
+ SPAposition curv_center = edge->mid_pos();
+
+ // get the length of the curve
+ double curve_length = edge->length();
+
+ // get the normal on the surface to the center of the curve
+ SPAunit_vector surf_normal = surf_to_trim.point_normal(curv_center);
+
+ // make wires and translate one along the normal and one in the opposite direction
+ double xyz[3];
+ xyz[0] = surf_normal.x()*curve_length*0.5;
+ xyz[1] = surf_normal.y()*curve_length*0.5;
+ xyz[2] = surf_normal.z()*curve_length*0.5;
+ SPAvector normal_trans(xyz[0], xyz[1], xyz[2]);
+ SPAvector minus_normal_trans(-xyz[0], -xyz[1], -xyz[2]);
+
+ SPAtransf plus_trans, minus_trans;
+ plus_trans = translate_transf(normal_trans);
+ minus_trans = translate_transf(minus_normal_trans);
+
+ result = api_apply_transf( wire_body1, plus_trans );
+ if( !result.ok())
+ {
+ AcisQueryEngine::instance()->ACIS_API_error(result);
+ PRINT_ERROR( "error #4\n");
+ }
+ result = api_apply_transf( wire_body3, minus_trans );
+ if( !result.ok())
+ {
+ AcisQueryEngine::instance()->ACIS_API_error(result);
+ PRINT_ERROR( "error #5\n");
+ }
+
+ // now skin the wires
+ BODY *wire_list[2];
+ wire_list[0] = wire_body1;
+ wire_list[1] = wire_body3;
+ skin_options tmp_skin_options;
+ tmp_skin_options.set_solid(0);
+ BODY *trim_tool;
+ result = api_skin_wires(2, wire_list, trim_tool, RULED_SKINNING, &tmp_skin_options);
+ if( !result.ok())
+ {
+ //AcisQueryEngine::instance()->ACIS_API_error(result);
+ PRINT_WARNING( "Could not create the surface to split with\n");
+ return CUBIT_FAILURE;
+ }
+
+ ENTITY_LIST trim_tool_edges;
+ result = api_get_edges(trim_tool, trim_tool_edges);
+ if( !result.ok() )
+ {
+ api_delent( trim_tool );
+ trim_tool = NULL;
+ //AcisQueryEngine::instance()->ACIS_API_error(result);
+ PRINT_ERROR( "Could not get the edges of the trimming surface\n");
+ return CUBIT_FAILURE;
+ }
+
+ if (expand)
+ {
+ SPAposition trim_tool_box_high(0,0,0);
+ SPAposition trim_tool_box_low(0,0,0);
+
+ // now extend the sheetbody
+ lop_options lop_opt = lop_options();
+ lop_opt.set_repair_self_int(TRUE);
+
+ result = api_extend_sheetbody(trim_tool_edges, 0.003, trim_tool_box_low, trim_tool_box_high, &lop_opt);
+ //result = api_extend_sheetbody(trim_tool_edges, 0.01, trim_tool_box_low, trim_tool_box_high, &lop_opt);
+ if( !result.ok() )
+ {
+ //AcisQueryEngine::instance()->ACIS_API_error(result);
+ PRINT_ERROR( "Unable to extend the trimming surface\n" );
+ return CUBIT_FAILURE;
+ }
+ }
+
+ ENTITY_LIST trim_tool_faces;
+ result = api_get_faces(trim_tool, trim_tool_faces);
+ if( !result.ok())
+ {
+ //AcisQueryEngine::instance()->ACIS_API_error(result);
+ PRINT_ERROR( "Could not get the faces of the trimming surface\n");
+ return CUBIT_FAILURE;
+ }
+ FACE *trim_tool_face = (FACE*)trim_tool_faces.first();
+
+ // do a face to face intersection
+ BODY *split_wire_body = NULL;
+ result = api_fafa_int(trim_tool_face, bface, split_wire_body);
+ if( !result.ok())
+ {
+ // as mentioned below in the original code this function will fail rather frequently
+ // however that rarely seems to cause a problem.
+ api_delent( trim_tool_face );
+ return CUBIT_SUCCESS;
+ }
+
+ // Imprint the wire-body onto the BODY
+ result = api_imprint( split_wire_body, bbody );
+ if( !result.ok() && result.error_number()!=200 && result.error_number()!=15020)
+ {
+ //AcisQueryEngine::instance()->ACIS_API_error(result);
+ PRINT_WARNING( "problem splitting face\n");
+ return CUBIT_FAILURE;
+ }
+
+ TopologyBridge *tb = AcisQueryEngine::instance()->populate_topology_bridges(trim_tool);
+ if(tb)
+ temporary_bridges.append(tb);
+
+ return CUBIT_SUCCESS;
+ }
else
- {
- // Create using a subsetted copy of the curve
- curve* subset_cur = temp_cur.subset(edge_range&cur_range);
- tsurf = cross_surface( *subset_cur, bsurf, *(pcurve*) NULL_REF);
- ACIS_DELETE subset_cur;
- }
- if( !tsurf )
- {
- PRINT_ERROR( "Unable to make imprint surface on body\n" );
- return CUBIT_FAILURE;
- }
- FACE* tface = ACIS_NEW FACE( NULL, NULL, make_surface( *tsurf ), FORWARD );
- ACIS_DELETE tsurf; // SRS Added 10-29-99
- tbody->set_lump( ACIS_NEW LUMP( ACIS_NEW SHELL( tface, NULL, NULL ), NULL ) );
+ {
+ // Get the geometry of the blank face.
+ surface const& surf_to_trim = bface->geometry()->equation();
- // Now, imprint the two bodies and throw away the tool body. The
- // resultant blank body will have the edge imprinted on the
- // selected face.
- EDGE* ssi_edges[1];
- FACE* tfaces[1];
- FACE* bfaces[1];
+ // Create an empty tool body
+ tbody = ACIS_NEW BODY( (LUMP*) NULL );
- ssi_edges[0] = edge;
- tfaces[0] = tface;
- bfaces[0] = bface;
+ // Create the tool body which consists of a single face
+ // with a "cross surface" geometric support and no loops.
+ const curve &temp_cur = edge->geometry()->equation();
+ SPAinterval cur_range = temp_cur.param_range();
+ SPAinterval edge_range = edge->param_range();
+ if (edge->sense() == REVERSED)
+ edge_range = -edge_range;
+ if (edge_range == cur_range)
+ tsurf = cross_surface( edge->geometry()->equation(),
+ surf_to_trim, *(pcurve*) NULL_REF);
+ else
+ {
+ // Create using a subsetted copy of the curve
+ curve* subset_cur = temp_cur.subset(edge_range&cur_range);
+ tsurf = cross_surface( *subset_cur, surf_to_trim, *(pcurve*) NULL_REF);
+ ACIS_DELETE subset_cur;
+ }
+
+ if( !tsurf )
+ {
+ PRINT_ERROR( "Unable to make imprint surface on body\n" );
+ return CUBIT_FAILURE;
+ }
+ FACE* tface = ACIS_NEW FACE( NULL, NULL, make_surface( *tsurf ), FORWARD );
+
+ ACIS_DELETE tsurf; // SRS Added 10-29-99
+ tbody->set_lump( ACIS_NEW LUMP( ACIS_NEW SHELL( tface, NULL, NULL ), NULL ) );
+
+ // Now, imprint the two bodies and throw away the tool body. The
+ // resultant blank body will have the edge imprinted on the
+ // selected face.
+ EDGE* ssi_edges[1];
+ FACE* tfaces[1];
+ FACE* bfaces[1];
- result = api_boolean_start( tbody, bbody );
+ ssi_edges[0] = edge;
+ tfaces[0] = tface;
+ bfaces[0] = bface;
- if( result.ok() )
- {
- // If the edge is known to lie on the face, some expensive
- // checking can be ommited by changing the last argument from
- // TRUE to FALSE.
- result = api_update_intersection( tface, *(SPAtransf *)NULL_REF, bface,
- *(SPAtransf *)NULL_REF, 1, ssi_edges, TRUE);
+ result = api_boolean_start( tbody, bbody );
if( result.ok() )
{
- result = api_selectively_intersect( 1, tfaces, bfaces );
+ // If the edge is known to lie on the face, some expensive
+ // checking can be ommited by changing the last argument from
+ // TRUE to FALSE.
+ result = api_update_intersection( tface, *(SPAtransf *)NULL_REF, bface,
+ *(SPAtransf *)NULL_REF, 1, ssi_edges, TRUE );
+
if( result.ok() )
{
- result = api_imprint_complete( tbody, bbody );
- if( !result.ok() )
+ result = api_selectively_intersect( 1, tfaces, bfaces );
+ if( result.ok() )
{
- PRINT_ERROR( "problem in completing imprint for curve on surface\n" );
+ result = api_imprint_complete( tbody, bbody );
+ if( !result.ok() )
+ {
+ PRINT_ERROR( "problem in completing imprint for curve on surface\n" );
+ AcisQueryEngine::instance()->ACIS_API_error(result);
+ api_delent( tbody );
+ return CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR( "problem in selective intersect for curve on surface\n" );
AcisQueryEngine::instance()->ACIS_API_error(result);
api_delent( tbody );
return CUBIT_FAILURE;
}
}
- else
+ else if( result.error_number()!=200 && result.error_number()!=615
+ && result.error_number()!=715 )
{
- PRINT_ERROR( "problem in selective intersect for curve on surface\n" );
- AcisQueryEngine::instance()->ACIS_API_error(result);
+ // Error 200 can occur when the imprint does nothing (curve that's
+ // a surface boundary, curve away from surface). Errors 615/715 can occur
+ // when imprinting a remnant of the same FACE again with the same curve.
+ // The orignal FACE_ptr remains after an imprint - it lives as one
+ // of the remnants. Then, when we attempt to imprint the other pieces
+ // with the same curves, we are getting error 715. The same error
+ // can occur when trying to use one of the surfaces own edges to
+ // imprint with. This has been reported to Spatial and logged as r6294.
+ // It's not fatal so for now we ignore it.
+
+ // We get these all the time, and they don't seem to hurt us.
+
api_delent( tbody );
- return CUBIT_FAILURE;
+ return CUBIT_SUCCESS;
}
}
- else if( result.error_number()!=200 && result.error_number()!=615
- && result.error_number()!=715 )
+ else
{
- // Error 200 can occur when the imprint does nothing (curve that's
- // a surface boundary, curve away from surface). Errors 615/715 can occur
- // when imprinting a remnant of the same FACE again with the same curve.
- // The orignal FACE_ptr remains after an imprint - it lives as one
- // of the remnants. Then, when we attempt to imprint the other pieces
- // with the same curves, we are getting error 715. The same error
- // can occur when trying to use one of the surfaces own edges to
- // imprint with. This has been reported to Spatial and logged as r6294.
- // It's not fatal so for now we ignore it.
-
- // We get these all the time, and they don't seem to hurt us.
+ PRINT_ERROR( "problem starting boolean for curve on surface\n" );
+ AcisQueryEngine::instance()->ACIS_API_error(result);
api_delent( tbody );
- return CUBIT_SUCCESS;
+ return CUBIT_FAILURE;
}
- }
- else
- {
- PRINT_ERROR( "problem starting boolean for curve on surface\n" );
- AcisQueryEngine::instance()->ACIS_API_error(result);
- api_delent( tbody );
- return CUBIT_FAILURE;
- }
- //EXCEPTION_CATCH(TRUE)
+ //EXCEPTION_CATCH(TRUE)
- // Remove temporary objects
- api_delent( tbody );
+ // Remove temporary objects
+ // api_delent( tbody );
+ TopologyBridge *tb = AcisQueryEngine::instance()->populate_topology_bridges(tbody);
+ if(tb)
+ temporary_bridges.append(tb);
- //EXCEPTION_END
+ //EXCEPTION_END
- return CUBIT_SUCCESS;
+ return CUBIT_SUCCESS;
+ }
+ return CUBIT_FAILURE;
}
//- Imprints a list of Surfaces with list of Curves, sorted per
@@ -12663,7 +14272,10 @@
CubitStatus AcisModifyEngine::imprint( DLIList<Surface*> &surface_list,
DLIList<DLIList<Curve*>*> &curve_lists_list,
BodySM*& new_body,
- bool keep_old_body ) const
+ bool keep_old_body,
+ bool expand,
+ DLIList<TopologyBridge*> *new_tbs,
+ DLIList<TopologyBridge*> *att_tbs ) const
{
// Calling code has already ensured that all the Surfaces are from the
// same body
@@ -12736,6 +14348,14 @@
EDGE_list_ptr->append( EDGE_ptr );
}
}
+
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( surface_list, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
// Copy the BODY and get the corresponding FACEs on the copied BODY that need
// to be imprinted
@@ -12751,16 +14371,89 @@
if( delete_attribs )
AcisQueryEngine::instance()->remove_cubit_owner_attrib_in_BODY(copied_BODY_ptr);
+ // Get the edges on the original faces to be split. When we are done
+ // with the split we will check to see if any of the split edges
+ // are the "same" as any of the original edges and if they are we
+ // will call them "new" for the sake of interoperability. This way
+ // if the edge was hidden in a composite it will then be
+ // reintroduced even though the ACIS surface being split wasn't
+ // actually split at all.
+ DLIList<DLIList<EDGE*>*> lists_of_EDGES_on_original_FACES;
+ DLIList<EDGE*> *list_ptr;
+ if(new_tbs)
+ {
+ for(i=copied_FACE_list.size(); i--;)
+ {
+ list_ptr = new DLIList<EDGE*>;
+ lists_of_EDGES_on_original_FACES.append( list_ptr );
+
+ FACE *FACE_ptr = copied_FACE_list.get_and_step();
+ ENTITY_LIST face_edges;
+ api_get_edges((ENTITY*)FACE_ptr, face_edges);
+
+ ENTITY *tmp_ent;
+ face_edges.init();
+ while((tmp_ent = face_edges.next()))
+ list_ptr->append((EDGE*)tmp_ent);
+ }
+ }
+
// Imprint the temporary EDGEs to the FACEs
- if( imprint( copied_BODY_ptr, copied_FACE_list, EDGE_lists_list ) == CUBIT_FAILURE )
+
+ if( imprint( copied_BODY_ptr, copied_FACE_list, EDGE_lists_list, expand ) == CUBIT_FAILURE )
{
api_delent( copied_BODY_ptr );
while( EDGE_lists_list.size() ) delete EDGE_lists_list.pop();
return CUBIT_FAILURE;
}
+
DLIList<EDGE*> new_edges = AcisModifyEngine::instance()->find_new_EDGES(copied_BODY_ptr);
+
+ DLIList<ENTITY*> new_ENTITIES, att_ENTITIES;
+ if(copied_BODY_ptr && new_tbs)
+ {
+ get_new_ENTITIES(copied_BODY_ptr, new_ENTITIES, &lists_of_EDGES_on_original_FACES,
+ &EDGE_lists_list);
+ }
+
new_body = get_new_Body( body_ptr, BODY_ptr, copied_BODY_ptr, false);
+ if (new_body)
+ {
+ // Get entities with composite attributes.
+ if(copied_BODY_ptr && att_tbs)
+ get_att_ENTITIES(copied_BODY_ptr, att_ENTITIES, "COMPOSITE_GEOM");
+ }
+ else
+ {
+ // Get entities with composite attributes.
+ if(att_tbs)
+ get_att_ENTITIES(BODY_ptr, att_ENTITIES, "COMPOSITE_GEOM");
+ }
+
+ // Convert the new_ENTITIES/att_ENTITIES lists into
+ // topology bridge lists.
+ if(new_tbs)
+ {
+ for(i=new_ENTITIES.size(); i--;)
+ {
+ ENTITY *cur_ENT = new_ENTITIES.get_and_step();
+ AcisBridge *acis_bridge = ATTRIB_CUBIT_OWNER::cubit_owner(cur_ENT);
+ if(dynamic_cast<TopologyBridge*>(acis_bridge))
+ new_tbs->append_unique(dynamic_cast<TopologyBridge*>(acis_bridge));
+ }
+ }
+ if(att_tbs)
+ {
+ for(i=att_ENTITIES.size(); i--;)
+ {
+ ENTITY *cur_ENT = att_ENTITIES.get_and_step();
+ AcisBridge *acis_bridge = ATTRIB_CUBIT_OWNER::cubit_owner(cur_ENT);
+ if(dynamic_cast<TopologyBridge*>(acis_bridge))
+ att_tbs->append_unique(dynamic_cast<TopologyBridge*>(acis_bridge));
+ }
+ }
+
// Add a imprint feature to the topo edges
for (int edge_count = new_edges.size(); edge_count-- && new_body; )
{
@@ -12772,6 +14465,13 @@
// Free memory allocated in EDGE_lists_list
while( EDGE_lists_list.size() ) delete EDGE_lists_list.pop();
+ if( GeometryQueryTool::instance()->history().is_tracking() && new_body )
+ {
+ DLIList<BodySM*> new_body_list(1);
+ new_body_list.append( new_body );
+ AcisModifyEngine::instance()->stop_tracking_history( new_body_list, history_object );
+ }
+
return new_body ? CUBIT_SUCCESS : CUBIT_FAILURE;
}
@@ -12800,8 +14500,9 @@
// list positions)
CubitStatus AcisModifyEngine::imprint( BODY *BODY_ptr,
DLIList<FACE*> &FACE_list,
- DLIList<DLIList<EDGE*>*> &EDGE_lists_list ) const
-{
+ DLIList<DLIList<EDGE*>*> &EDGE_lists_list,
+ bool expand) const
+{
// Imprint the edges to the surfaces on this body
outcome result;
FACE *FACE_ptr = 0;
@@ -12839,12 +14540,19 @@
FACES_BEFORE.clean_out();
AcisQueryEngine::instance()->get_FACEs( (ENTITY *)BODY_ptr, FACES_BEFORE );
-
- if( imprint( BODY_ptr, FACE_ptr, EDGE_ptr ) == CUBIT_FAILURE )
+
+ DLIList<TopologyBridge*> temporary_bridges;
+ if( imprint( BODY_ptr, FACE_ptr, EDGE_ptr, temporary_bridges, expand ) == CUBIT_FAILURE )
{
- PRINT_ERROR( "Unable to imprint EDGE to FACE\n" );
+ // PRINT_ERROR( "Unable to imprint EDGE to FACE\n" ); With new split surface algorithm this is not an error
+ temporary_bridges.uniquify_ordered();
+ while(temporary_bridges.size())
+ delete temporary_bridges.pop();
continue;
}
+ temporary_bridges.uniquify_ordered();
+ while(temporary_bridges.size())
+ delete temporary_bridges.pop();
// Check against an assumption that if invalid, will
// cause a crash. The assumption is that the imprinted
@@ -12888,13 +14596,21 @@
DLIList<BodySM*>& new_body_list,
bool keep_old_body,
DLIList<TopologyBridge*> *new_tbs,
- DLIList<TopologyBridge*> *att_tbs ) const
+ DLIList<TopologyBridge*> *att_tbs,
+ double *tol_in,
+ bool clean_up_slivers) const
{
// Until Spatial fixes imprinting with vertices, implement a hack
// (Steve Storm, Caterpillar Inc.)
int i, j, k;
outcome result;
- double tol = 1e-3;
+ double tol;
+ if(tol_in)
+ tol = *tol_in;
+ else
+ tol = GEOMETRY_RESABS;
+// double tol = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS;
+ double tol_sq = tol*tol;
//CubitStatus status = CUBIT_SUCCESS;
CubitVector* vector_ptr;
@@ -12926,6 +14642,14 @@
DLIList<ENTITY*> new_ENTITIES;
DLIList<ENTITY*> att_ENTITIES;
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( body_list, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
body_list.reset();
for( i=0; i<body_list.size(); i++ )
{
@@ -12938,10 +14662,6 @@
// Copy the body before working with it
copied_BODY_ptr = copy_BODY( BODY_ptr, delete_attribs );
- // Get all the vertices of the BODY
- DLIList<VERTEX*> VERTEX_list;
- AcisQueryEngine::instance()->get_VERTICEs( (ENTITY*)BODY_ptr, VERTEX_list );
-
// Get all the FACES of the *original* BODY
DLIList<FACE*> FACE_list;
AcisQueryEngine::instance()->get_FACEs( (ENTITY*)BODY_ptr, FACE_list );
@@ -12953,7 +14673,13 @@
{
vector_ptr = vector_list.get_and_step();
SPAposition test_point( vector_ptr->x(), vector_ptr->y(), vector_ptr->z() );
+ APOINT *apt = new APOINT(test_point);
+ VERTEX *vert = new VERTEX(apt);
+ // Get all the vertices of the BODY
+ DLIList<VERTEX*> VERTEX_list;
+ AcisQueryEngine::instance()->get_VERTICEs( (ENTITY*)copied_BODY_ptr, VERTEX_list );
+
CubitBoolean on_vertex = CUBIT_FALSE;
VERTEX_list.reset();
for( k=0; k<VERTEX_list.size(); k++ )
@@ -12962,9 +14688,11 @@
SPAposition VERTEX_coords = VERTEX_ptr->geometry()->coords();
- if (( fabs(VERTEX_coords.x() - vector_ptr->x()) < tol) &&
- ( fabs(VERTEX_coords.y() - vector_ptr->y()) < tol) &&
- ( fabs(VERTEX_coords.z() - vector_ptr->z()) < tol))
+ CubitVector vec(VERTEX_coords.x() - vector_ptr->x(),
+ VERTEX_coords.y() - vector_ptr->y(),
+ VERTEX_coords.z() - vector_ptr->z());
+
+ if(vec.length_squared() < tol_sq)
{
on_vertex = CUBIT_TRUE;
break; // Skip - coincident with a vertex
@@ -12972,7 +14700,10 @@
}
if( on_vertex )
+ {
+ api_del_entity(vert);
continue; // No imprinting necessary
+ }
// Get all the EDGES of the copied BODY
DLIList<EDGE*> EDGE_list;
@@ -12989,7 +14720,34 @@
continue; // Check next edge
//const curve* acis_curve = &EDGE_ptr->geometry()->equation();
+ SPAposition vert_pos, edge_pos;
+ double dist = 0.0;
+ api_entity_entity_distance(vert, EDGE_ptr, vert_pos, edge_pos, dist);
+ if(dist < tol)
+ {
+ on_edge = CUBIT_TRUE;
+ VERTEX *new_vertex = ACIS_NEW VERTEX(ACIS_NEW APOINT(edge_pos));
+
+ API_BEGIN;
+ sg_split_edge_at_vertex( EDGE_ptr, new_vertex );
+ API_END;
+
+ if( !result.ok() && result.error_number()!=200 )
+ {
+ AcisQueryEngine::instance()->ACIS_API_error(result);
+ PRINT_ERROR( "problem imprinting curve onto volume\n");
+ }
+
+ break;
+ }
+ else
+ continue; // Check next edge
+
+
+
+
+/*
SPAtransf ftrans;
point_edge_containment pe_rel;
@@ -13018,10 +14776,14 @@
break;
}
+ */
}
if( on_edge )
+ {
+ api_del_entity(vert);
continue; // Already imprinted onto the body - check next vertex
+ }
// Check the FACES
FACE_list.reset();
@@ -13032,6 +14794,71 @@
if (FACE_ptr->geometry() == NULL)
continue; // Check next face
+
+ SPAposition vert_pos, face_pos;
+ double dist = 0.0;
+ api_entity_entity_distance(vert, FACE_ptr, vert_pos, face_pos, dist);
+
+ if(dist < tol)
+ {
+ // Create a short curve normal to the surface at the vertex and imprint it
+ SPAunit_vector norm;
+ norm = FACE_ptr->geometry()->equation().point_normal( face_pos );
+
+ if ( FACE_ptr->sense() == REVERSED )
+ norm = -norm;
+
+ // Find the end point
+ SPAposition end_point;
+ end_point.set_x( face_pos.x() + (0.001 * norm.x()) );
+ end_point.set_y( face_pos.y() + (0.001 * norm.y()) );
+ end_point.set_z( face_pos.z() + (0.001 * norm.z()) );
+
+ // Create the curve
+ EDGE* new_EDGE_ptr = NULL;
+ result = api_mk_ed_line ( face_pos, end_point, new_EDGE_ptr );
+ if (!result.ok() || new_EDGE_ptr == NULL)
+ {
+ AcisQueryEngine::instance()->ACIS_API_error (result);
+ PRINT_WARNING("Unable to make short normal curve for imprint operation\n" );
+ continue;
+ }
+
+ // Create a wire from the short curve
+ BODY *wire_BODY_ptr = NULL;
+ result = api_make_ewire( 1, &new_EDGE_ptr, wire_BODY_ptr );
+ if (!result.ok())
+ {
+ AcisQueryEngine::instance()->ACIS_API_error (result);
+ PRINT_WARNING( "Unable to make ACIS WIRE from short imprint curve\n" );
+
+ if( wire_BODY_ptr )
+ api_delent( wire_BODY_ptr );
+ else
+ api_delent( new_EDGE_ptr );
+ continue;
+ }
+
+ // Imprint the wire-body onto the BODY
+ result = api_imprint( wire_BODY_ptr, copied_BODY_ptr );
+
+ if( !result.ok() && result.error_number()!=200 )
+ {
+ AcisQueryEngine::instance()->ACIS_API_error(result);
+ PRINT_ERROR( "problem imprinting short curve onto volume\n");
+ }
+
+ api_delent( wire_BODY_ptr );
+
+ break; // Done imprinting with this vertex
+
+ }
+ else
+ continue; // Check next face
+
+
+
+/*
SPAtransf ftrans;
point_face_containment pf_rel = point_in_face( test_point, FACE_ptr, ftrans );
@@ -13048,9 +14875,9 @@
// Find the end point
SPAposition end_point;
- end_point.set_x( test_point.x() + (tol * norm.x()) );
- end_point.set_y( test_point.y() + (tol * norm.y()) );
- end_point.set_z( test_point.z() + (tol * norm.z()) );
+ end_point.set_x( test_point.x() + (0.001 * norm.x()) );
+ end_point.set_y( test_point.y() + (0.001 * norm.y()) );
+ end_point.set_z( test_point.z() + (0.001 * norm.z()) );
// Create the curve
EDGE* new_EDGE_ptr = NULL;
@@ -13098,10 +14925,13 @@
}
else if( pf_rel == point_unknown_face )
continue; // Check next face
+ */
}
+ api_del_entity(vert);
}
- AcisModifyEngine::instance()->cleanup_slivers( copied_BODY_ptr );
+ if(clean_up_slivers)
+ AcisModifyEngine::instance()->cleanup_slivers( copied_BODY_ptr );
// Get the new entities (just edges for now)
// created by the imprint operation.
@@ -13131,9 +14961,11 @@
if(att_tbs)
get_att_ENTITIES(BODY_ptr, att_ENTITIES, "COMPOSITE_GEOM");
}
-
}
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ AcisModifyEngine::instance()->stop_tracking_history( new_body_list, history_object );
+
// Convert the new_ENTITIES/att_ENTITIES lists into
// topology bridge lists.
if(new_tbs)
@@ -13354,6 +15186,44 @@
return CUBIT_SUCCESS;
}
+CubitStatus
+AcisModifyEngine::split_curve( Curve* curve_to_split,
+ const CubitVector& split_location,
+ DLIList<Curve*>& created_curves )
+{
+ //Expose api_split_curve to Cubit
+ EDGE* EDGE_ptr = AcisQueryEngine::get_EDGE( curve_to_split );
+ if( EDGE_ptr == NULL )
+ return CUBIT_FAILURE;
+
+ SPAposition split_position( split_location.x() , split_location.y() , split_location.z() );
+ EDGE* cutting_EDGE = NULL;
+ ENTITY* new_ENT = NULL;
+ ENTITY_LIST new_ENTs;
+
+ //call api function
+ outcome result = api_split_curve( EDGE_ptr, &split_position , cutting_EDGE , new_ENTs );
+ if( !result.ok() )
+ {
+ AcisQueryEngine::instance()->ACIS_API_error (result);
+ PRINT_ERROR( "Unable to split curve\n" );
+ return CUBIT_FAILURE;
+ }
+ if( new_ENTs.count() == 0 )
+ {
+ PRINT_ERROR( "Split curves not created\n" );
+ return CUBIT_FAILURE;
+ }
+ for(int i=0; i < new_ENTs.count(); i++)
+ {
+ new_ENT = static_cast<EDGE*>(new_ENTs[i]);
+ Curve *new_curve = AcisQueryEngine::instance()->populate_topology_bridges((EDGE*)new_ENT);
+ if(new_curve)
+ created_curves.append(new_curve);
+ }
+ return CUBIT_SUCCESS;
+}
+
Curve*
AcisModifyEngine::trim_curve( Curve* trim_curve,
const CubitVector& trim_vector,
@@ -13753,6 +15623,12 @@
// to the RefFace's).
copied_BODY_ptr = copy_BODY(BODY_ptr, CUBIT_FALSE);
+ if (!copied_BODY_ptr)
+ {
+ PRINT_ERROR( "Unable to copy ACIS body.\n" );
+ return CUBIT_FAILURE;
+ }
+
// Loop through the copied BODY's FACES to find which one's
// match to the original BODY's RefFaces.
ENTITY_LIST ENTITIES;
@@ -13818,6 +15694,219 @@
}
CubitStatus
+AcisModifyEngine::get_copied_FACES_and_EDGES_of_body( DLIList<SurfaceACIS*>& ref_face_list,
+ DLIList<CurveACIS*>& ref_edge_list,
+ DLIList<FACE*>& FACE_list,
+ DLIList<EDGE*>& EDGE_list,
+ DLIList<SurfaceACIS*>& removed_ref_faces,
+ DLIList<CurveACIS*>& removed_ref_edges,
+ BODY*& copied_BODY_ptr ) const
+{
+ int i, num_faces, num_edges;
+
+ // Note: we will be pulling surfaces/curves out of incoming ref_face_list/ref_edge_list.
+ SurfaceACIS* ref_face_ptr;
+ CurveACIS* ref_edge_ptr;
+
+ BODY *BODY_ptr;
+ BODY *BODY_ptr2;
+
+ copied_BODY_ptr = NULL;
+
+ outcome result;
+
+ DLIList<SurfaceACIS*> body_face_list;
+ DLIList<CurveACIS*> body_edge_list;
+
+ ref_face_list.reset();
+ ref_edge_list.reset();
+
+ if(ref_face_list.size())
+ {
+ BODY_ptr = AcisQueryEngine::instance()->get_BODY_of_entity( ref_face_list.get() );
+ if( BODY_ptr == NULL )
+ {
+ PRINT_ERROR( "Unable to get volume from FACE\n" );
+ return CUBIT_FAILURE;
+ }
+ }
+ else if(ref_edge_list.size())
+ {
+ BODY_ptr = AcisQueryEngine::instance()->get_BODY_of_entity( ref_edge_list.get() );
+ if( BODY_ptr == NULL )
+ {
+ PRINT_ERROR( "Unable to get volume from EDGE\n" );
+ return CUBIT_FAILURE;
+ }
+ }
+
+ // Add all remaining faces from this same body to face list
+ num_faces = ref_face_list.size();
+ for( i=0; i<num_faces; i++ )
+ {
+ ref_face_ptr = ref_face_list.get();
+
+ BODY_ptr2 = AcisQueryEngine::instance()->get_BODY_of_entity( ref_face_ptr );
+
+ if( BODY_ptr == BODY_ptr2 )
+ {
+ body_face_list.append_unique( ref_face_ptr );
+ ref_face_list.remove();
+ removed_ref_faces.append( ref_face_ptr );
+ }
+ else
+ ref_face_list.step();
+ }
+ // Add all remaining faces from this same body to face list
+ num_edges = ref_edge_list.size();
+ for( i=0; i<num_edges; i++ )
+ {
+ ref_edge_ptr = ref_edge_list.get();
+
+ BODY_ptr2 = AcisQueryEngine::instance()->get_BODY_of_entity( ref_edge_ptr );
+
+ if( BODY_ptr == BODY_ptr2 )
+ {
+ body_edge_list.append_unique( ref_edge_ptr );
+ ref_edge_list.remove();
+ removed_ref_edges.append( ref_edge_ptr );
+ }
+ else
+ ref_edge_list.step();
+ }
+
+ // Now we have all the faces and edges from this particular BODY.
+
+ // Copy the body before working with it. Here we keep the
+ // attributes on the BODY so we can get back to the TE's
+ // in CUBIT from the copy (to find which FACE's to correlate
+ // to the RefFace's).
+ copied_BODY_ptr = copy_BODY(BODY_ptr, CUBIT_FALSE);
+
+ // Loop through the copied BODY's FACES to find which one's
+ // match to the original BODY's RefFaces.
+ ENTITY_LIST ENTITIES;
+ result = api_get_faces( copied_BODY_ptr, ENTITIES );
+ if( !result.ok() )
+ {
+ PRINT_ERROR( "Unable to get ACIS FACES from volume\n" );
+ api_delent( copied_BODY_ptr );
+ copied_BODY_ptr = NULL;
+ return CUBIT_FAILURE;
+ }
+
+ ENTITIES.init();
+ ENTITY* ENTITY_ptr;
+ int index = -1;
+ DLIList<int> index_list;
+ DLIList<FACE*> temp_FACE_list;
+ while( (ENTITY_ptr = ENTITIES.next() ) != NULL )
+ {
+ AcisBridge* ab_ptr = ATTRIB_CUBIT_OWNER::cubit_owner(ENTITY_ptr);
+ ref_face_ptr = CAST_TO( ab_ptr, SurfaceACIS );
+ if( ref_face_ptr == NULL )
+ {
+ PRINT_ERROR( "Unable to find RefFace from ACIS FACE!\n" );
+ api_delent( copied_BODY_ptr );
+ copied_BODY_ptr = NULL;
+ return CUBIT_FAILURE;
+ }
+
+ index = body_face_list.where_is_item( ref_face_ptr );
+ if( index != -1 )
+ {
+ index_list.append( index );
+ temp_FACE_list.append( (FACE *)ENTITY_ptr );
+ }
+ if( temp_FACE_list.size() == body_face_list.size() )
+ break;
+ }
+ ENTITIES.clear();
+
+ if( temp_FACE_list.size() != body_face_list.size() )
+ {
+ PRINT_ERROR( "Internal error correlating FACE lists\n" );
+ api_delent( copied_BODY_ptr );
+ copied_BODY_ptr = NULL;
+ return CUBIT_FAILURE;
+ }
+
+ // Re-sort the list into the proper order
+ temp_FACE_list.reset();
+ index_list.reset();
+ for( i=0; i<index_list.size(); i++ )
+ {
+ // Find the FACE with the corresponding index
+ index = index_list.where_is_item( i );
+ temp_FACE_list.reset();
+ temp_FACE_list.step( index );
+
+ FACE_list.append( temp_FACE_list.get() );
+ }
+
+ // Loop through the copied BODY's EDGES to find which one's
+ // match to the original BODY's RefEdges.
+ ENTITIES.clear();
+ result = api_get_edges( copied_BODY_ptr, ENTITIES );
+ if( !result.ok() )
+ {
+ PRINT_ERROR( "Unable to get ACIS EDGES from volume\n" );
+ api_delent( copied_BODY_ptr );
+ copied_BODY_ptr = NULL;
+ return CUBIT_FAILURE;
+ }
+
+ ENTITIES.init();
+ index = -1;
+ index_list.clean_out();
+ DLIList<EDGE*> temp_EDGE_list;
+ while( (ENTITY_ptr = ENTITIES.next() ) != NULL )
+ {
+ AcisBridge* ab_ptr = ATTRIB_CUBIT_OWNER::cubit_owner(ENTITY_ptr);
+ ref_edge_ptr = CAST_TO( ab_ptr, CurveACIS );
+ if( ref_edge_ptr == NULL )
+ {
+ PRINT_ERROR( "Unable to find RefEdge from ACIS EDGE!\n" );
+ api_delent( copied_BODY_ptr );
+ copied_BODY_ptr = NULL;
+ return CUBIT_FAILURE;
+ }
+
+ index = body_edge_list.where_is_item( ref_edge_ptr );
+ if( index != -1 )
+ {
+ index_list.append( index );
+ temp_EDGE_list.append( (EDGE *)ENTITY_ptr );
+ }
+ if( temp_EDGE_list.size() == body_edge_list.size() )
+ break;
+ }
+ ENTITIES.clear();
+
+ if( temp_EDGE_list.size() != body_edge_list.size() )
+ {
+ PRINT_ERROR( "Internal error correlating EDGE lists\n" );
+ api_delent( copied_BODY_ptr );
+ copied_BODY_ptr = NULL;
+ return CUBIT_FAILURE;
+ }
+
+ // Re-sort the list into the proper order
+ temp_EDGE_list.reset();
+ index_list.reset();
+ for( i=0; i<index_list.size(); i++ )
+ {
+ // Find the FACE with the corresponding index
+ index = index_list.where_is_item( i );
+ temp_EDGE_list.reset();
+ temp_EDGE_list.step( index );
+
+ EDGE_list.append( temp_EDGE_list.get() );
+ }
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus
AcisModifyEngine::get_copied_FACES_of_body( DLIList<SurfaceACIS*>& ref_face_list,
DLIList<FACE*>& FACE_list,
BODY*& copied_BODY_ptr ) const
@@ -14670,9 +16759,7 @@
CubitStatus AcisModifyEngine::scale( BodySM *&body, const CubitVector& f )
{
-#if CUBIT_ACIS_VERSION < 1100
- api_initialize_operators();
-#elif defined(WIN32) || defined(MACOSX)
+#if defined(WIN32) || defined(MACOSX)
api_initialize_warp();
#endif
BODY *new_BODY = NULL;
@@ -14688,9 +16775,7 @@
CubitStatus result = AcisQueryEngine::instance()->transform( new_BODY, scale_transf( f.x(), f.y(), f.z() ) );
-#if CUBIT_ACIS_VERSION < 1100
- api_terminate_operators();
-#elif defined(WIN32) || defined(MACOSX)
+#if defined(WIN32) || defined(MACOSX)
api_terminate_warp();
#endif
@@ -14705,9 +16790,9 @@
}
CubitStatus AcisModifyEngine::tolerant_imprint( DLIList<BodySM*> &bodies_in,
- DLIList<BodySM*> &new_bodies,
- DLIList<TopologyBridge*> *new_tbs,
- DLIList<TopologyBridge*> *att_tbs ) const
+ DLIList<BodySM*> &new_bodies,
+ DLIList<TopologyBridge*> *new_tbs,
+ DLIList<TopologyBridge*> *att_tbs ) const
{
//make sure all bodies are from the same modify engine
DLIList<BodySM*> new_body_list;
@@ -14719,56 +16804,53 @@
progress_tool->start(0, 100, "Tolerant Imprinting" );
}
+ AcisHistory history_object;
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ {
+ DLIList<TopologyBridge*> my_bridges;
+ CAST_LIST( bodies_in, my_bridges, TopologyBridge );
+ AcisModifyEngine::instance()->start_tracking_history( my_bridges, history_object );
+ }
+
CubitStatus status = imprint_overlapping_curves( bodies_in, new_body_list, progress_tool );
status = imprint_overlapping_surfaces( bodies_in, new_body_list, progress_tool );
status = imprint_overlapping_curves( bodies_in, new_body_list, progress_tool, new_tbs, att_tbs );
+
+ //clear out bounding boxes
+ int i;
+ for( i=new_body_list.size(); i--; )
+ {
+ BodyACIS *body_acis = dynamic_cast<BodyACIS*>( new_body_list.get_and_step() );
+ if( body_acis )
+ {
+ BODY *acis_BODY = body_acis->get_BODY_ptr();
+ AcisQueryEngine::instance()->clear_bounding_box( acis_BODY );
+ }
+ }
+ if( GeometryQueryTool::instance()->history().is_tracking() )
+ AcisModifyEngine::instance()->stop_tracking_history( new_body_list, history_object );
+
if( progress_tool )
progress_tool->end();
return CUBIT_SUCCESS;
}
-CubitStatus AcisModifyEngine::imprint_overlapping_curves( DLIList<BodySM*> &body_sms,
- DLIList<BodySM*> &new_body_sms,
- ProgressTool *progress_tool,
- DLIList<TopologyBridge*> *new_tbs,
- DLIList<TopologyBridge*> *att_tbs ) const
+CubitStatus AcisModifyEngine::imprint_overlapping_curves(
+ DLIList< DLIList<Curve*>* > &lists_of_mergeable_curves,
+ DLIList< DLIList<Curve*>* > &lists_of_overlapping_curves,
+ std::map<Curve*, DLIList<Curve*>* > &curve_to_list_map,
+ std::multimap<BodySM*, CubitVector> &body_vertex_imprint_map,
+ DLIList<BodySM*> &new_body_sms,
+ ProgressTool *progress_tool,
+ DLIList<TopologyBridge*> *new_tbs,
+ DLIList<TopologyBridge*> *att_tbs ) const
{
- //find all mergeable curves between the bodies
- CubitStatus status;
-#ifdef BOYD16
- DLIList<RefEntity*> entities;
-#endif
- DLIList< DLIList<Curve*>* > lists_of_mergeable_curves;
+ int i, j;
- status = MergeTool::instance()->find_only_mergeable_curves( body_sms, lists_of_mergeable_curves );
-
- int i,j;
- //increment 4%
- if( progress_tool )
- {
- for( i=4; i--; )
- progress_tool->step();
- }
-
- //find all overlapping curves between the bodies
- std::map<Curve*, DLIList<Curve*>* > curve_to_list_map;
- DLIList< DLIList<Curve*>* > lists_of_overlapping_curves;
- //for each list, curves 2-n overlap the first curve
-
- SurfaceOverlapTool::instance()->find_overlapping_curves( body_sms, lists_of_overlapping_curves,
- curve_to_list_map );
-
- //increment 8%
- if( progress_tool )
- {
- for( i=9; i--; )
- progress_tool->step();
- }
-
//remove idential groups and sub-groups of mergeable curves from
//overlapping groups. For example: If curves A,B,C,D are in a mergeable group
//the following groups will have no need for imprinting, becasue the curves are
@@ -14849,14 +16931,14 @@
double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS;
- DLIList<BodySM*> imprint_body_order;
+ //DLIList<BodySM*> imprint_body_order;
lists_of_overlapping_curves.reset();
//Now setup multi-map for imprinting vertices onto bodies
//This is how the curve - vertex imprinting should be done:
// -imprint vertices of curve 1 in list onto curves 2 - n
// -imprint vertcies of curve 2 - n onto curve 1
- std::multimap<BodySM*, CubitVector* > body_point_imprint_map;
- std::multimap<BodySM*, CubitVector* >::iterator tmp_iter, upper_iter;
+ std::multimap<BodySM*, CubitVector > body_point_imprint_map;
+ std::multimap<BodySM*, CubitVector >::iterator tmp_iter, upper_iter;
for( i=lists_of_overlapping_curves.size(); i--; )
{
@@ -14865,7 +16947,9 @@
Curve *first_curve = curve_list->get_and_step();
DLIList<Point*> curve_1_points;
- first_curve->points( curve_1_points );
+ DLIList<TopologyBridge*> tmp_tb_list;
+ first_curve->get_children_virt(tmp_tb_list);
+ CAST_LIST(tmp_tb_list, curve_1_points, Point);
Point *s_point1 = curve_1_points.get_and_step();
Point *e_point1 = curve_1_points.get_and_step();
@@ -14874,8 +16958,11 @@
while( curve_list->size() > 1 )
{
Curve *other_curve = curve_list->pop();
+
DLIList<Point*> curve_2_points;
- other_curve->points( curve_2_points );
+ tmp_tb_list.clean_out();
+ other_curve->get_children_virt(tmp_tb_list);
+ CAST_LIST(tmp_tb_list, curve_2_points, Point);
Point *s_point2 = curve_2_points.get_and_step();
Point *e_point2 = curve_2_points.get_and_step();
@@ -14885,7 +16972,8 @@
first_curve->closest_point_trimmed( s_point2->coordinates(), close_pt );
if( close_pt.distance_between( s_point1->coordinates() ) > tolerance &&
- close_pt.distance_between( e_point1->coordinates() ) > tolerance )
+ close_pt.distance_between( e_point1->coordinates() ) > tolerance &&
+ close_pt.distance_between( s_point2->coordinates() ) <= tolerance )
{
//are there any other points within tolerance to this point
//to be imprinted onto this body?
@@ -14893,34 +16981,33 @@
bool consider_point = true;
if( tmp_iter != body_point_imprint_map.end() )
{
- CubitVector *tmp_vec = tmp_iter->second;
+ CubitVector tmp_vec = tmp_iter->second;
upper_iter = body_point_imprint_map.upper_bound( tmp_iter->first );
for(; tmp_iter!=upper_iter; ++tmp_iter)
{
tmp_vec = tmp_iter->second;
- if( close_pt.distance_between( *tmp_vec ) < tolerance )
+ if( close_pt.distance_between( tmp_vec ) < tolerance )
{
consider_point = false;
break;
}
}
}
-
+
if( consider_point )
{
//imprint body of curve1 with vertex at this location
- CubitVector *tmp_vec = new CubitVector( close_pt );
body_point_imprint_map.insert( std::multimap<BodySM*,
- CubitVector*>::value_type( first_curve_body, tmp_vec ));
- imprint_body_order.append_unique( first_curve_body );
+ CubitVector>::value_type( first_curve_body, close_pt ));
}
}
first_curve->closest_point_trimmed( e_point2->coordinates(), close_pt );
if( close_pt.distance_between( s_point1->coordinates() ) > tolerance &&
- close_pt.distance_between( e_point1->coordinates() ) > tolerance )
+ close_pt.distance_between( e_point1->coordinates() ) > tolerance &&
+ close_pt.distance_between( e_point2->coordinates() ) <= tolerance )
{
//are there any other points within tolerance to this point
//to be imprinted onto this body?
@@ -14928,13 +17015,13 @@
bool consider_point = true;
if( tmp_iter != body_point_imprint_map.end() )
{
- CubitVector *tmp_vec = tmp_iter->second;
+ CubitVector tmp_vec = tmp_iter->second;
upper_iter = body_point_imprint_map.upper_bound( tmp_iter->first );
for(; tmp_iter!=upper_iter; ++tmp_iter)
{
tmp_vec = tmp_iter->second;
- if( close_pt.distance_between( *tmp_vec ) < tolerance )
+ if( close_pt.distance_between( tmp_vec ) < tolerance )
{
consider_point = false;
break;
@@ -14945,17 +17032,16 @@
if( consider_point )
{
//imprint body of curve1 with vertex at this location
- CubitVector *tmp_vec = new CubitVector( close_pt );
body_point_imprint_map.insert( std::multimap<BodySM*,
- CubitVector*>::value_type( first_curve_body, tmp_vec ));
- imprint_body_order.append_unique( first_curve_body );
+ CubitVector>::value_type( first_curve_body, close_pt ));
}
}
other_curve->closest_point_trimmed( s_point1->coordinates(), close_pt );
if( close_pt.distance_between( s_point2->coordinates() ) > tolerance &&
- close_pt.distance_between( e_point2->coordinates() ) > tolerance )
+ close_pt.distance_between( e_point2->coordinates() ) > tolerance &&
+ close_pt.distance_between( s_point1->coordinates() ) <= tolerance )
{
//are there any other points within tolerance to this point
//to be imprinted onto this body?
@@ -14963,13 +17049,13 @@
bool consider_point = true;
if( tmp_iter != body_point_imprint_map.end() )
{
- CubitVector *tmp_vec = tmp_iter->second;
+ CubitVector tmp_vec = tmp_iter->second;
upper_iter = body_point_imprint_map.upper_bound( tmp_iter->first );
for(; tmp_iter!=upper_iter; ++tmp_iter)
{
tmp_vec = tmp_iter->second;
- if( close_pt.distance_between( *tmp_vec ) < tolerance )
+ if( close_pt.distance_between( tmp_vec ) < tolerance )
{
consider_point = false;
break;
@@ -14980,17 +17066,16 @@
if( consider_point )
{
//imprint body of curve1 with vertex at this location
- CubitVector *tmp_vec = new CubitVector( close_pt );
body_point_imprint_map.insert( std::multimap<BodySM*,
- CubitVector*>::value_type( other_curve_body, tmp_vec ));
- imprint_body_order.append_unique( other_curve_body );
+ CubitVector>::value_type( other_curve_body, close_pt ));
}
}
other_curve->closest_point_trimmed( e_point1->coordinates(), close_pt );
if( close_pt.distance_between( s_point2->coordinates() ) > tolerance &&
- close_pt.distance_between( e_point2->coordinates() ) > tolerance )
+ close_pt.distance_between( e_point2->coordinates() ) > tolerance &&
+ close_pt.distance_between( e_point1->coordinates() ) <= tolerance )
{
//Are there already any other points within tolerance to this point
//to be imprinted onto this body?
@@ -14999,13 +17084,13 @@
bool consider_point = true;
if( tmp_iter != body_point_imprint_map.end() )
{
- CubitVector *tmp_vec = tmp_iter->second;
+ CubitVector tmp_vec = tmp_iter->second;
upper_iter = body_point_imprint_map.upper_bound( tmp_iter->first );
for(; tmp_iter!=upper_iter; ++tmp_iter )
{
tmp_vec = tmp_iter->second;
- if( close_pt.distance_between( *tmp_vec ) < tolerance )
+ if( close_pt.distance_between( tmp_vec ) < tolerance )
{
consider_point = false;
break;
@@ -15016,39 +17101,67 @@
if( consider_point )
{
//imprint body of curve1 with vertex at this location
- CubitVector *tmp_vec = new CubitVector( close_pt );
body_point_imprint_map.insert( std::multimap<BodySM*,
- CubitVector*>::value_type( other_curve_body, tmp_vec ));
- imprint_body_order.append_unique( other_curve_body );
+ CubitVector>::value_type( other_curve_body, close_pt ));
}
}
}
}
+ //append only unique positions
+ std::multimap<BodySM*, CubitVector >::iterator iter;
+ iter = body_vertex_imprint_map.begin();
+ for(; iter != body_vertex_imprint_map.end(); iter++ )
+ {
+ BodySM *tmp_body_sm = iter->first;
+ CubitVector tmp_vec1 = iter->second;
+ bool consider_point = true;
+
+ std::pair< std::multimap<BodySM*, CubitVector >::iterator,
+ std::multimap<BodySM*, CubitVector >::iterator > body_position_pair;
+
+ body_position_pair = body_point_imprint_map.equal_range( tmp_body_sm );
+
+ tmp_iter = body_position_pair.first;
+ upper_iter = body_position_pair.second;
+ for(; tmp_iter!=upper_iter; ++tmp_iter)
+ {
+ CubitVector tmp_vec2 = tmp_iter->second;
+ if( tmp_vec1.distance_between( tmp_vec2 ) < tolerance )
+ {
+ consider_point = false;
+ break;
+ }
+ }
+
+ if( consider_point )
+ {
+ body_point_imprint_map.insert( std::multimap<BodySM*,
+ CubitVector>::value_type( tmp_body_sm, tmp_vec1 ));
+ }
+ }
+
//Imprint Vertices-onto-Body
- imprint_body_order.reset();
- std::multimap<BodySM*, CubitVector*>::iterator point_iter, last_point_iter;
- for( i=imprint_body_order.size(); i--; )
+ std::multimap<BodySM*, CubitVector>::iterator point_iter, last_point_iter, tmp_upper_iter;
+ point_iter = body_point_imprint_map.begin();
+ last_point_iter = body_point_imprint_map.end();
+ for(; point_iter != last_point_iter; )
{
- BodySM *tmp_body_sm = imprint_body_order.get_and_step();
- DLIList<BodySM*> body_to_imprint;
+ BodySM *tmp_body_sm = point_iter->first;
+ DLIList<BodySM*> body_to_imprint(1);
body_to_imprint.append( tmp_body_sm );
- DLIList<CubitVector*> points_to_imprint;
-
point_iter = body_point_imprint_map.find( tmp_body_sm );
- last_point_iter = body_point_imprint_map.upper_bound( point_iter->first );
+ tmp_upper_iter = body_point_imprint_map.upper_bound( point_iter->first );
- for(; point_iter!=last_point_iter; ++point_iter )
- points_to_imprint.append( point_iter->second );
+ DLIList<CubitVector*> points_to_imprint;
+ for(; point_iter!=tmp_upper_iter; ++point_iter )
+ points_to_imprint.append( &(point_iter->second) );
DLIList<BodySM*> new_bodies;
- CubitStatus status = imprint( body_to_imprint, points_to_imprint, new_bodies, false, new_tbs, att_tbs );
+ imprint( body_to_imprint, points_to_imprint, new_bodies, false, new_tbs, att_tbs, &tolerance, false);
if( new_bodies.size() )
new_body_sms.append( new_bodies.get() );
-
- for( j=points_to_imprint.size(); j--; )
- delete points_to_imprint.get_and_step();
}
//increment 4%
@@ -15061,47 +17174,15 @@
return CUBIT_SUCCESS;
}
-CubitStatus AcisModifyEngine::imprint_overlapping_surfaces( DLIList<BodySM*> &body_sms,
- DLIList<BodySM*> &new_body_sms,
- ProgressTool *progress_tool) const
-{
- //Find all mergeable surfaces between the bodies
- DLIList< DLIList<Surface*>* > lists_of_mergeable_surfaces;
- CubitStatus status = MergeTool::instance()->
- find_only_mergeable_surfaces( body_sms, lists_of_mergeable_surfaces );
- if( progress_tool )
- progress_tool->percent( 0.24 );
- //Find all overlapping surfaces between the bodies
- DLIList<Surface*> overlapping_surfaces1;
- DLIList<Surface*> overlapping_surfaces2;
- SurfaceOverlapTool::instance()->
- find_overlapping_surfaces( body_sms, overlapping_surfaces1, overlapping_surfaces2 );
-
- if( progress_tool )
- progress_tool->percent( 0.57 );
-
- //We only want the non-mergeable overlapping surfaces.
- //Remove mergable surfaces from overlapping pairs.
+CubitStatus AcisModifyEngine::imprint_overlapping_surfaces(DLIList<Surface*> &overlapping_surfaces1,
+ DLIList<Surface*> &overlapping_surfaces2,
+ DLIList<BodySM*> &new_body_sms,
+ ProgressTool *progress_tool,
+ DLIList<Surface*> *new_surface_list) const
+{
int i, j, k;
- for( i=lists_of_mergeable_surfaces.size(); i--; )
- {
- DLIList<Surface*> *tmp_surface_list = lists_of_mergeable_surfaces.get_and_step();
- for( j=tmp_surface_list->size(); j--; )
- {
- Surface *tmp_surface = tmp_surface_list->get_and_step();
- while( overlapping_surfaces1.move_to( tmp_surface ) )
- overlapping_surfaces1.change_to(NULL);
- while( overlapping_surfaces2.move_to( tmp_surface ) )
- overlapping_surfaces2.change_to(NULL);
- }
- delete tmp_surface_list;
- }
-
- if( progress_tool )
- progress_tool->percent( 0.59 );
-
//Surface A might be mergeable/overlapping with B and just ever-so-slightly
//overlapping with C. Get rid of C or other overlapping surfaces
//that might be in the list.
@@ -15265,6 +17346,9 @@
//Get bounding box for later
CubitBox bb_surf = overlapping_surface1->bounding_box();
+ CubitSense dummy_sense;
+ double geo_factor = GeometryQueryTool::get_geometry_factor();
+
//remove overlapping curves between the 2 surfaces
for( j=curves2.size(); j--; )
{
@@ -15278,19 +17362,18 @@
{
Curve *tmp_curve_2 = curves1.get();
- if( SurfaceOverlapTool::instance()->
- check_overlap( tmp_curve, tmp_curve_2, NULL))
+ if((tmp_curve->bridge_manager() &&
+ tmp_curve->bridge_manager() == tmp_curve_2->bridge_manager()) ||
+ MergeTool::instance()->about_spatially_equal( tmp_curve, tmp_curve_2,
+ dummy_sense, geo_factor)
+ ||
+ SurfaceOverlapTool::instance()->
+ check_overlap( tmp_curve, tmp_curve_2, NULL) )
{
- //They should be about spatially equal too!
-// CubitSense dummy_sense;
-// if( MergeTool::instance()->about_spatially_equal( curves1.get(), curves2.get(),
-// dummy_sense, GeometryQueryTool::get_geometry_factor() ) )
-// {
curves1.change_to(NULL);
curves2.change_to(NULL);
overlap = true;
break;
-// }
}
}
curves1.step();
@@ -15332,7 +17415,11 @@
break;
}
- if( SurfaceOverlapTool::instance()->check_overlap( iter->second, tmp_curve, NULL ) )
+ if((tmp_curve->bridge_manager() &&
+ tmp_curve->bridge_manager() == iter->second->bridge_manager()) ||
+ MergeTool::instance()->about_spatially_equal( tmp_curve, iter->second,
+ dummy_sense, geo_factor))
+ // if( SurfaceOverlapTool::instance()->check_overlap( iter->second, tmp_curve, NULL ) )
{
match_found = true;
break;
@@ -15390,7 +17477,11 @@
break;
}
- if( SurfaceOverlapTool::instance()->check_overlap( iter->second, tmp_curve, NULL ) )
+ if((tmp_curve->bridge_manager() &&
+ tmp_curve->bridge_manager() == iter->second->bridge_manager()) ||
+ MergeTool::instance()->about_spatially_equal( tmp_curve, iter->second,
+ dummy_sense, geo_factor))
+// if( SurfaceOverlapTool::instance()->check_overlap( iter->second, tmp_curve, NULL ) )
{
match_found = true;
break;
@@ -15405,7 +17496,6 @@
overlapping_surface2, tmp_curve ));
surface_ordering_list.append_unique( overlapping_surface2 );
}
-
}
}
curves1.step();
@@ -15445,9 +17535,8 @@
percentage_per_surface = 0.16 / surface_ordering_list.size();
else
progress_tool->percent( 0.83 );
-
}
-
+ double same_pos_tol_sq = GEOMETRY_RESABS*GEOMETRY_RESABS;
//Now iterate of each surface that will be imprinted with curves.
surface_ordering_list.reset();
bool print_errors = false;
@@ -15471,46 +17560,139 @@
surf_curve_last = final_surface_curve_imprint_map.upper_bound( surf_curve_iter->first );
//For each curve that might be imprinted on the surface...
- for(; surf_curve_iter!=surf_curve_last; ++surf_curve_iter )
- {
- DLIList<Curve*> tmp_curve_list1, tmp_curve_list2;
- Curve *original_curve = surf_curve_iter->second;
- tmp_curve_list1.append( original_curve );
+ for(; surf_curve_iter!=surf_curve_last; ++surf_curve_iter )
+ {
+ DLIList<Curve*> tmp_curve_list1, tmp_curve_list2;
+ Curve *original_curve = surf_curve_iter->second;
+ Curve *projected_curve = NULL;
- //project
- CubitStatus projected = project_edges( surface_list, tmp_curve_list1, tmp_curve_list2, print_errors );
- if( projected == CUBIT_FAILURE )
- {
- AcisQueryEngine::instance()->delete_solid_model_entities( original_curve );
- continue;
- }
-
- Curve *projected_curve = tmp_curve_list2.get();
-
- //if midpoint of projected is far from original curve, continue
- CubitVector original_curve_mid_point = original_curve->center_point();
- if( original_curve_mid_point.distance_between( projected_curve->center_point() ) > tolerance )
- {
- AcisQueryEngine::instance()->delete_solid_model_entities( original_curve );
- AcisQueryEngine::instance()->delete_solid_model_entities( projected_curve );
- continue;
- }
-
- //now intersect
- tmp_curve_list1.clean_out();
- CubitStatus intersected = curve_surface_intersection( tmp_surface, projected_curve, tmp_curve_list1 );
-
- //delete the curves
- AcisQueryEngine::instance()->delete_solid_model_entities( original_curve );
- AcisQueryEngine::instance()->delete_solid_model_entities( projected_curve );
+ // Ideally, we would always just project to the surface, intersect with the
+ // surface (trim to surface), and then imprint the resulting curve(s) onto
+ // the surface. However, becuase of defficiencies in ACIS the projection
+ // and intersection are often flakey. Projecting when you don't need to
+ // can cause problems and often times the intersection fails depending on
+ // whether you have projected or not. So, we will try to dance around these
+ // bugs in ACIS and get something that works.
+ bool need_to_project = false;
+ DLIList<Curve*> final_curves_to_imprint;
- if( intersected == CUBIT_FAILURE)
- continue;
-
- curves_to_imprint += tmp_curve_list1;
- }
+ // Check if it looks like we really need to project this curve or whether
+ // it appears to already be on the surface.
+ CubitVector pt_in, pt_out;
+ DLIList<double> params;
+ double start_param = original_curve->start_param();
+ double end_param = original_curve->end_param();
+ double range = end_param-start_param;
+ params.append(start_param + .2 * range);
+ params.append(start_param + .55 * range);
+ params.append(start_param + .87 * range);
+ int g;
+ for(g=params.size(); g>0 && !need_to_project; g--)
+ {
+ double cur_param = params.get_and_step();
+ original_curve->position_from_u(cur_param, pt_in);
+ tmp_surface->closest_point(pt_in, &pt_out);
+ if((pt_in-pt_out).length_squared() > same_pos_tol_sq)
+ need_to_project = true;
+ }
+ // If it doens't look like we need to project, attempt the curve surface intersection with
+ // the original curve. If this fails we will try projecting first and then doing the
+ // intersection with the projected curve.
+ if(!need_to_project)
+ {
+ // Try to intersect.
+ tmp_curve_list1.clean_out();
+ curve_surface_intersection( tmp_surface, original_curve, tmp_curve_list1 );
+
+ // If we didn't get an intersection with the original curve attempt to project to
+ // see if this helps.
+ if(tmp_curve_list1.size() == 0)
+ {
+ tmp_curve_list1.clean_out();
+ tmp_curve_list1.append(original_curve);
+ CubitStatus projected = project_edges( surface_list, tmp_curve_list1, tmp_curve_list2, print_errors );
+ if( projected == CUBIT_FAILURE )
+ {
+ // If we can't even project bail out.
+ AcisQueryEngine::instance()->delete_solid_model_entities(original_curve);
+ continue;
+ }
+ projected_curve = tmp_curve_list2.get();
+ //if midpoint of projected is far from original curve, continue
+ CubitVector original_curve_mid_point = original_curve->center_point();
+ CubitVector projected_curve_mid_point = projected_curve->center_point();
+ if( original_curve_mid_point.distance_between( projected_curve_mid_point ) > tolerance )
+ {
+ CubitVector closest;
+ projected_curve->closest_point(original_curve_mid_point, closest);
+ if( original_curve_mid_point.distance_between( closest ) > tolerance )
+ {
+ AcisQueryEngine::instance()->delete_solid_model_entities( original_curve );
+ AcisQueryEngine::instance()->delete_solid_model_entities( projected_curve );
+ continue;
+ }
+ }
+
+ // Try to intersect with the projected curve.
+ tmp_curve_list1.clean_out();
+ curve_surface_intersection( tmp_surface, projected_curve, tmp_curve_list1 );
+ if(tmp_curve_list1.size() > 0)
+ final_curves_to_imprint = tmp_curve_list1;
+ }
+ else
+ {
+ final_curves_to_imprint = tmp_curve_list1;
+ }
+ }
+ else
+ {
+ // Project the curve.
+ tmp_curve_list1.clean_out();
+ tmp_curve_list1.append(original_curve);
+ CubitStatus projected = project_edges( surface_list, tmp_curve_list1, tmp_curve_list2, print_errors );
+ if( projected == CUBIT_FAILURE )
+ {
+ // If we can't even project bail out.
+ AcisQueryEngine::instance()->delete_solid_model_entities(original_curve);
+ continue;
+ }
+ projected_curve = tmp_curve_list2.get();
+ //if midpoint of projected is far from original curve, continue
+ CubitVector original_curve_mid_point = original_curve->center_point();
+ CubitVector projected_curve_mid_point = projected_curve->center_point();
+ if( original_curve_mid_point.distance_between( projected_curve_mid_point ) > tolerance )
+ {
+ CubitVector closest;
+ projected_curve->closest_point(original_curve_mid_point, closest);
+ if( original_curve_mid_point.distance_between( closest ) > tolerance )
+ {
+ AcisQueryEngine::instance()->delete_solid_model_entities( original_curve );
+ AcisQueryEngine::instance()->delete_solid_model_entities( projected_curve );
+ continue;
+ }
+ }
+
+ // Try to intersect with the projected curve.
+ tmp_curve_list1.clean_out();
+ curve_surface_intersection( tmp_surface, projected_curve, tmp_curve_list1 );
+ if(tmp_curve_list1.size() > 0)
+ final_curves_to_imprint = tmp_curve_list1;
+ }
+
+ if(final_curves_to_imprint.size() == 0)
+ {
+ AcisQueryEngine::instance()->delete_solid_model_entities( original_curve );
+ if(projected_curve && projected_curve != original_curve)
+ AcisQueryEngine::instance()->delete_solid_model_entities( projected_curve );
+ }
+ else
+ {
+ curves_to_imprint += final_curves_to_imprint;
+ }
+ }
+
//filter out small curves
int j;
for( j=curves_to_imprint.size(); j--; )
@@ -15542,9 +17724,33 @@
{
AcisDrawTool::instance()->draw_curve( curves_to_imprint.get_and_step(), kkk+5 );
GfxDebug::mouse_xforms();
+ } */
+
+ DLIList<Surface*> before_list;
+ if(new_surface_list)
+ {
+ BodySM *bsm = tmp_surface->bodysm();
+ if(bsm)
+ {
+ bsm->surfaces_ignore_virtual(before_list);
+ before_list.remove(tmp_surface);
+ }
}
-*/
- status = embed_curves_into_surface( tmp_surface, curves_to_imprint, new_body_sm );
+
+ DLIList<TopologyBridge*> temporary_bridges;
+ status = embed_curves_into_surface( tmp_surface, curves_to_imprint, temporary_bridges, new_body_sm );
+
+ if(new_surface_list && new_body_sm)
+ {
+ DLIList<Surface*> after_list;
+ new_body_sm->surfaces_ignore_virtual(after_list);
+ after_list -= before_list;
+ *new_surface_list += after_list;
+ }
+
+ temporary_bridges.uniquify_ordered();
+ while(temporary_bridges.size())
+ delete temporary_bridges.pop();
}
if( new_body_sm == NULL )
@@ -15556,21 +17762,28 @@
AcisQueryEngine::instance()->delete_solid_model_entities( curves_to_imprint.get_and_step() );
}
+
+ if(new_surface_list)
+ new_surface_list->uniquify_unordered();
+
return CUBIT_SUCCESS;
}
-//WARNING!!! Only use this function if you KNOW that the curves you want
-//to imprint line on the surface.....otherwise you'll get problems.
-//api_embed_wire_in_faces returns unexpected results if the curve
-//does not lie on the surface.
-CubitStatus AcisModifyEngine::embed_curves_into_surface( Surface *surface,
- DLIList<Curve*> &curves_to_imprint,
- BodySM *&new_body ) const
+CubitStatus AcisModifyEngine::tolerant_imprint_surface_with_curves(
+ Surface *surface,
+ DLIList<Curve*> &curves_to_imprint,
+ DLIList<TopologyBridge*> &temporary_bridges,
+ BodySM *&new_body,
+ DLIList<TopologyBridge*> *new_tbs,
+ DLIList<TopologyBridge*> *att_tbs ) const
{
if( curves_to_imprint.size() == 0 )
return CUBIT_FAILURE;
+ if( curves_to_imprint.size() == 1 )
+ return embed_curves_into_surface( surface, curves_to_imprint, temporary_bridges, new_body, new_tbs, att_tbs );
+
BODY *copied_BODY = NULL;
DLIList<FACE*> imprint_FACE_list;
DLIList<SurfaceACIS*> acis_surfs;
@@ -15596,10 +17809,7 @@
int i;
EDGE *EDGEs[ 1 ];
- ENTITY_LIST wire_BODYs;
-#ifdef BOYD16
- outcome tmp_result;
-#endif
+ DLIList<BODY*> wire_BODYs;
for( i=0; i<curves_to_imprint.size(); i++ )
{
//copy
@@ -15612,16 +17822,18 @@
EDGEs[0] = copied_EDGE_ptr;
BODY *tmp_BODY = NULL;
tmp_result = api_make_ewire( 1, EDGEs, tmp_BODY );
- wire_BODYs.add( (ENTITY*)tmp_BODY );
+ //wire_BODYs.add( (ENTITY*)tmp_BODY );
+ wire_BODYs.append( tmp_BODY );
}
- int number_wire_bodies = wire_BODYs.count();
+ int number_wire_bodies = wire_BODYs.size();
if( number_wire_bodies == 0 )
return CUBIT_FAILURE;
+
+ wire_BODYs.reset();
+ BODY *wire_BODY_ptr = (BODY*)wire_BODYs.get_and_step();
- BODY *wire_BODY_ptr = (BODY*)wire_BODYs[0];
-
ENTITY_LIST *face_list = new ENTITY_LIST;
FACE* imprint_FACE = imprint_FACE_list.get();
face_list->add( (ENTITY*)imprint_FACE );
@@ -15634,13 +17846,27 @@
result = api_embed_wire_in_faces( wire_BODY_ptr, copied_BODY, face_list, tolerance );
API_END
- for(i=1; i<number_wire_bodies; i++ )
+ ENTITY_LIST tmp_edges;
+ ENTITY *tmp_ent;
+ if(result.ok())
{
-#ifdef BOYD16
- bool embedded = false;
-#endif
- wire_BODY_ptr = (BODY*)wire_BODYs[i];
+ api_get_edges((ENTITY*)wire_BODY_ptr, tmp_edges);
+ tmp_edges.init();
+ while((tmp_ent = tmp_edges.next()))
+ {
+ Curve *new_curve = AcisQueryEngine::instance()->populate_topology_bridges((EDGE*)tmp_ent);
+ if(new_curve)
+ temporary_bridges.append(new_curve);
+ }
+ }
+ //now embed the rest of the wires
+ for(i=1; i<wire_BODYs.size(); i++ )
+ {
+ //wire_BODY_ptr = (BODY*)wire_BODYs[i];
+ wire_BODYs.reset();
+ wire_BODY_ptr = wire_BODYs.next( i );
+
//get all the faces on the body
ENTITY_LIST FACEs;
api_get_faces( copied_BODY, FACEs );
@@ -15650,65 +17876,131 @@
if( number_faces_before == FACEs.count() )
{
result = api_embed_wire_in_faces( wire_BODY_ptr, copied_BODY, face_list, tolerance );
+ if(result.ok())
+ {
+ tmp_edges.clear();
+ api_get_edges((ENTITY*)wire_BODY_ptr, tmp_edges);
+ tmp_edges.init();
+ while((tmp_ent = tmp_edges.next()))
+ {
+ Curve *new_curve = AcisQueryEngine::instance()->populate_topology_bridges((EDGE*)tmp_ent);
+ if(new_curve)
+ temporary_bridges.append(new_curve);
+ }
+ }
continue;
}
- //need to determine which face to embed curve onto
- //may be able to remove this later on and just embed into body
- //just embed the remining wires into the body
- //result = api_embed_wire_in_faces( wire_BODY_ptr, copied_BODY, NULL, tolerance );
- //if( !result.ok() )
- // AcisQueryEngine::instance()->ACIS_API_error (result);
-
- //get midpoint of curve to embed
ENTITY_LIST wire_edge_list;
api_get_edges( wire_BODY_ptr, wire_edge_list );
EDGE *wire_edge = (EDGE*)wire_edge_list[0];
- SPAposition mid_point = wire_edge->mid_pos();
//get position at fraction 0.79 along curve
-#ifdef BOYD16
- SPAposition start_point = wire_edge->start()->geometry()->coords();
-#endif
SPAparameter s_param = wire_edge->start_param();
SPAparameter e_param = wire_edge->end_param();
-
- //SPAinterval param_interval = wire_edge->param_range();
SPAparameter new_parameter = s_param + ((e_param - s_param ) * 0.79);
-
if (wire_edge->sense() == REVERSED )
new_parameter = -(new_parameter);
-
SPAposition point_on_curve;
wire_edge->geometry()->equation().eval(new_parameter, point_on_curve );
- //find surface which contains point at parameter 0.79 and midpoint
- //loop to find appropriate face
+ //find faces WITHOUT an owner attrib on them.
+ //this indicates faces which have been split.
ENTITY *temp_ENT;
FACEs.init();
- FACE *embed_FACE = NULL;
while( (temp_ENT = FACEs.next()) != NULL )
{
FACE *tmp_FACE = (FACE*)temp_ENT;
- SPAposition point1;
- api_find_cls_ptto_face(mid_point, tmp_FACE, point1 );
- if ( distance_to_point( point1, mid_point ) < 0.0005 )
+ if(!ATTRIB_CUBIT_OWNER::cubit_owner( temp_ENT ) )
{
- api_find_cls_ptto_face(point_on_curve, tmp_FACE, point1 );
+ //project edge to surface
+ EDGE *projected_EDGE = project_EDGE( wire_edge, (FACE*)tmp_FACE, false );
+ if( projected_EDGE == NULL )
+ continue;
+
+ //does projection coincide with original
+ curve const* projected_curve = &(projected_EDGE->geometry()->equation());
+ SPAposition result_pos;
+ SPAparameter result_param;
+ projected_curve->point_perp( point_on_curve, result_pos,
+ *(SPAparameter*)NULL_REF,
+ result_param );
+ if( distance_to_point( point_on_curve, result_pos ) > tolerance )
+ {
+ //if no...continue
+ api_delent( (ENTITY*)projected_EDGE);
+ continue;
+ }
+
+ //intersect projected edge with surface
+ ENTITY_LIST *ent_list = new ENTITY_LIST;
+ result = api_edfa_int( projected_EDGE, tmp_FACE, ent_list );
- if ( distance_to_point( point1, point_on_curve ) < 0.0005 )
+ if( !result.ok() || ent_list->count() == 0 )
{
- embed_FACE = tmp_FACE;
- break;
+ delete ent_list;
+ continue;
}
+
+ //we only want edges
+ DLIList<EDGE*> edges_to_embed;
+ ENTITY *tmp_ent;
+ ent_list->init();
+ while( (tmp_ent=ent_list->next()) != NULL )
+ {
+ if( is_EDGE( tmp_ent ) )
+ {
+ EDGE *EDGE_ptr = static_cast<EDGE*>(tmp_ent);
+ edges_to_embed.append( EDGE_ptr );
+ }
+ else
+ api_delent( tmp_ent );
+ }
+ delete ent_list;
+
+ if( edges_to_embed.size() == 0 )
+ continue;
+
+ EDGE *EDGEs[1];
+ EDGEs[0] = edges_to_embed.get_and_step();
+ BODY *wire_to_embed = NULL;
+ result = api_make_ewire( 1, EDGEs, wire_to_embed );
+ ENTITY_LIST *face_list = new ENTITY_LIST;
+ face_list->add( tmp_FACE );
+
+ //now do the embedding
+ API_BEGIN
+ result = api_embed_wire_in_faces( wire_to_embed, copied_BODY, face_list, tolerance );
+ API_END
+
+ if(result.ok())
+ {
+ tmp_edges.clear();
+ api_get_edges((ENTITY*)wire_to_embed, tmp_edges);
+ tmp_edges.init();
+ while((tmp_ent = tmp_edges.next()))
+ {
+ Curve *new_curve = AcisQueryEngine::instance()->populate_topology_bridges((EDGE*)tmp_ent);
+ if(new_curve)
+ temporary_bridges.append(new_curve);
+ }
+ }
+
+ //for any additional intersection curves...add them to the list to embed
+ int kk;
+ for(kk=1; kk<edges_to_embed.size(); kk++ )
+ {
+ EDGEs[0] = edges_to_embed.get_and_step();
+ BODY *wire_to_embed = NULL;
+ result = api_make_ewire( 1, EDGEs, wire_to_embed );
+ if( result.ok() )
+ wire_BODYs.append( wire_to_embed );
+ }
+
+ delete face_list;
+
}
}
- if( embed_FACE )
- {
- face_list->clear();
- face_list->add( (ENTITY*)embed_FACE );
- result = api_embed_wire_in_faces( wire_BODY_ptr, copied_BODY, face_list, tolerance );
- }
}
AcisModifyEngine::instance()->cleanup_slivers( copied_BODY );
@@ -15736,16 +18028,348 @@
num_vertex_bef == num_vertex_aft)
{
AcisQueryEngine::instance()->delete_ACIS_BODY(copied_BODY, CUBIT_TRUE);
- return CUBIT_SUCCESS;
+ return CUBIT_FAILURE;
}
+ // Get the new entities (just edges for now)
+ // created by the imprint operation.
+ DLIList<ENTITY*> new_ENTITIES, att_ENTITIES;
+ if(copied_BODY && new_tbs)
+ get_new_ENTITIES(copied_BODY, new_ENTITIES);
+
BodySM* new_body_ptr = get_new_Body( old_body_sm, BODY_ptr, copied_BODY,
false, CUBIT_TRUE );
+ if (new_body_ptr)
+ {
+ // Get entities with composite attributes.
+ if(copied_BODY && att_tbs)
+ get_att_ENTITIES(copied_BODY, att_ENTITIES, "COMPOSITE_GEOM");
+ }
+ else
+ {
+ // Get entities with composite attributes.
+ if(att_tbs)
+ get_att_ENTITIES(BODY_ptr, att_ENTITIES, "COMPOSITE_GEOM");
+ }
+ // Convert the new_ENTITIES/att_ENTITIES lists into
+ // topology bridge lists.
+ if(new_tbs)
+ {
+ for(i=new_ENTITIES.size(); i--;)
+ {
+ ENTITY *cur_ENT = new_ENTITIES.get_and_step();
+ AcisBridge *acis_bridge = ATTRIB_CUBIT_OWNER::cubit_owner(cur_ENT);
+ if(dynamic_cast<TopologyBridge*>(acis_bridge))
+ new_tbs->append_unique(dynamic_cast<TopologyBridge*>(acis_bridge));
+ }
+ }
+ if(att_tbs)
+ {
+ for(i=att_ENTITIES.size(); i--;)
+ {
+ ENTITY *cur_ENT = att_ENTITIES.get_and_step();
+ AcisBridge *acis_bridge = ATTRIB_CUBIT_OWNER::cubit_owner(cur_ENT);
+ if(dynamic_cast<TopologyBridge*>(acis_bridge))
+ att_tbs->append_unique(dynamic_cast<TopologyBridge*>(acis_bridge));
+ }
+ }
+
new_body = new_body_ptr;
return CUBIT_SUCCESS;
}
+
+//WARNING!!! Only use this function if you KNOW that the curves you want
+//to imprint line on the surface.....otherwise you'll get problems.
+//api_embed_wire_in_faces returns unexpected results if the curve
+//does not lie on the surface.
+CubitStatus AcisModifyEngine::embed_curves_into_surface( Surface *surface,
+ DLIList<Curve*> &curves_to_imprint,
+ DLIList<TopologyBridge*> &temporary_bridges,
+ BodySM *&new_body,
+ DLIList<TopologyBridge*> *new_tbs,
+ DLIList<TopologyBridge*> *att_tbs ) const
+{
+ if( curves_to_imprint.size() == 0 )
+ return CUBIT_FAILURE;
+
+ BODY *copied_BODY = NULL;
+ DLIList<FACE*> imprint_FACE_list;
+ DLIList<SurfaceACIS*> acis_surfs;
+ SurfaceACIS *tmp_acis_surf = CAST_TO( surface, SurfaceACIS );
+
+ if( tmp_acis_surf == NULL )
+ return CUBIT_FAILURE;
+
+ FACE *FACE_ptr = tmp_acis_surf->get_FACE_ptr();
+ BODY *BODY_ptr = AcisQueryEngine::instance()->get_BODY_of_ENTITY( FACE_ptr );
+ BodySM *old_body_sm = AcisQueryEngine::instance()->get_body_sm_of_ENTITY( FACE_ptr );
+
+ acis_surfs.append( tmp_acis_surf );
+ if( get_copied_FACES_of_body( acis_surfs, imprint_FACE_list, copied_BODY ) == CUBIT_FAILURE )
+ return CUBIT_FAILURE;
+
+ if( imprint_FACE_list.size() == 0 )
+ return CUBIT_FAILURE;
+
+ double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS;
+
+ int i;
+ EDGE *EDGEs[ 1 ];
+ ENTITY_LIST wire_BODYs;
+ for( i=0; i<curves_to_imprint.size(); i++ )
+ {
+ //copy
+ EDGE *EDGE_ptr = AcisQueryEngine::get_EDGE( curves_to_imprint.get_and_step() );
+
+ EDGE *copied_EDGE_ptr = NULL;
+ outcome tmp_result = api_edge( EDGE_ptr, copied_EDGE_ptr );
+ ATTRIB_CUBIT_OWNER::remove_cubit_owner( (ENTITY *)copied_EDGE_ptr,
+ CUBIT_TRUE );
+ EDGEs[0] = copied_EDGE_ptr;
+ BODY *tmp_BODY = NULL;
+ tmp_result = api_make_ewire( 1, EDGEs, tmp_BODY );
+ wire_BODYs.add( (ENTITY*)tmp_BODY );
+ }
+
+ int number_wire_bodies = wire_BODYs.count();
+
+ if( number_wire_bodies == 0 )
+ return CUBIT_FAILURE;
+
+ ENTITY_LIST temp_face_list;
+ api_get_faces( copied_BODY, temp_face_list );
+
+ ENTITY_LIST *face_list = new ENTITY_LIST;
+ FACE* imprint_FACE = imprint_FACE_list.get();
+ face_list->add( (ENTITY*)imprint_FACE );
+
+ double dist, dist2;
+ SPAposition wire_pos, edge_pos, pos1, pos2;
+
+ outcome result;
+ ENTITY *tmp_ent, *tmp_face_edge;
+ ENTITY_LIST tmp_edges, face_edges;
+ for(i=0; i<number_wire_bodies; i++ )
+ {
+ BODY *wire_BODY_ptr = (BODY*)wire_BODYs[i];
+
+ ENTITY_LIST FACEs;
+ api_get_faces( copied_BODY, FACEs );
+ if(imprint_FACE == NULL)
+ {
+ // Need to see if we can find a face to imprint into. This face will
+ // also help us know which curves to search for proximity with
+ // the curve we are embedding.
+
+ //get midpoint of curve to embed
+ ENTITY_LIST wire_edge_list;
+ api_get_edges( wire_BODY_ptr, wire_edge_list );
+ EDGE *wire_edge = (EDGE*)wire_edge_list[0];
+ SPAposition mid_point = wire_edge->mid_pos();
+
+ //get position at fraction 0.79 along curve
+ SPAparameter s_param = wire_edge->start_param();
+ SPAparameter e_param = wire_edge->end_param();
+
+ //SPAinterval param_interval = wire_edge->param_range();
+ SPAparameter new_parameter = s_param + ((e_param - s_param ) * 0.79);
+
+ if (wire_edge->sense() == REVERSED )
+ new_parameter = -(new_parameter);
+
+ SPAposition point_on_curve;
+ wire_edge->geometry()->equation().eval(new_parameter, point_on_curve );
+
+ //find surface which contains point at parameter 0.79 and midpoint
+ //loop to find appropriate face
+ ENTITY *temp_ENT;
+ FACEs.init();
+ while( (temp_ENT = FACEs.next()) != NULL )
+ {
+ FACE *tmp_FACE = (FACE*)temp_ENT;
+ SPAposition point1;
+ api_find_cls_ptto_face(mid_point, tmp_FACE, point1 );
+ if ( distance_to_point( point1, mid_point ) < tolerance )
+ {
+ api_find_cls_ptto_face(point_on_curve, tmp_FACE, point1 );
+
+ if ( distance_to_point( point1, point_on_curve ) < tolerance )
+ {
+ imprint_FACE = tmp_FACE;
+ break;
+ }
+ }
+ }
+ }
+ ENTITY_LIST search_edges;
+ if(imprint_FACE == NULL)
+ {
+ // Couldn't find a face so search all curves in body.
+ api_get_edges((ENTITY*)copied_BODY, search_edges);
+ }
+ else
+ {
+ // Found a face so search the curves in the face.
+ api_get_edges((ENTITY*)imprint_FACE, search_edges);
+ }
+ bool found_entities_within_tolerance = false;
+ double largest_distance_within_tolerance = 0.0;
+ search_edges.init();
+ while((tmp_face_edge = search_edges.next()))
+ {
+ dist = 0.0;
+ api_entity_entity_distance(wire_BODY_ptr, tmp_face_edge, wire_pos, edge_pos, dist);
+ if(dist <= tolerance)
+ {
+ found_entities_within_tolerance = true;
+ ENTITY_LIST verts1, verts2;
+ api_get_vertices(wire_BODY_ptr, verts1);
+ api_get_vertices(tmp_face_edge, verts2);
+ ENTITY *vert1, *vert2;
+ verts1.init();
+ while((vert1 = verts1.next()))
+ {
+ verts2.init();
+ while((vert2 = verts2.next()))
+ {
+ dist2 = 0.0;
+ api_entity_entity_distance(vert1, vert2, pos1, pos2, dist2);
+ if(dist2 > dist && dist2 < tolerance)
+ dist = dist2;
+ }
+ }
+ if(dist > largest_distance_within_tolerance)
+ largest_distance_within_tolerance = dist;
+ }
+ }
+ int num_faces_before = FACEs.count();
+ if(found_entities_within_tolerance && largest_distance_within_tolerance > GEOMETRY_RESABS)
+ {
+ // If the biggest distance between entities is less than 1e-6 (ACIS resabs)
+ // we can use regular imprinting. Otherwise we have to use tolerant embedding.
+ largest_distance_within_tolerance *= 1.1;
+ if(largest_distance_within_tolerance > tolerance)
+ largest_distance_within_tolerance = tolerance;
+
+ if(imprint_FACE)
+ {
+ face_list->clear();
+ face_list->add( (ENTITY*)imprint_FACE );
+ result = api_embed_wire_in_faces(wire_BODY_ptr, copied_BODY, face_list, largest_distance_within_tolerance);
+ }
+ else
+ {
+ result = api_embed_wire_in_faces(wire_BODY_ptr, copied_BODY, NULL, largest_distance_within_tolerance);
+ }
+ }
+ else
+ {
+ // Just do a regular imprint becuase the curve already lies in the face
+ // but doesn't come close to other entities.
+ result = api_imprint(wire_BODY_ptr, copied_BODY);
+ }
+ if(result.ok())
+ {
+ tmp_edges.clear();
+ api_get_edges((ENTITY*)wire_BODY_ptr, tmp_edges);
+ tmp_edges.init();
+ while((tmp_ent = tmp_edges.next()))
+ {
+ Curve *new_curve = AcisQueryEngine::instance()->populate_topology_bridges((EDGE*)tmp_ent);
+ if(new_curve)
+ temporary_bridges.append(new_curve);
+ }
+ }
+ //if normal imprint didn't succeed, try embedding
+ else
+ api_embed_wire_in_faces(wire_BODY_ptr, copied_BODY, NULL, largest_distance_within_tolerance);
+
+ FACEs.clear();
+ api_get_faces( copied_BODY, FACEs );
+ if(FACEs.count() != num_faces_before)
+ imprint_FACE = NULL;
+ }
+
+ delete face_list;
+
+ //AcisModifyEngine::instance()->cleanup_slivers( copied_BODY );
+
+ //check to see if anything actually happened
+ int num_vol_bef, num_face_bef, num_edge_bef, num_vertex_bef;
+ CubitStatus status1 = AcisQueryEngine::instance()->number_ENTITIES( BODY_ptr, num_vol_bef,
+ num_face_bef, num_edge_bef,
+ num_vertex_bef );
+
+ int num_vol_aft, num_face_aft, num_edge_aft, num_vertex_aft;
+ CubitStatus status2 = AcisQueryEngine::instance()->number_ENTITIES( copied_BODY, num_vol_aft,
+ num_face_aft, num_edge_aft,
+ num_vertex_aft );
+
+ if( status1 == CUBIT_FAILURE ||
+ status2 == CUBIT_FAILURE )
+ {
+ return CUBIT_FAILURE;
+ }
+
+ if( num_vol_bef == num_vol_aft &&
+ num_face_bef == num_face_aft &&
+ num_edge_bef == num_edge_aft &&
+ num_vertex_bef == num_vertex_aft)
+ {
+ AcisQueryEngine::instance()->delete_ACIS_BODY(copied_BODY, CUBIT_TRUE);
+ return CUBIT_FAILURE;
+ }
+
+ // Get the new entities (just edges for now)
+ // created by the imprint operation.
+ DLIList<ENTITY*> new_ENTITIES, att_ENTITIES;
+ if(copied_BODY && new_tbs)
+ get_new_ENTITIES(copied_BODY, new_ENTITIES);
+
+ BodySM* new_body_ptr = get_new_Body( old_body_sm, BODY_ptr, copied_BODY,
+ false, CUBIT_TRUE );
+ if (new_body_ptr)
+ {
+ // Get entities with composite attributes.
+ if(copied_BODY && att_tbs)
+ get_att_ENTITIES(copied_BODY, att_ENTITIES, "COMPOSITE_GEOM");
+ }
+ else
+ {
+ // Get entities with composite attributes.
+ if(att_tbs)
+ get_att_ENTITIES(BODY_ptr, att_ENTITIES, "COMPOSITE_GEOM");
+ }
+
+ // Convert the new_ENTITIES/att_ENTITIES lists into
+ // topology bridge lists.
+ if(new_tbs)
+ {
+ for(i=new_ENTITIES.size(); i--;)
+ {
+ ENTITY *cur_ENT = new_ENTITIES.get_and_step();
+ AcisBridge *acis_bridge = ATTRIB_CUBIT_OWNER::cubit_owner(cur_ENT);
+ if(dynamic_cast<TopologyBridge*>(acis_bridge))
+ new_tbs->append_unique(dynamic_cast<TopologyBridge*>(acis_bridge));
+ }
+ }
+ if(att_tbs)
+ {
+ for(i=att_ENTITIES.size(); i--;)
+ {
+ ENTITY *cur_ENT = att_ENTITIES.get_and_step();
+ AcisBridge *acis_bridge = ATTRIB_CUBIT_OWNER::cubit_owner(cur_ENT);
+ if(dynamic_cast<TopologyBridge*>(acis_bridge))
+ att_tbs->append_unique(dynamic_cast<TopologyBridge*>(acis_bridge));
+ }
+ }
+
+ new_body = new_body_ptr;
+ return CUBIT_SUCCESS;
+}
+
CubitStatus AcisModifyEngine::curve_surface_intersection( Surface *surface,
Curve* curve,
DLIList<Curve*> &new_curves ) const
@@ -15753,13 +18377,12 @@
FACE *FACE_ptr = AcisQueryEngine::get_FACE( surface );
EDGE *EDGE_ptr = AcisQueryEngine::get_EDGE( curve );
- ENTITY_LIST *ent_list = new ENTITY_LIST;
+ ENTITY_LIST *ent_list = new ENTITY_LIST;
outcome result = api_edfa_int( EDGE_ptr, FACE_ptr, ent_list );
if( !result.ok() || ent_list->count() == 0 )
{
- delete ent_list;
return CUBIT_FAILURE;
}
@@ -15774,55 +18397,88 @@
new_curves.append( curve_ptr );
}
}
- delete ent_list;
-
- if( new_curves.size() == 0 )
- return CUBIT_FAILURE;
-
+
+ if( ent_list )
+ ACIS_DELETE ent_list;
+
return CUBIT_SUCCESS;
}
-void AcisModifyEngine::get_new_ENTITIES(ENTITY *top_ENTITY, DLIList<ENTITY*> &new_ENTITIES) const
+void AcisModifyEngine::get_new_ENTITIES(ENTITY *top_ENTITY, DLIList<ENTITY*> &new_ENTITIES,
+ DLIList<DLIList<EDGE*>*> *lists_of_EDGES_on_original_FACES,
+ DLIList<DLIList<EDGE*>*> *imprint_EDGE_lists) const
{
ENTITY_LIST ENTITIES;
- int i;
+ int i, j, k;
// vertices
api_get_vertices( top_ENTITY, ENTITIES);
for (i = 0; i < ENTITIES.count(); i++)
{
if (!ATTRIB_CUBIT_OWNER::cubit_owner(ENTITIES[i]))
- {
new_ENTITIES.append_unique(ENTITIES[i]);
- }
}
ENTITIES.clear();
// edges
- api_get_edges( top_ENTITY, ENTITIES);
+ api_get_edges(top_ENTITY, ENTITIES);
for (i = 0; i < ENTITIES.count(); i++)
{
if (!ATTRIB_CUBIT_OWNER::cubit_owner(ENTITIES[i]))
{
new_ENTITIES.append_unique(ENTITIES[i]);
+
+ // Now that we have determined this entity is new remove it
+ // form this lists we will use below in further checks.
+ if(lists_of_EDGES_on_original_FACES)
+ {
+ for(j=lists_of_EDGES_on_original_FACES->size(); j--;)
+ {
+ DLIList<EDGE*> *cur_list = lists_of_EDGES_on_original_FACES->get_and_step();
+ if(cur_list->move_to((EDGE*)ENTITIES[i]))
+ cur_list->extract();
+ }
+ }
}
}
ENTITIES.clear();
-/*
+ if(lists_of_EDGES_on_original_FACES &&
+ lists_of_EDGES_on_original_FACES->size() &&
+ lists_of_EDGES_on_original_FACES->size() == imprint_EDGE_lists->size())
+ {
+ for(j=imprint_EDGE_lists->size(); j--;)
+ {
+ DLIList<EDGE*> *cur_original_EDGE_list = lists_of_EDGES_on_original_FACES->get_and_step();
+ DLIList<EDGE*> *cur_imprint_EDGE_list = imprint_EDGE_lists->get_and_step();
+ for(i=cur_imprint_EDGE_list->size(); i--;)
+ {
+ EDGE *cur_imprint_EDGE = cur_imprint_EDGE_list->get_and_step();
+ for(k=cur_original_EDGE_list->size(); k--;)
+ {
+ EDGE *cur_orig_EDGE = cur_original_EDGE_list->get_and_step();
+ if(AcisQueryEngine::instance()->about_spatially_equal(cur_imprint_EDGE,
+ cur_orig_EDGE))
+ {
+ new_ENTITIES.append_unique((ENTITY*)cur_orig_EDGE);
+ new_ENTITIES.append_unique((ENTITY*)cur_orig_EDGE->start());
+ new_ENTITIES.append_unique((ENTITY*)cur_orig_EDGE->end());
+ }
+ }
+ }
+ }
+ }
+
// faces
api_get_faces( top_ENTITY, ENTITIES);
for (i = 0; i < ENTITIES.count(); i++)
{
if (!ATTRIB_CUBIT_OWNER::cubit_owner(ENTITIES[i]))
- {
new_ENTITIES.append_unique(ENTITIES[i]);
- }
}
ENTITIES.clear();
- */
}
-void AcisModifyEngine::get_att_ENTITIES(ENTITY *top_ENTITY, DLIList<ENTITY*> &att_ENTITIES, char *att_name) const
+void AcisModifyEngine::get_att_ENTITIES(ENTITY *top_ENTITY, DLIList<ENTITY*> &att_ENTITIES, const char *att_name) const
{
ENTITY_LIST ENTITIES;
int i;
@@ -15890,10 +18546,21 @@
double sliver_curve_tol = GeometryQueryTool::get_sliver_curve_cleanup_tolerance();
double sliver_surface_tol = GeometryQueryTool::get_sliver_surface_cleanup_tolerance();
- ENTITY_LIST dummy_list;
- api_detect_short_edges( body_to_cleanup, dummy_list, sliver_curve_tol, true );
- api_detect_sliver_faces( body_to_cleanup, dummy_list, sliver_surface_tol, true );
+ ENTITY_LIST ents_to_remove;
+ api_detect_short_edges( body_to_cleanup, ents_to_remove, sliver_curve_tol, true );
+ //put no-merge attributes on all vertices so that irrelevant vertices do not
+ //get inadvertantly removed (regularized out)
+ ENTITY_LIST body_verts;
+ api_get_vertices( body_to_cleanup, body_verts );
+ api_set_no_merge_attrib( body_verts );
+
+ api_detect_sliver_faces( body_to_cleanup, ents_to_remove, sliver_surface_tol, true );
+
+ body_verts.clear();
+ api_get_vertices( body_to_cleanup, body_verts );
+ api_remove_no_merge_attrib( body_verts );
+
return CUBIT_SUCCESS;
}
@@ -15927,7 +18594,7 @@
if( removed_curves.count() == 0 )
{
api_delent( (ENTITY*)copy_BODY );
- return CUBIT_SUCCESS;
+ return CUBIT_FAILURE;
}
get_new_Body(body_sm, tmp_BODY, copy_BODY, CUBIT_FALSE);
@@ -15935,6 +18602,7 @@
return CUBIT_SUCCESS;
}
+
CubitStatus AcisModifyEngine::stitch_surfs(
DLIList<BodySM*>& surf_bodies,
BodySM*& stitched_body)const
@@ -15986,24 +18654,1749 @@
return CUBIT_SUCCESS;
}
- CubitStatus AcisModifyEngine::trim_up_to_next_surface(BodySM*& tool_body,
- DLIList<BodySM*> bodies,
- GeometryEntity * surf_vert)
+CubitStatus AcisModifyEngine::remove_topology(DLIList<Curve*> &curves_to_remove,
+ DLIList<Surface*> &surfs_to_remove,
+ double backoff_distance,
+ double small_edge_size,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean preview) const
+{
+ return AcisTweakTool::instance()->remove_topology( curves_to_remove, surfs_to_remove,
+ backoff_distance, small_edge_size, new_bodysm_list, preview);
+
+}
+
+
+
+
+CubitStatus AcisModifyEngine::imprint_overlapping_curves( DLIList<BodySM*> &body_sms,
+ DLIList<BodySM*> &new_body_sms,
+ ProgressTool *progress_tool,
+ DLIList<TopologyBridge*> *new_tbs,
+ DLIList<TopologyBridge*> *att_tbs ) const
+{
+ //find all mergeable curves between the bodies
+#ifdef BOYD16
+ DLIList<RefEntity*> entities;
+#endif
+ DLIList< DLIList<Curve*>* > lists_of_mergeable_curves;
+
+ MergeTool::instance()->find_only_mergeable_curves( body_sms, lists_of_mergeable_curves );
+
+ int i;
+ //increment 4%
+ if( progress_tool )
+ {
+ for( i=4; i--; )
+ progress_tool->step();
+ }
+
+ //find all overlapping curves between the bodies
+ std::map<Curve*, DLIList<Curve*>* > curve_to_list_map;
+ DLIList< DLIList<Curve*>* > lists_of_overlapping_curves;
+ std::multimap<BodySM*, CubitVector> body_vertex_imprint_map;
+ //for each list, curves 2-n overlap the first curve
+
+ SurfaceOverlapTool::instance()->find_overlapping_curves( body_sms, lists_of_overlapping_curves,
+ curve_to_list_map,
+ body_vertex_imprint_map);
+
+ //increment 8%
+ if( progress_tool )
+ {
+ for( i=9; i--; )
+ progress_tool->step();
+ }
+
+ return imprint_overlapping_curves(lists_of_mergeable_curves,
+ lists_of_overlapping_curves,
+ curve_to_list_map,
+ body_vertex_imprint_map,
+ new_body_sms,
+ progress_tool,
+ new_tbs,
+ att_tbs );
+
+}
+
+CubitStatus AcisModifyEngine::tolerant_imprint(DLIList<Surface*> &surfs_in,
+ DLIList<BodySM*> &new_bodysm_list) const
+{
+ DLIList<Surface*> new_surface_list;
+
+ CubitStatus status = imprint_overlapping_curves(surfs_in, new_bodysm_list);
+
+ status = imprint_overlapping_surfaces(surfs_in, new_bodysm_list, &new_surface_list);
+
+ // The surface may have been blown away by this point so don't do this last one.
+ // I may need to change things so that I pass in the body so I can get the new
+ // surf and still call this but for now I just won't call it.
+// status = imprint_overlapping_curves(surfs_in, new_bodysm_list);
+ status = imprint_overlapping_curves(new_surface_list, new_bodysm_list);
+
+ return CUBIT_SUCCESS;
+}
+
+
+CubitStatus AcisModifyEngine::imprint_overlapping_curves(DLIList<Surface*> &surfs,
+ DLIList<BodySM*> &new_body_sms) const
+{
+ //find all mergeable curves between the bodies
+ DLIList< DLIList<Curve*>* > lists_of_mergeable_curves;
+
+ MergeTool::instance()->find_only_mergeable_curves(surfs, lists_of_mergeable_curves);
+
+ //find all overlapping curves between the bodies
+ std::map<Curve*, DLIList<Curve*>* > curve_to_list_map;
+ DLIList< DLIList<Curve*>* > lists_of_overlapping_curves;
+ std::multimap<BodySM*, CubitVector> body_vertex_imprint_map;
+ //for each list, curves 2-n overlap the first curve
+
+ SurfaceOverlapTool::instance()->find_overlapping_curves(surfs, lists_of_overlapping_curves,
+ curve_to_list_map, body_vertex_imprint_map );
+
+ return imprint_overlapping_curves(lists_of_mergeable_curves,
+ lists_of_overlapping_curves,
+ curve_to_list_map,
+ body_vertex_imprint_map,
+ new_body_sms,
+ NULL,
+ NULL,
+ NULL );
+}
+CubitStatus AcisModifyEngine::imprint_overlapping_surfaces( DLIList<Surface*> &surfs,
+ DLIList<BodySM*> &new_bodysm_list,
+ DLIList<Surface*> *new_surface_list) const
+{
+ //Find all overlapping surfaces between the bodies
+ DLIList<Surface*> overlapping_surfaces1;
+ DLIList<Surface*> overlapping_surfaces2;
+
+ overlapping_surfaces1.append(surfs.get_and_step());
+ overlapping_surfaces2.append(surfs.get());
+
+ return imprint_overlapping_surfaces(overlapping_surfaces1, overlapping_surfaces2, new_bodysm_list,
+ NULL, new_surface_list);
+}
+
+CubitStatus AcisModifyEngine::imprint_overlapping_surfaces( DLIList<BodySM*> &body_sms,
+ DLIList<BodySM*> &new_body_sms,
+ ProgressTool *progress_tool) const
+{
+ //Find all mergeable surfaces between the bodies
+ DLIList< DLIList<Surface*>* > lists_of_mergeable_surfaces;
+ /*CubitStatus status =*/ MergeTool::instance()->
+ find_only_mergeable_surfaces( body_sms, lists_of_mergeable_surfaces );
+
+ if( progress_tool )
+ progress_tool->percent( 0.24 );
+
+ //Find all overlapping surfaces between the bodies
+ DLIList<Surface*> overlapping_surfaces1;
+ DLIList<Surface*> overlapping_surfaces2;
+ SurfaceOverlapTool::instance()->
+ find_overlapping_surfaces( body_sms, overlapping_surfaces1, overlapping_surfaces2 );
+
+ if( progress_tool )
+ progress_tool->percent( 0.57 );
+
+ //We only want the non-mergeable overlapping surfaces.
+ //Remove mergable surfaces from overlapping pairs.
+ int i, j;
+ for( i=lists_of_mergeable_surfaces.size(); i--; )
+ {
+ DLIList<Surface*> *tmp_surface_list = lists_of_mergeable_surfaces.get_and_step();
+ for( j=tmp_surface_list->size(); j--; )
{
- assert(tool_body);
- assert(surf_vert);
- BODY* tool_BODY = AcisQueryEngine::get_BODY( tool_body );
- if (tool_BODY == NULL)
- return CUBIT_FAILURE;
+ Surface *tmp_surface = tmp_surface_list->get_and_step();
+ while( overlapping_surfaces1.move_to( tmp_surface ) )
+ overlapping_surfaces1.change_to(NULL);
+ while( overlapping_surfaces2.move_to( tmp_surface ) )
+ overlapping_surfaces2.change_to(NULL);
+ }
+ delete tmp_surface_list;
+ }
- Point * vertex = CAST_TO(surf_vert, Point);
- if (!vertex)
- return CUBIT_FAILURE;
- VERTEX * VERTEX_ptr = AcisQueryEngine::get_VERTEX(vertex);
+ if( progress_tool )
+ progress_tool->percent( 0.59 );
- CubitStatus stat= trim_up_to_next_surface(tool_BODY, bodies, VERTEX_ptr);
- if (stat)
- tool_body = AcisQueryEngine::instance()->populate_topology_bridges(tool_BODY);
+ return imprint_overlapping_surfaces(overlapping_surfaces1, overlapping_surfaces2,
+ new_body_sms, progress_tool);
+}
- return stat;
+CubitStatus
+AcisModifyEngine::remove_FACEs_from_BODY( BODY *BODY_ptr,
+ DLIList<FACE*> &remove_FACE_list,
+ CubitBoolean silent )
+{
+ if( remove_FACE_list.size() == 0 )
+ return CUBIT_SUCCESS;
+
+ // Need special handling if BODY is solid
+ bool is_closed = false;
+ if( is_closed_solid_body( BODY_ptr ) )
+ is_closed = true;
+
+ int i;
+ outcome result;
+ bool old_flg = ATTRIB_CUBIT_OWNER::set_split_copy( true );
+ //ENTITY_LIST faces_to_remove;
+ FACE *FACE_ptr;
+ for( i=remove_FACE_list.size(); i--; )
+ {
+ FACE_ptr = remove_FACE_list.get_and_step();
+ if( !FACE_ptr )
+ continue;
+ //faces_to_remove.add( FACE_ptr );
+ result = api_remove_face( FACE_ptr );
+ if( !result.ok() )
+ {
+ ATTRIB_CUBIT_OWNER::set_split_copy( old_flg );
+ if( !silent) AcisQueryEngine::instance()->ACIS_API_error(result);
+ return CUBIT_FAILURE;
}
+ }
+ ATTRIB_CUBIT_OWNER::set_split_copy( old_flg );
+
+ // This doesn't work, because all attributes are removed from the input body,
+ // even if we copy attributes during a split (set_split_copy). I think this
+ // would be faster than the method we are using. This could be an acis bug..
+ //ENTITY_LIST unhooked_bodies;
+ //result = api_unhook_faces( faces_to_remove, false, unhooked_bodies );
+ //unhooked_bodies.init();
+ //ENTITY *ENTITY_ptr = NULL;
+ //while( ENTITY_ptr = unhooked_bodies.next() )
+ // api_delent( ENTITY_ptr );
+ //if( !result.ok() )
+ //{
+ // AQE->ACIS_API_error(result);
+ // return CUBIT_FAILURE;
+ //}
+
+ // If we removed a FACE from a solid BODY, we need to make the remaining
+ // FACEs 2D
+ if( is_closed == true )
+ {
+ result = api_body_to_2d( BODY_ptr );
+ if( !result.ok() )
+ {
+ if( !silent) AcisQueryEngine::instance()->ACIS_API_error(result);
+ return CUBIT_FAILURE;
+ }
+ }
+
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus
+AcisModifyEngine::remove_FACEs_from_BODY_except( BODY *BODY_ptr,
+ DLIList<FACE*> &keep_FACE_list,
+ CubitBoolean silent )
+{
+ DLIList<FACE*> FACE_list;
+ AcisQueryEngine::instance()->get_FACEs( BODY_ptr, FACE_list );
+
+ DLIList<FACE*> remove_FACE_list;
+ int i;
+ FACE *FACE_ptr;
+ for( i=FACE_list.size(); i--; )
+ {
+ FACE_ptr = FACE_list.get_and_step();
+ if( !FACE_ptr )
+ continue;
+ if( !keep_FACE_list.is_in_list( FACE_ptr ) )
+ remove_FACE_list.append( FACE_ptr );
+ }
+
+ return remove_FACEs_from_BODY( BODY_ptr, remove_FACE_list, silent );
+}
+
+CubitStatus
+AcisModifyEngine::remove_dup_owners( BODY *ref_BODY_ptr, BODY *BODY_ptr )
+{
+ // Check BODIEs, LUMPs, SHELLs, FACEs, LOOPs, COEDGEs, EDGEs, VERTICEs
+ remove_dup_owners( ref_BODY_ptr, BODY_ptr, BODY_TYPE );
+ remove_dup_owners( ref_BODY_ptr, BODY_ptr, LUMP_TYPE );
+ remove_dup_owners( ref_BODY_ptr, BODY_ptr, SHELL_TYPE );
+ remove_dup_owners( ref_BODY_ptr, BODY_ptr, FACE_TYPE );
+ remove_dup_owners( ref_BODY_ptr, BODY_ptr, LOOP_TYPE );
+ remove_dup_owners( ref_BODY_ptr, BODY_ptr, COEDGE_TYPE );
+ remove_dup_owners( ref_BODY_ptr, BODY_ptr, EDGE_TYPE );
+ remove_dup_owners( ref_BODY_ptr, BODY_ptr, VERTEX_TYPE );
+
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus
+AcisModifyEngine::remove_dup_owners( BODY *ref_BODY_ptr, BODY *BODY_ptr,
+ const int type )
+{
+ if( type == BODY_TYPE )
+ {
+ if( ATTRIB_CUBIT_OWNER::cubit_owner(ref_BODY_ptr) ==
+ ATTRIB_CUBIT_OWNER::cubit_owner(BODY_ptr))
+ ATTRIB_CUBIT_OWNER::remove_cubit_owner(BODY_ptr);
+ return CUBIT_SUCCESS;
+ }
+
+ outcome result;
+ ENTITY *ENTITY_ptr;
+ AcisBridge* ab_ptr;
+
+ // Use a map
+ std::map<AcisBridge*, ENTITY*>::iterator iter;
+ std::map<AcisBridge*, ENTITY*> ref_map; // <map key, type>
+ ENTITY_LIST ENTs;
+
+ // Get the entities of the reference BODY into the map
+
+ // More elegant would be to use a function pointer, if I could get it to work
+ if( type==LUMP_TYPE )
+ result = api_get_lumps( ref_BODY_ptr, ENTs );
+ else if( type==SHELL_TYPE )
+ result = api_get_shells( ref_BODY_ptr, ENTs );
+ else if( type==FACE_TYPE )
+ result = api_get_faces( ref_BODY_ptr, ENTs );
+ else if( type==LOOP_TYPE )
+ result = api_get_loops( ref_BODY_ptr, ENTs );
+ else if( type==COEDGE_TYPE )
+ result = api_get_coedges( ref_BODY_ptr, ENTs );
+ else if( type==EDGE_TYPE )
+ result = api_get_edges( ref_BODY_ptr, ENTs );
+ else if( type==VERTEX_TYPE )
+ result = api_get_vertices( ref_BODY_ptr, ENTs );
+ else
+ {
+ PRINT_ERROR( "Invalid entity type encountered\n" );
+ return CUBIT_FAILURE;
+ }
+ if( !result.ok() )
+ return CUBIT_FAILURE;
+
+ // Populate the reference BODY map
+ ENTs.init();
+ while( (ENTITY_ptr = ENTs.next() ) != NULL )
+ {
+ ab_ptr = ATTRIB_CUBIT_OWNER::cubit_owner(ENTITY_ptr);
+ if( ab_ptr )
+ ref_map.insert(std::map<AcisBridge*, ENTITY*>::value_type(
+ ab_ptr, ENTITY_ptr ) );
+ }
+
+ // Loop through the entities of the other BODY, looking for duplicate cubit
+ // owners.
+ ENTs.clear();
+ if( type==LUMP_TYPE )
+ result = api_get_lumps( BODY_ptr, ENTs );
+ else if( type==SHELL_TYPE )
+ result = api_get_shells( BODY_ptr, ENTs );
+ else if( type==FACE_TYPE )
+ result = api_get_faces( BODY_ptr, ENTs );
+ else if( type==LOOP_TYPE )
+ result = api_get_loops( BODY_ptr, ENTs );
+ else if( type==COEDGE_TYPE )
+ result = api_get_coedges( BODY_ptr, ENTs );
+ else if( type==EDGE_TYPE )
+ result = api_get_edges( BODY_ptr, ENTs );
+ else if( type==VERTEX_TYPE )
+ result = api_get_vertices( BODY_ptr, ENTs );
+ else
+ {
+ PRINT_ERROR( "Invalid entity type encountered\n" );
+ return CUBIT_FAILURE;
+ }
+ if( !result.ok() )
+ return CUBIT_FAILURE;
+ ENTs.init();
+ while( (ENTITY_ptr = ENTs.next() ) != NULL )
+ {
+ ab_ptr = ATTRIB_CUBIT_OWNER::cubit_owner(ENTITY_ptr);
+ if( ab_ptr )
+ {
+ iter = ref_map.find( ab_ptr );
+ if( iter != ref_map.end() )
+ ATTRIB_CUBIT_OWNER::remove_cubit_owner(ENTITY_ptr);
+ }
+ }
+
+ return CUBIT_SUCCESS;
+}
+
+//=============================================================================
+// Function : trim_BODY_to_box
+// Member Type: PRIVATE
+// Description: Trim the given BODY to fit within the given CubitBox.
+// Author : Steve Storm
+// Date : 2/15/07
+//=============================================================================
+CubitStatus
+AcisModifyEngine::trim_BODY_to_box( BODY *&BODY_ptr, CubitBox &box ) const
+{
+ // Work on a copy of the box
+ CubitBox box_copy = box;
+
+ // Special case for planar situation. Technically, this is not correct but
+ // we can't create a brick with a zero dimension. Usually, if we have a zero
+ // dimension, we are dealing with a planar model, so it is valid to expand
+ // out like this... in that case we get the correct end result.
+ double box_tol = 1e-6;
+ if( (fabs(box.x_range())<box_tol) ||
+ (fabs(box.y_range())<box_tol) ||
+ (fabs(box.z_range())<box_tol) )
+ {
+ // Arbitrarily make the zero length side 1/10th the shortest side
+ double x = box.x_range();
+ double y = box.y_range();
+ double z = box.z_range();
+ double range;
+
+ if( fabs(x)<box_tol )
+ {
+ if( y<=z )
+ range = y/10.0;
+ else
+ range = z/10.0;
+ }
+ else if( fabs(y)<box_tol )
+ {
+ if( x<=z )
+ range = x/10.0;
+ else
+ range = z/10.0;
+ }
+ else // fabs(z)<box_tol
+ {
+ if( x<=y )
+ range = x/10.0;
+ else
+ range = y/10.0;
+ }
+
+ CubitVector box_center = box.center();
+ if( fabs(x)<box_tol )
+ {
+ box_copy |= (box_center + CubitVector(range, 0.0, 0.0));
+ box_copy |= (box_center - CubitVector(range, 0.0, 0.0));
+ }
+ else if( fabs(y)<box_tol )
+ {
+ box_copy |= (box_center + CubitVector(0.0, range, 0.0));
+ box_copy |= (box_center - CubitVector(0.0, range, 0.0));
+ }
+ else // fabs(z)<box_tol
+ {
+ box_copy |= (box_center + CubitVector(0.0, 0.0, range));
+ box_copy |= (box_center - CubitVector(0.0, 0.0, range));
+ }
+ }
+
+ // Setup a brick
+ CubitVector axes[3];
+ CubitVector extension;
+ axes[0].set( 1.0, 0.0, 0.0 );
+ axes[1].set( 0.0, 1.0, 0.0 );
+ axes[2].set( 0.0, 0.0, 1.0 );
+ extension.set( box_copy.x_range()/2.0, box_copy.y_range()/2.0,
+ box_copy.z_range()/2.0 );
+
+ // Create a brick
+ BODY *brick_ptr = make_brick_BODY( box_copy.center(), axes, extension );
+ if( !brick_ptr )
+ return CUBIT_FAILURE;
+
+ // Intersect the brick and BODY (note this will destroy the brick)
+ outcome result = api_boolean( brick_ptr, BODY_ptr, INTERSECTION );
+ if( !result.ok() )
+ {
+ api_delent( brick_ptr );
+ return CUBIT_FAILURE;
+ }
+
+ // Make sure there is something left
+ if( BODY_ptr == NULL ||
+ BODY_ptr->lump() == NULL ||
+ BODY_ptr->lump()->shell() == NULL ||
+ BODY_ptr->lump()->shell()->first_face() == NULL ||
+ BODY_ptr->lump()->shell()->first_face()->geometry() == NULL )
+ {
+ if( BODY_ptr )
+ api_delent( BODY_ptr );
+ BODY_ptr = NULL;
+ }
+
+ return CUBIT_SUCCESS;
+}
+
+int stitch_process_callback( stitch_progress_info *progress_info )
+{
+ double progress = progress_info->percentage()/100.0;
+ AppUtil::instance()->progress_tool()->percent( progress );
+ return 0;
+}
+
+CubitStatus AcisModifyEngine::stitch( DLIList<BodySM*> &bodies_to_stitch,
+ DLIList<BodySM*> &new_bodies,
+ bool tighten_gaps,
+ double tolerance ) const
+{
+ ENTITY_LIST bodies_in;
+ DLIList<BODY*> original_BODYs;
+ //get all the underlying ACIS bodies from bodies_to_stitch
+ int i;
+ for( i=bodies_to_stitch.size(); i--; )
+ {
+ BodySM *tmp_body = bodies_to_stitch.get_and_step();
+ BodyACIS* body_acis = CAST_TO(tmp_body, BodyACIS );
+
+ BODY *original_BODY = body_acis->get_BODY_ptr();
+ original_BODYs.append( original_BODY );
+
+ BODY *copied_BODY = this->copy_BODY( original_BODY );
+ bodies_in.add( copied_BODY );
+ }
+
+ ENTITY_LIST new_body_list;
+ CubitStatus stat = stitch_simplify_and_tighten_gaps( bodies_in, new_body_list, tighten_gaps, tolerance );
+
+ if( stat == CUBIT_FAILURE )
+ return stat;
+
+ ENTITY *tmp_ent=NULL;
+ DLIList<BODY*>new_BODYs;
+ new_body_list.init();
+ while( NULL != (tmp_ent = new_body_list.next()))
+ new_BODYs.append( (BODY*)tmp_ent );
+
+ get_new_Body( bodies_to_stitch, original_BODYs, new_BODYs, new_bodies, false, true );
+
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus AcisModifyEngine::stitch_simplify_and_tighten_gaps(
+ ENTITY_LIST& bodies_imported_into_ACIS,
+ ENTITY_LIST& output_bodies,
+ bool tighten_gaps,
+ double tolerance )const
+{
+ // **************************************************************
+ // Step 1 : Tolerant Stitching
+ // (call api_stitch with tolerant_stitch_options)
+ // **************************************************************
+
+ if( tolerance == -1 )
+ tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS;
+
+ bool stitch = true;
+ if(stitch)
+ {
+ // Create a default tolerant_stitch_options object.
+ tolerant_stitch_options sopts;
+
+ // Set the stitcher coincident face identification routine
+ // to SPASTITCH_COIN_SKIP to skip stitching coincident faces.
+ STITCH_COIN_MODES mode = SPASTITCH_COIN_SKIP;
+ sopts.set_stch_coincident_face_handling_mode(mode);
+
+ // Determine and set max-stitch-tol for stitching.
+ sopts.set_max_stitch_tol( tolerance );
+
+ // Call User's function to stitch list of entities
+ if( stitch_entities(bodies_imported_into_ACIS, output_bodies, sopts) == CUBIT_FAILURE )
+ {
+ output_bodies.clear();
+ return CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ output_bodies = bodies_imported_into_ACIS;
+ }
+
+ // **************************************************************
+ // Step 2 : Simplification
+ // (call api_simplify_entity)
+ // **************************************************************
+
+ // Determine the desired gap tightness ("desired_gap_tightness")
+ // of the user's downstream application (like manufacturing).
+ bool simplification = true;
+ if(simplification)
+ {
+ // A user may want to simplify each stitched BODY in the "output_bodies" list.
+ // Create default simplify_options object. A default simplify_options object
+ // will do both curve and surface simplification based on the default value of
+ // simplification tolerance(SPAresabs).
+ simplify_options simp_opts;
+
+ // Choose a simplification tolerance. If the user desires the gaps in the model
+ // to be within a certain value, then that value could be the best value
+ // to use as simplification tolerance. So user may want to use the desired
+ // gap tightness as simplification tolerance. Set the simplification tolerance
+ // equal to the desired_gap_tightness value of the downstream application.
+ simp_opts.set_simplification_tol( tolerance );
+
+ // Call User's function to simplify each stitched body
+ ENTITY* entity_to_simplify = NULL;
+ output_bodies.init();
+ while (NULL != (entity_to_simplify = output_bodies.next()))
+ {
+ if( CUBIT_FAILURE == simplify_entity(entity_to_simplify, simp_opts) )
+ {
+ PRINT_ERROR("Tightening gaps failed, try healing beforehand.\n");
+ output_bodies.clear();
+ return CUBIT_FAILURE;
+ }
+ }
+ }
+
+ // **************************************************************
+ // Step 3 : Tighten Gaps to desired tightness
+ // (call api_tighten_gaps)
+ // **************************************************************
+ if(tighten_gaps)
+ {
+ // A user may want to tighten gaps in each of the stitched and simplified
+ // BODY so that the gaps in TEDGEs and TVERTEXs in
+ // the BODYs are within a "desired_gap_tightness" of the user's downstream
+ // application (like manufacturing).
+ BODY* body = NULL;
+ output_bodies.init();
+ while (NULL != (body = (BODY *)output_bodies.next()))
+ {
+ if( CUBIT_FAILURE == tighten_gaps_in_body(body, tolerance ) )
+ {
+ PRINT_ERROR("Tightening gaps failed, try healing beforehand.\n");
+ output_bodies.clear();
+ return CUBIT_FAILURE;
+ }
+ }
+ }
+
+ return CUBIT_SUCCESS;
+}
+
+// ************************************************************
+// User function to stitch a list of entities
+// ************************************************************
+CubitStatus AcisModifyEngine::stitch_entities(ENTITY_LIST& to_be_stitched,
+ ENTITY_LIST& output_bodies,
+ tolerant_stitch_options& sopts)const
+{
+ // ENTITY_LIST& new_bodies will contain all the new bodies resulting
+ // from the API api_stitch. This list will be a subset of
+ // ENTITY_LIST& output_bodies. This list is provided so that it is
+ // convenient to the caller to find out the new bodies that the caller
+ // will have to take ownership of (for example, the users may have to register
+ // new bodies in their application and/or do memory management for those bodies).
+ ENTITY_LIST new_bodies;
+
+ // Make the careful option OFF to enable failsafe behavior.
+ // Note: By default the "careful" option is already OFF
+ option_header *careful_opt = find_option("careful");
+ if (NULL != careful_opt)
+ careful_opt->push(FALSE);
+ // Note: To disable the failsafe behavior, set the "careful" option ON (push TRUE)
+
+ set_stitch_progress_callback( *stitch_process_callback );
+
+ AppUtil::instance()->progress_tool()->start(0, 100, "Stitching Progress:" );
+ // Make a call to api_stitch to stitch the entities in "to be stitched" list
+ outcome result_stch = api_stitch(to_be_stitched,
+ output_bodies,
+ new_bodies,
+ &sopts);
+
+ AppUtil::instance()->progress_tool()->end();
+
+ // Restore the original value of careful_opt
+ if (NULL != careful_opt)
+ careful_opt->pop();
+
+ // Check and handle fatal problems reported by api_stitch
+ // User code to handle failure and exit.
+ if ( TRUE == handle_fatal_problem_reported_by_outcome(result_stch) )
+ {
+ PRINT_ERROR("Stitching failed, try healing beforehand.\n");
+ return CUBIT_FAILURE;
+ }
+
+ /*
+ // User may want to know of the non fatal problems the API encoutered,
+ // and take corrective actions if any, before before proceeding to the next step.
+ //handle_problems_reported_by_outcome(result_stch);
+
+ // Pointer to an array of ENTITY_LIST pointers to store the coincident face
+ // cluster lists to allow list processing.
+ ENTITY_LIST* coin_face_list = NULL;
+
+ // Get the number of coincident faces clusters
+ int num_clusters = sopts.get_number_of_coincident_face_clusters();
+
+ // Check if coincident faces were detected
+ if ( num_clusters > 0 )
+ {
+ // Allocate memory based on the size of coincident face cluster list
+ coin_face_list = ACIS_NEW ENTITY_LIST[num_clusters];
+
+ // Now to go in a loop to collect each coincident face cluster
+ ENTITY_LIST* cluster = NULL;
+ int cluster_index = 0;
+ sopts.init_coincident_face_cluster_list();
+
+ while (NULL != (cluster = sopts.get_next_coincident_face_cluster()))
+ {
+ // deep copy list
+ coin_face_list[cluster_index] = *cluster;
+ cluster_index ++;
+ }
+
+ // Process each cluster (as an example, just print the size of each cluster).
+ // In practice, customers will probably want to exit to a handling routine
+ // which deletes items from the to_be_stitched list and recall api_stitch
+ // again. The user may need to keep retrying this step until no coincident
+ // faces are detected anymore.
+ int i=0;
+ for (i = 0; i < num_clusters; i++)
+ {
+ int num_faces = coin_face_list[i].count();
+ PRINT_INFO("Number of faces in cluster %d = %d", i, num_faces);
+ }
+
+ // Delete the coincident faces cluster list.
+ if ( coin_face_list != NULL )
+ {
+ ACIS_DELETE [] coin_face_list;
+ coin_face_list = NULL;
+ }
+ } // end braces for "num_clusters > 0"
+ */
+
+ return CUBIT_SUCCESS;
+}
+
+// ************************************************************
+// User function to simplify an ENTITY
+// ************************************************************
+CubitStatus AcisModifyEngine::simplify_entity(ENTITY*& entity_to_simplify,
+ simplify_options& simp_opts)const
+{
+ // Make the careful option OFF to enable failsafe behavior.
+ // Note: By default the "careful" option is already OFF
+ option_header *careful_opt = find_option("careful");
+ if (NULL != careful_opt)
+ careful_opt->push(FALSE);
+
+ // Call api_simplify_entity to simplify body.
+ outcome result_of_simplify = api_simplify_entity(entity_to_simplify, &simp_opts);
+
+ // Restore the original value of careful_opt
+ if (NULL != careful_opt)
+ careful_opt->pop();
+
+ // Check and handle fatal problems reported by api_simplify_entity
+ // User code to handle failure and exit.
+ if ( TRUE == handle_fatal_problem_reported_by_outcome(result_of_simplify) )
+ return CUBIT_FAILURE;
+
+ // User may want to know of the non fatal problems the
+ // api encoutered, and take corrective actions if any,
+ // before before proceeding to the next step.
+ // handle_problems_reported_by_outcome(result_of_simplify);
+
+ return CUBIT_SUCCESS;
+}
+
+// ************************************************************
+// User function to tighten gaps in BODY
+// ************************************************************
+CubitStatus AcisModifyEngine::tighten_gaps_in_body(BODY*& body,
+ const double& desired_gap_tightness)const
+{
+ // Make the careful option OFF to enable failsafe behavior.
+ // Note: By default the "careful" option is already OFF
+ option_header *careful_opt = find_option("careful");
+ if (NULL != careful_opt)
+ careful_opt->push(FALSE);
+
+ // Call api_tighten_gaps on body with desired_gap_tightness.
+ outcome result_of_gap_tightening = api_tighten_gaps(body,
+ desired_gap_tightness);
+
+ // Restore the original value of careful_opt
+ if (NULL != careful_opt)
+ careful_opt->pop();
+
+ // Check and handle fatal problems reported by api_tighten_gaps
+ // User code to handle failure and exit.
+ if ( TRUE == handle_fatal_problem_reported_by_outcome(result_of_gap_tightening) )
+ return CUBIT_FAILURE;
+
+ // User may want to know of the non fatal problems the
+ // api encoutered, and take corrective actions if any,
+ // before before proceeding to the next step.
+ //handle_problems_reported_by_outcome(result_of_gap_tightening);
+
+ return CUBIT_SUCCESS;
+}
+
+bool AcisModifyEngine::handle_fatal_problem_reported_by_outcome(const outcome& api_outcome)const
+{
+ logical fatal = FALSE;
+
+ // Handle fatal errors of api
+ if ( !api_outcome.ok() )
+ {
+ AcisQueryEngine::instance()->ACIS_API_error ( api_outcome );
+ // User may want to know about the fatal error due to
+ // which the API failed
+ error_info* einf = api_outcome.get_error_info();
+
+ // User code to report information on errors. A sample
+ // function "display_problems_encountered" for such
+ // reporting is given at the bottom of the code
+ // snippet
+ display_problems_encountered(einf);
+
+ // Reasons for error
+ if (einf->has_reasons())
+ {
+ // User code to mention that the following are
+ // reasons for the error, the user may print it as
+ // printf("Following are the reasons for the error:\n");
+
+ // error_info_list owns all the error_info
+ // objects inside it and cleans them up on
+ // destruction. User need not worry about memory
+ // cleanup of the error_info objects.
+ error_info_list reasons_eil;
+ einf->reasons(reasons_eil);
+ const error_info* reason_einf = NULL;
+ for (reasons_eil.init(); NULL != (reason_einf =
+ reasons_eil.next());)
+ {
+ display_problems_encountered(reason_einf);
+ }
+ }
+
+ fatal = TRUE;
+ }
+ return fatal;
+}
+
+void AcisModifyEngine::handle_problems_reported_by_outcome(const outcome& api_outcome) const
+{
+ if ( api_outcome.ok() )
+ {
+ // Problem reporting by API.
+ // API succeeded (either partially or fully) if this point
+ // is reached
+ error_info_list eil;
+ api_outcome.get_error_info_list(eil);
+ const error_info* einf = NULL;
+ for (eil.init(); NULL != (einf = eil.next());)
+ {
+ // User code to report information on problems. A
+ // sample function "display_problems_encountered" for
+ // such reporting is given at the bottom of the code
+ // snippet.
+ display_problems_encountered(einf);
+
+ // Reasons for the problem
+ if (einf->has_reasons())
+ {
+ // User code to mention that the following are
+ // reasons for the problem, the user may print it as
+ printf("Following are the reasons for the error:\n");
+
+ // error_info_list owns all the error_info
+ // objects inside it and cleans them up on
+ // destruction. User need not worry about memory
+ // cleanup of the error_info objects.
+ error_info_list reasons_eil;
+ einf->reasons(reasons_eil);
+ const error_info* reason_einf = NULL;
+ for (reasons_eil.init(); NULL != (reason_einf =
+ reasons_eil.next());)
+ {
+ display_problems_encountered(reason_einf);
+ }
+ }
+ }
+ }
+}
+
+// ************************************************************
+// User function to report information on problems
+// ************************************************************
+void AcisModifyEngine::display_problems_encountered(const error_info *einf) const
+{
+ if ( NULL == einf )
+ { return; }
+ char const *err_message = einf->error_message();
+ spa_outcome_severity_type err_severity = einf->severity();
+
+ // User code to display message and severity
+ // for example, the user might do the following
+
+ PRINT_INFO("Problem encountered: %s\n", err_message);
+ if (SPA_OUTCOME_FATAL == err_severity)
+
+ // Represents a fatal error
+
+ { PRINT_INFO("Severity: FATAL \n"); }
+ else if (SPA_OUTCOME_ERROR == err_severity)
+
+ // Represents an error encountered by a failsafe routine
+ // during an atomic operation
+
+ { PRINT_INFO("Severity: ERROR \n"); }
+ else if (SPA_OUTCOME_PROBLEM == err_severity)
+
+ // Represents a problem encountered during an operation
+
+ { PRINT_INFO("Severity: PROBLEM \n"); }
+ else if (SPA_OUTCOME_INSANITY == err_severity)
+
+ // Represents an insanity in the model
+
+ { PRINT_INFO("Severity: INSANITY \n"); }
+ int ent_id_cnt = get_error_info_entity_id_count(einf);
+
+ // If ent_id_cnt returns positive count,
+ // then einf has atleast one entity, dead or live
+
+ if ( 0 < ent_id_cnt && einf->type() == entity_error_info::id() )
+ {
+ const entity_error_info* ent_einf = (const entity_error_info *)einf;
+ if ( 0 ) /* the user wants to report problems on dead entities too ) */
+ // LIVE and DEAD entities
+ {
+ for (int i = 0; i < ent_id_cnt; i++)
+ {
+ tag_id_type ent_id = ent_einf->get_entity_id(i);
+ ENTITY *err_entity = NULL;
+ outcome res_get_ent = api_get_entity_from_id(ent_id, err_entity);
+ if ( !res_get_ent.ok() )
+ {
+ // Handle API failure and continue or exit as caller thinks suitable
+ }
+ if (NULL != err_entity) // err_entity is LIVE
+ {
+ // User code to report a live entity associated with a problem,
+ // for example the user may want to highlight the entity
+ }
+ else
+ {
+ // Report problem for a dead entity
+ }
+ }
+ }
+ else // Only LIVE entities
+ {
+ ENTITY_LIST live_entities;
+ ent_einf->get_entities_alive(live_entities);
+ ENTITY *live_err_entity = NULL;
+ for (live_entities.init(); NULL != (live_err_entity = live_entities.next()); )
+ {
+ // User code to report a live entity associated with a problem,
+ // for example the user may want to highlight the entity
+ }
+ }
+ }
+}
+
+CubitStatus AcisModifyEngine::finish_webcut(
+ BODY *tool_BODY,
+ DLIList<BodySM*> &original_bodysm_list, //original BodySMs of successfully webcut bodies
+ DLIList<BODY*> &original_BODY_list, //original ACIS BODYs
+ DLIList<BODY*> &new_webcut_BODY_list, //BODYs resulting from successful webcuts
+ DLIList<BodySM*> &neighbor_imprint_list, //neighbor BodySMs that need to be imprinted
+ //with bodies that were successfully webcut
+ ImprintType imprint_type,
+ DLIList<BodySM*> &results_list ) const
+{
+ CubitBoolean delete_bodies = (GeometryModifyTool::instance()->get_new_ids() ?
+ CUBIT_FALSE : CUBIT_TRUE);
+
+ int i,j;
+ DLIList<BodySM*> imprinted_neighbor_bodysms;
+ DLIList<BODY*> original_imprinted_neighbor_BODYs;
+ DLIList<BODY*> new_imprinted_neighbor_BODYs;
+
+ //normal imprint--w/ neighbors
+ if( imprint_type == ONLY_INVOLVED_BODIES ||
+ imprint_type == INCLUDE_NEIGHBORS )
+ {
+ BODY* first_BODY_ptr = NULL;
+ BODY* second_BODY_ptr = NULL;
+
+ //imprint only involved bodies first
+ for (i=0; i< (new_webcut_BODY_list.size() - 1); i++)
+ {
+ first_BODY_ptr = new_webcut_BODY_list.get_and_step();
+
+ for (j=(i + 1); j<new_webcut_BODY_list.size(); j++)
+ {
+ second_BODY_ptr = new_webcut_BODY_list.get_and_step();
+ imprint_BODYs( first_BODY_ptr, second_BODY_ptr );
+ }
+
+ new_webcut_BODY_list.reset() ;
+ new_webcut_BODY_list.step(i+1) ;
+ }
+
+ //now imprint with the neighbors
+ if( imprint_type == INCLUDE_NEIGHBORS )
+ {
+ // Loop over all the neighboring Bodies
+ for (i=neighbor_imprint_list.size(); i--;)
+ {
+ BODY *neighbor_BODY_copy = NULL;
+
+ // Get this existing Body's parent ACIS BODY
+ BodySM *neighbor_bodysm = neighbor_imprint_list.get_and_step() ;
+ BODY *neighbor_BODY= AcisQueryEngine::get_BODY(neighbor_bodysm) ;
+ if( neighbor_BODY == NULL )
+ continue;
+
+ //exclude the tool body from the neighbor imprint
+ if ((tool_BODY && neighbor_BODY == tool_BODY ) ||
+ original_bodysm_list.move_to(neighbor_bodysm))
+ {
+ // Don't do anything
+ continue;
+ }
+
+ for(j=new_webcut_BODY_list.size(); j--; )
+ {
+ BODY *new_webcut_BODY = new_webcut_BODY_list.get_and_step();
+
+ if ( BODYs_interfering(new_webcut_BODY, neighbor_BODY) == CUBIT_TRUE )
+ {
+ if ( neighbor_BODY_copy == NULL ) //Haven't made a copy yet
+ {
+ neighbor_BODY_copy = this->copy_BODY( neighbor_BODY,
+ GeometryModifyTool::instance()->get_new_ids());
+
+ if (neighbor_BODY_copy == NULL)
+ {
+ PRINT_ERROR("Cannot test imprinting for volume.\n" );
+ break;
+ }
+ else
+ {
+ imprinted_neighbor_bodysms.append( neighbor_bodysm );
+ original_imprinted_neighbor_BODYs.append( neighbor_BODY );
+ new_imprinted_neighbor_BODYs.append( neighbor_BODY_copy );
+ }
+ }
+
+ imprint_BODYs(new_webcut_BODY, neighbor_BODY_copy);
+
+ }
+ }
+ }
+ }
+ }
+
+
+ //Now create the new BodySMs
+ new_webcut_BODY_list.reset();
+ original_bodysm_list.reset();
+ original_BODY_list.reset();
+
+ for ( i=0; i<new_webcut_BODY_list.size(); i+=2 )
+ {
+ //Get the original BodySM and BODY
+ BodySM *old_Body = original_bodysm_list.get_and_step();
+ BODY *old_BODY = original_BODY_list.get_and_step();
+
+ //Get the resulting 2 BODYs
+ DLIList<BODY*> temp_BODY_list;
+ BODY *webcut_BODY_ptr = new_webcut_BODY_list.get_and_step();
+ temp_BODY_list.append(webcut_BODY_ptr);
+ webcut_BODY_ptr = new_webcut_BODY_list.get_and_step();
+ temp_BODY_list.append(webcut_BODY_ptr);
+
+ //Obtain the new BodySMs
+ DLIList<BodySM*> new_bodysm_list;
+ CubitStatus status = get_new_Body( old_Body, old_BODY,
+ temp_BODY_list, new_bodysm_list,
+ false, delete_bodies );
+
+ if (status == CUBIT_FAILURE)
+ PRINT_ERROR("Failed to build new volume in AGE::webcut.\n");
+
+ // if we didn't get any new bodies back from get_new_Body,
+ // that means that an imprinted body wasn't really imprinted
+ if (new_bodysm_list.size() > 0)
+ {
+ temp_BODY_list.reset();
+ new_bodysm_list.reset();
+ for (int j = 0; j < new_bodysm_list.size(); j++)
+ {
+ BodySM *new_body_ptr = new_bodysm_list.get_and_step();
+ results_list.append_unique(new_body_ptr);
+ }
+ }
+ }
+
+ //make new BodySMs if you have done normal imprinting w/ neighbors
+ if( imprint_type == INCLUDE_NEIGHBORS )
+ {
+ imprinted_neighbor_bodysms.reset();
+ original_imprinted_neighbor_BODYs.reset();
+ new_imprinted_neighbor_BODYs.reset();
+ for( i=imprinted_neighbor_bodysms.size(); i--; )
+ {
+ BodySM *original_bodysm = imprinted_neighbor_bodysms.get_and_step();
+ BODY *old_BODY = original_imprinted_neighbor_BODYs.get_and_step();
+ BODY *new_BODY = new_imprinted_neighbor_BODYs.get_and_step();
+
+ BodySM* new_Body = get_new_Body( original_bodysm, old_BODY, new_BODY,
+ false, true, true );
+ if (new_Body)
+ results_list.append(new_Body);
+ else
+ results_list.append(original_bodysm); //because unaltered bodies
+ //may need to be merged
+ }
+ }
+
+
+
+ //Tolerant imprinting
+ if( imprint_type == TOL_IMPRINT ||
+ imprint_type == TOL_IMPRINT_INCLUDE_NEIGHBORS )
+ {
+ //If any virtual geometry got modified, we cannot do
+ //subsequent tolerant imprinting. Check the model for any
+ //problems.
+ for( i=results_list.size(); i--; )
+ {
+ DLIList<Surface*> body_surfs;
+ BodySM *tmp_body = results_list.get_and_step();
+
+ tmp_body->surfaces( body_surfs );
+
+ int j;
+ for( j=body_surfs.size(); j--; )
+ {
+ Surface *tmp_surf = body_surfs.get_and_step();
+ DLIList<LoopSM*> tmp_loops;
+ tmp_surf->loopsms( tmp_loops );
+
+ int l;
+ for( l=tmp_loops.size(); l--; )
+ {
+ LoopSM* tmp_loop = tmp_loops.get_and_step();
+ DLIList<CoEdgeSM*> tmp_coedges;
+ tmp_loop->coedgesms( tmp_coedges );
+
+ int m;
+ for( m=tmp_coedges.size(); m--; )
+ {
+ DLIList<Curve*> tmp_curves;
+ CoEdgeSM *coedge = tmp_coedges.get_and_step();
+ coedge->curves( tmp_curves );
+ if( tmp_curves.size() == 0 )
+ {
+ PRINT_WARNING("Virtual geometry modified in webcut. Cannot do\n"
+ " subsequent tolerant imprinting\n" );
+ return CUBIT_SUCCESS;
+ }
+ }
+ }
+ }
+ }
+
+ results_list.reset();
+ double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS;
+
+ //imprint all new BodySMs with each other
+ for (i=0; i< (results_list.size() - 1); i++)
+ {
+ BodySM *bodysm_1 = results_list.get_and_step();
+ CubitBox bbox1 = bodysm_1->bounding_box();
+
+ for (j=(i + 1); j<results_list.size(); j++)
+ {
+ BodySM *bodysm_2 = results_list.get_and_step();
+ CubitBox bbox2 = bodysm_2->bounding_box();
+
+ if( bbox1.overlap( tolerance, bbox2 ) )
+ {
+ DLIList<BodySM*> bodies_in(2), bodies_out;
+ bodies_in.append( bodysm_1 );
+ bodies_in.append( bodysm_2 );
+ tolerant_imprint( bodies_in, bodies_out, NULL, NULL );
+ }
+ }
+ results_list.reset() ;
+ results_list.step(i+1) ;
+ }
+
+ if( imprint_type == TOL_IMPRINT_INCLUDE_NEIGHBORS )
+ {
+ DLIList<BodySM*> imprinted_neighbors;
+
+ for( i=neighbor_imprint_list.size(); i--; )
+ {
+ BodySM *neighbor_body = neighbor_imprint_list.get_and_step();
+ CubitBox neighbor_box = neighbor_body->bounding_box();
+
+ for( j=results_list.size(); j--; )
+ {
+ BodySM *webcut_body = results_list.get_and_step();
+ CubitBox bbox = webcut_body->bounding_box();
+
+ if( neighbor_box.overlap( tolerance, bbox ) )
+ {
+ DLIList<BodySM*> bodies_in(2), bodies_out;
+ bodies_in.append( neighbor_body );
+ bodies_in.append( webcut_body );
+ tolerant_imprint( bodies_in, bodies_out, NULL, NULL );
+ imprinted_neighbors.append_unique( neighbor_body );
+ }
+ }
+ }
+
+ results_list += imprinted_neighbors;
+ }
+ }
+
+ return CUBIT_SUCCESS;
+}
+
+
+void AcisModifyEngine::start_tracking_history( DLIList<TopologyBridge*> &bridges,
+ AcisHistory &history_object,
+ bool ignore_parents )
+{
+ GeometryQueryTool::instance()->history().clear();
+
+ //get all RefEntities from the bridges
+
+ bool debug = false;
+ int i,j;
+ for( i=bridges.size(); i--; )
+ {
+ //lets assume that it's a body we're modifying
+
+ DLIList<BodySM*> body_tbs;
+ DLIList<Lump*> lump_tbs;
+ DLIList<Surface*> surface_tbs;
+ DLIList<Curve*> curve_tbs;
+ DLIList<Point*> vertex_tbs;
+
+ TopologyBridge *tb = bridges.get_and_step();
+
+ //don't bother putting attribute on parents
+ if( ignore_parents )
+ {
+ //only the case if you have a surface, curve, or vertex
+ if( CAST_TO(tb, Surface ) )
+ {
+ tb->surfaces( surface_tbs );
+ tb->curves( curve_tbs );
+ tb->points( vertex_tbs );
+ }
+ else if( CAST_TO(tb, Curve) )
+ {
+ tb->curves( curve_tbs );
+ tb->points( vertex_tbs );
+ }
+ else if( CAST_TO(tb, Point ) )
+ tb->points( vertex_tbs );
+
+ }
+ else
+ {
+ tb->bodysms( body_tbs );
+ assert(body_tbs.size() == 1 );
+ body_tbs.get()->lumps( lump_tbs );
+ body_tbs.get()->surfaces( surface_tbs );
+ body_tbs.get()->curves( curve_tbs );
+ body_tbs.get()->points( vertex_tbs );
+ }
+
+ //Attach history attributes to all bodies, volumes, surfaces,
+ //curves and vertices
+
+ //bodies
+ for( j=body_tbs.size(); j--; )
+ {
+ //get the RefEntity
+ BodySM *bodysm = body_tbs.get_and_step();
+ TopologyEntity *te = bodysm->topology_entity();
+ RefEntity *ref_ent = CAST_TO( te, RefEntity );
+
+ if( NULL == ref_ent )
+ {
+ DLIList<TopologyBridge*> tbs;
+ GeometryQueryTool::instance()->get_tbs_with_bridge_manager_as_owner( bodysm, tbs );
+ te = tbs.get()->topology_entity();
+ ref_ent = CAST_TO( te, RefEntity );
+ }
+
+ //get the Acis ENTITY
+ ENTITY *entity = AcisQueryEngine::instance()->get_ENTITY_of_entity( bodysm );
+
+ //if there's an attribute there already, get rid of it
+ ATTRIB_HISTORY *att = ATTRIB_HISTORY::get_history_attrib( entity );
+ if( att && att->deletable() )
+ {
+ att->unhook();
+ att->lose();
+ }
+ else if( att )
+ {
+// att->unhook();
+// PRINT_INFO("---------------------Still have attrib around but can't delete it!\n");
+ }
+
+ //create the history attrib on the entity if it doesn't exist already
+ att = ATTRIB_HISTORY::get_history_attrib( entity, true, &history_object );
+ int tracking_id = history_object.generate_next_tracking_id();
+ att->add_tracking_id( tracking_id );
+ if( debug )
+ PRINT_INFO("RefEntity %s %d ---> ENTITY = %d w/ attrib %p\n",
+ ref_ent->class_name(), ref_ent->id(), tracking_id, att );
+ history_object.add_refentity_tracking_id_pair( ref_ent, tracking_id );
+ }
+
+ //lumps (volumes)
+ for( j=lump_tbs.size(); j--; )
+ {
+ //get the RefEntity
+ Lump *lump = lump_tbs.get_and_step();
+ TopologyEntity *te = lump->topology_entity();
+ RefEntity *ref_ent = CAST_TO( te, RefEntity );
+
+ //get the Acis ENTITY
+ ENTITY *entity = AcisQueryEngine::instance()->get_ENTITY_of_entity( lump );
+
+ //if there's an attribute there already, get rid of it
+ ATTRIB_HISTORY *att = ATTRIB_HISTORY::get_history_attrib( entity );
+ if( att && att->deletable() )
+ {
+ att->unhook();
+ att->lose();
+ }
+ else if( att )
+ {
+ // att->unhook();
+ PRINT_INFO("---------------------Still have attrib around but can't delete it!\n");
+ }
+
+ //create the history attrib on the entity if it doesn't exist already
+ att = ATTRIB_HISTORY::get_history_attrib( entity, true, &history_object );
+ int tracking_id = history_object.generate_next_tracking_id();
+ att->add_tracking_id( tracking_id );
+ if( debug )
+ PRINT_INFO("RefEntity %s %d ---> ENTITY = %d w/ attrib %p\n",
+ ref_ent->class_name(), ref_ent->id(), tracking_id, att );
+ history_object.add_refentity_tracking_id_pair( ref_ent, tracking_id );
+
+ //add ENTITY to list in case of failure
+ history_object.add_ENTITY( entity );
+ }
+
+ //surfaces
+ for( j=surface_tbs.size(); j--; )
+ {
+ //get the RefEntity
+ Surface *surf = surface_tbs.get_and_step();
+ TopologyEntity *te = surf->topology_entity();
+ RefEntity *ref_ent = CAST_TO( te, RefEntity );
+
+ //Check to see that the entity is a SurfaceACIS
+ SurfaceACIS *surf_acis = CAST_TO( surf, SurfaceACIS );
+ if( surf_acis )
+ {
+ //get the Acis ENTITY
+ ENTITY *entity = AcisQueryEngine::instance()->get_ENTITY_of_entity( surf );
+
+ //if there's an attribute there already, get rid of it
+ ATTRIB_HISTORY *att = ATTRIB_HISTORY::get_history_attrib( entity );
+ if( att && att->deletable() )
+ {
+ att->unhook();
+ att->lose();
+ }
+ else if( att )
+ {
+ // att->unhook();
+ PRINT_INFO("---------------------Still have attrib around but can't delete it!\n");
+ }
+
+ //create the history attrib on the entity if it doesn't exist already
+ att = ATTRIB_HISTORY::get_history_attrib( entity, true, &history_object );
+ int tracking_id = history_object.generate_next_tracking_id();
+ att->add_tracking_id( tracking_id );
+ if( debug )
+ PRINT_INFO("RefEntity %s %d ---> ENTITY = %d w/ attrib %p\n",
+ ref_ent->class_name(), ref_ent->id(), tracking_id, att );
+ history_object.add_refentity_tracking_id_pair( ref_ent, tracking_id );
+
+ //add ENTITY to list in case of failure
+ history_object.add_ENTITY( entity );
+ }
+ else
+ {
+ DLIList<TopologyBridge*> hidden_surfaces;
+ GeometryQueryEngine *gqe = surf->get_geometry_query_engine();
+ gqe->get_underlying_surfaces( surf, hidden_surfaces );
+
+ int k;
+ for(k=hidden_surfaces.size(); k--; )
+ {
+ //get the Acis ENTITY
+ ENTITY *entity = AcisQueryEngine::instance()->get_ENTITY_of_entity( hidden_surfaces.get_and_step() );
+
+ //if there's an attribute there already, get rid of it
+ ATTRIB_HISTORY *att = ATTRIB_HISTORY::get_history_attrib( entity );
+ if( att && att->deletable() )
+ {
+ att->unhook();
+ att->lose();
+ }
+ else if( att )
+ {
+ // att->unhook();
+ PRINT_INFO("---------------------Still have attrib around but can't delete it!\n");
+ }
+
+ //create the history attrib on the entity if it doesn't exist already
+ att = ATTRIB_HISTORY::get_history_attrib( entity, true, &history_object );
+ int tracking_id = history_object.generate_next_tracking_id();
+ att->add_tracking_id( tracking_id );
+ if( debug )
+ PRINT_INFO("RefEntity %s %d ---> ENTITY = %d w/ attrib %p\n",
+ ref_ent->class_name(), ref_ent->id(), tracking_id, att );
+ history_object.add_refentity_tracking_id_pair( ref_ent, tracking_id );
+
+ //add ENTITY to list in case of failure
+ history_object.add_ENTITY( entity );
+ }
+ }
+ }
+
+ //curves
+ for( j=curve_tbs.size(); j--; )
+ {
+ //get the RefEntity
+ Curve *curve = curve_tbs.get_and_step();
+ TopologyEntity *te = curve->topology_entity();
+ RefEntity *ref_ent = CAST_TO( te, RefEntity );
+
+ //Check to see that the entity is a SurfaceACIS
+ CurveACIS *curve_acis = CAST_TO( curve, CurveACIS );
+ if( curve_acis )
+ {
+ //get the Acis ENTITY
+ ENTITY *entity = AcisQueryEngine::instance()->get_ENTITY_of_entity( curve );
+
+ //if there's an attribute there already, get rid of it
+ ATTRIB_HISTORY *att = ATTRIB_HISTORY::get_history_attrib( entity );
+ if( att && att->deletable() )
+ {
+ att->unhook();
+ att->lose();
+ }
+ else if( att )
+ {
+ // att->unhook();
+ PRINT_INFO("---------------------Still have attrib around but can't delete it!\n");
+ }
+
+ //create the history attrib on the entity if it doesn't exist already
+ att = ATTRIB_HISTORY::get_history_attrib( entity, true, &history_object );
+ int tracking_id = history_object.generate_next_tracking_id();
+ att->add_tracking_id( tracking_id );
+ if( debug )
+ PRINT_INFO("RefEntity %s %d ---> ENTITY = %d w/ attrib %p\n",
+ ref_ent->class_name(), ref_ent->id(), tracking_id, att );
+ history_object.add_refentity_tracking_id_pair( ref_ent, tracking_id );
+
+ //add ENTITY to list in case of failure
+ history_object.add_ENTITY( entity );
+ }
+ else
+ {
+ DLIList<TopologyBridge*> hidden_curves;
+ GeometryQueryEngine *gqe = curve->get_geometry_query_engine();
+ gqe->get_underlying_curves( curve, hidden_curves );
+
+ int k;
+ for(k=hidden_curves.size(); k--; )
+ {
+ ENTITY *entity = AcisQueryEngine::instance()->get_ENTITY_of_entity( hidden_curves.get_and_step() );
+
+ //if there's an attribute there already, get rid of it
+ ATTRIB_HISTORY *att = ATTRIB_HISTORY::get_history_attrib( entity );
+ if( att && att->deletable() )
+ {
+ att->unhook();
+ att->lose();
+ }
+ else if( att )
+ {
+ // att->unhook();
+ PRINT_INFO("---------------------Still have attrib around but can't delete it!\n");
+ }
+
+ //create the history attrib on the entity if it doesn't exist already
+ att = ATTRIB_HISTORY::get_history_attrib( entity, true, &history_object );
+ int tracking_id = history_object.generate_next_tracking_id();
+ att->add_tracking_id( tracking_id );
+ if( debug )
+ PRINT_INFO("RefEntity %s %d ---> ENTITY = %d w/ attrib %p\n",
+ ref_ent->class_name(), ref_ent->id(), tracking_id, att );
+ history_object.add_refentity_tracking_id_pair( ref_ent, tracking_id );
+
+ //add ENTITY to list in case of failure
+ history_object.add_ENTITY( entity );
+ }
+ }
+ }
+
+ //vertices
+ for( j=vertex_tbs.size(); j--; )
+ {
+ //get the RefEntity
+ Point *point = vertex_tbs.get_and_step();
+ TopologyEntity *te = point->topology_entity();
+ RefEntity *ref_ent = CAST_TO( te, RefEntity );
+
+ PointACIS *point_acis = CAST_TO( point, PointACIS );
+ if( point_acis )
+ {
+ //get the Acis ENTITY
+ ENTITY *entity = AcisQueryEngine::instance()->get_ENTITY_of_entity( point );
+
+ //if there's an attribute there already, get rid of it
+ ATTRIB_HISTORY *att = ATTRIB_HISTORY::get_history_attrib( entity );
+ if( att && att->deletable() )
+ {
+ att->unhook();
+ att->lose();
+ }
+ else if( att )
+ {
+ // att->unhook();
+ PRINT_INFO("---------------------Still have attrib around but can't delete it!\n");
+ }
+
+ //create the history attrib on the entity if it doesn't exist already
+ att = ATTRIB_HISTORY::get_history_attrib( entity, true, &history_object );
+ int tracking_id = history_object.generate_next_tracking_id();
+ att->add_tracking_id( tracking_id );
+ if( debug )
+ PRINT_INFO("RefEntity %s %d ---> ENTITY = %d w/ attrib %p\n",
+ ref_ent->class_name(), ref_ent->id(), tracking_id, att );
+ history_object.add_refentity_tracking_id_pair( ref_ent, tracking_id );
+
+ //add ENTITY to list in case of failure
+ history_object.add_ENTITY( entity );
+ }
+ else
+ {
+ DLIList<TopologyBridge*> hidden_vertex;
+ GeometryQueryEngine *gqe = point->get_geometry_query_engine();
+ gqe->get_underlying_bridges( point, hidden_vertex );
+
+ if( hidden_vertex.size() )
+ {
+ PointACIS *point_acis = CAST_TO( hidden_vertex.get(), PointACIS );
+ //may have to go a level deeper -- compositing a partitioned curve
+ if( NULL == point_acis )
+ {
+ Point *tmp_point = CAST_TO( hidden_vertex.get(), Point );
+ hidden_vertex.clean_out();
+ gqe->get_underlying_bridges( tmp_point , hidden_vertex );
+ }
+ }
+ else //could be just a partition point..so no real underlying point
+ continue;
+
+ if( hidden_vertex.size() == 0 )
+ continue;
+
+ ENTITY *entity = AcisQueryEngine::instance()->get_ENTITY_of_entity( hidden_vertex.get() );
+
+ //if there's an attribute there already, get rid of it
+ ATTRIB_HISTORY *att = ATTRIB_HISTORY::get_history_attrib( entity );
+ if( att && att->deletable() )
+ {
+ // att->unhook();
+ att->lose();
+ }
+ else if( att )
+ {
+ att->unhook();
+ PRINT_INFO("---------------------Still have attrib around but can't delete it!\n");
+ }
+
+ //create the history attrib on the entity if it doesn't exist already
+ att = ATTRIB_HISTORY::get_history_attrib( entity, true, &history_object );
+ int tracking_id = history_object.generate_next_tracking_id();
+ att->add_tracking_id( tracking_id );
+ if( debug )
+ PRINT_INFO("RefEntity %s %d ---> ENTITY = %d w/ attrib %p\n",
+ ref_ent->class_name(), ref_ent->id(), tracking_id, att );
+ history_object.add_refentity_tracking_id_pair( ref_ent, tracking_id );
+
+ //add ENTITY to list in case of failure
+ history_object.add_ENTITY( entity );
+ }
+ }
+ }
+}
+
+void AcisModifyEngine::stop_tracking_history( DLIList<BodySM*> &new_bodies,
+ AcisHistory &history_object )
+{
+ DLIList<TopologyBridge*> tbs;
+ CAST_LIST( new_bodies, tbs, TopologyBridge );
+
+ stop_tracking_history( tbs, history_object );
+}
+
+
+void AcisModifyEngine::stop_tracking_history( DLIList<TopologyBridge*> &new_tbs,
+ AcisHistory &history_object )
+{
+ DLIList<ENTITY*> ents_with_attribs;
+ DLIList<Point*> tmp_vertex_tbs;
+
+ //map tracking ids to TB
+ int i;
+ for( i=new_tbs.size(); i--; )
+ {
+ //get all the TopologyBridges of Bodies, Lumps, Surfaces, Curves, and Vertices
+ DLIList<Lump*> lump_tbs;
+ DLIList<Surface*> surface_tbs;
+ DLIList<Curve*> curve_tbs;
+ DLIList<Point*> vertex_tbs;
+ DLIList<BodySM*> body_tbs;
+
+ TopologyBridge *tmp_tb = new_tbs.get_and_step();
+
+ tmp_tb->bodysms( body_tbs );
+ assert( body_tbs.size() < 2 );
+
+ tmp_tb->lumps( lump_tbs );
+ tmp_tb->surfaces( surface_tbs );
+ tmp_tb->curves( curve_tbs );
+ tmp_tb->points( vertex_tbs );
+
+ tmp_vertex_tbs += vertex_tbs;
+
+ //collect a list of events leading back to the RefEntity
+ //PRINT_INFO("BODY\n");
+
+
+ if( body_tbs.size() )
+ {
+ BodySM *bodysm = body_tbs.get();
+ ENTITY *tmp_ent = AcisQueryEngine::instance()->get_ENTITY_of_entity( bodysm );
+ ATTRIB_HISTORY *att = ATTRIB_HISTORY::get_history_attrib( tmp_ent, false );
+ if( att )
+ {
+ std::set<int> tracking_ids = att->get_tracking_ids();
+ history_object.add_to_tracking_ids_tb_map( tracking_ids, bodysm );
+ ents_with_attribs.append( tmp_ent );
+ }
+ }
+
+ int j;
+ //PRINT_INFO("LUMPS\n");
+ for( j=lump_tbs.size(); j--; )
+ {
+ TopologyBridge *tmp_bridge = lump_tbs.get_and_step();
+ ENTITY *tmp_ent = AcisQueryEngine::instance()->get_ENTITY_of_entity( tmp_bridge );
+ ATTRIB_HISTORY *att = ATTRIB_HISTORY::get_history_attrib( tmp_ent, false );
+ if( att )
+ {
+ std::set<int> tracking_ids = att->get_tracking_ids();
+ history_object.add_to_tracking_ids_tb_map( tracking_ids, tmp_bridge);
+ ents_with_attribs.append( tmp_ent );
+ }
+ }
+
+ //PRINT_INFO("FACES\n");
+ for( j=surface_tbs.size(); j--; )
+ {
+ TopologyBridge *tmp_bridge = surface_tbs.get_and_step();
+ SurfaceACIS *surf_acis = CAST_TO( tmp_bridge, SurfaceACIS );
+ if( NULL == surf_acis )
+ continue;
+ ENTITY *tmp_ent = AcisQueryEngine::instance()->get_ENTITY_of_entity( tmp_bridge );
+ ATTRIB_HISTORY *att = ATTRIB_HISTORY::get_history_attrib( tmp_ent, false );
+ if( att )
+ {
+ std::set<int> tracking_ids = att->get_tracking_ids();
+ history_object.add_to_tracking_ids_tb_map( tracking_ids, tmp_bridge );
+ ents_with_attribs.append( tmp_ent );
+ }
+ }
+
+ //PRINT_INFO("EDGES\n");
+ for( j=curve_tbs.size(); j--; )
+ {
+ TopologyBridge *tmp_bridge = curve_tbs.get_and_step();
+ CurveACIS *curve_acis = CAST_TO( tmp_bridge, CurveACIS );
+ if( NULL == curve_acis )
+ continue;
+ ENTITY *tmp_ent = AcisQueryEngine::instance()->get_ENTITY_of_entity( tmp_bridge );
+ ATTRIB_HISTORY *att = ATTRIB_HISTORY::get_history_attrib( tmp_ent, false );
+ if( att )
+ {
+ std::set<int> tracking_ids = att->get_tracking_ids();
+ history_object.add_to_tracking_ids_tb_map( tracking_ids, tmp_bridge );
+ ents_with_attribs.append( tmp_ent );
+ }
+ }
+
+ //PRINT_INFO("VERTICES\n");
+ for( j=vertex_tbs.size(); j--; )
+ {
+ TopologyBridge *tmp_bridge = vertex_tbs.get_and_step();
+ PointACIS *pt_acis = CAST_TO( tmp_bridge, PointACIS );
+ if( NULL == pt_acis )
+ continue;
+ ENTITY *tmp_ent = AcisQueryEngine::instance()->get_ENTITY_of_entity( tmp_bridge );
+ ATTRIB_HISTORY *att = ATTRIB_HISTORY::get_history_attrib( tmp_ent, false );
+ if( att )
+ {
+ std::set<int> tracking_ids = att->get_tracking_ids();
+ history_object.add_to_tracking_ids_tb_map( tracking_ids, tmp_bridge );
+ ents_with_attribs.append( tmp_ent );
+ }
+ }
+ }
+
+ //now sort what happened
+ history_object.create_cgm_history_objects();
+ //history_object.print();
+ GeometryQueryTool::instance()->history().print_port_events();
+
+/*
+ //strip off attributes --
+ for( i=0; i<ents_with_attribs.size(); i++ )
+ {
+ ATTRIB_HISTORY *att = ATTRIB_HISTORY::get_history_attrib( ents_with_attribs.get_and_step(), false );
+ if( att )
+ {
+ att->unhook();
+ att->lose();
+ }
+ }
+*/
+ //TODO: get this working.
+ ATTRIB_HISTORY::remove_all_attribs();
+
+}
+
+
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisModifyEngine.hpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisModifyEngine.hpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisModifyEngine.hpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -19,6 +19,7 @@
#include "AcisQueryEngine.hpp"
#include <set>
+#include <map>
class ENTITY;
class ENTITY_LIST;
@@ -55,6 +56,9 @@
class LoopSM;
class Curve;
class Point;
+class tolerant_stitch_options;
+class simplify_options;
+class error_info;
class AcisBridge;
class BodyACIS;
@@ -66,6 +70,7 @@
class CurveACIS;
class PointACIS;
class BodySM;
+class AcisHistory;
class CubitBox;
class CubitString;
@@ -87,6 +92,9 @@
friend class AcisHealerTool;
friend class AcisSurfaceTool;
friend class AcisTweakTool;
+#ifdef ACIS_TWEAK
+ friend class AcisTweakToolCAT;
+#endif
friend class AcisEdgeTool;
friend class AcisToolUtil;
friend class AcisBridge;
@@ -121,6 +129,10 @@
static AcisModifyEngine* instance_;
std::set<AcisBridge*> deactivatedSet;
+
+ virtual bool supports_interoperability() { return true; }
+ //- Returns whether intermixing of real and virtual geometry operations
+ //- is supported for the current geometry kernel.
bool bridge_deactivated(AcisBridge*) const;
CubitStatus deactivate_bridge(AcisBridge*) const;
@@ -246,6 +258,7 @@
BodySM*& newBody1,
BodySM*& newBody2,
bool keep_old = false) const ;
+
virtual CubitStatus imprint(DLIList<BodySM*> &from_body_list,
DLIList<BodySM*> &new_from_body_list,
bool keep_old = false,
@@ -258,6 +271,7 @@
virtual CubitStatus imprint( DLIList<BodySM*> &body_list,
DLIList<Curve*> &ref_edge_list,
DLIList<BodySM*>& new_body_list,
+ DLIList<TopologyBridge*> &temporary_bridges,
bool keep_old_body,
bool show_messages = true) const;
//- Imprints a list of Bodies with a list of RefEdges. All entities must
@@ -266,6 +280,7 @@
virtual CubitStatus imprint( DLIList<Surface*> &surface_list,
DLIList<Curve*> &curve_list,
+ DLIList<TopologyBridge*> &temporary_bridges,
DLIList<BodySM*>& new_body_list,
bool keep_old_body ) const;
//- Imprints a list of RefFaces with a list of RefEdges. This is
@@ -276,7 +291,10 @@
virtual CubitStatus imprint( DLIList<Surface*> &surface_list,
DLIList<DLIList<Curve*>*> &curve_lists_list,
BodySM*& new_body,
- bool keep_old_body ) const;
+ bool keep_old_body,
+ bool expand = true,
+ DLIList<TopologyBridge*> *new_tbs = NULL,
+ DLIList<TopologyBridge*> *att_tbs = NULL ) const;
//- Imprints a list of Surfaces with list of Curves, sorted per
//- Surface (ie., curve_lists_list is same length as surface_list).
//- This version is more efficient than the general-purpose one
@@ -288,7 +306,9 @@
DLIList<BodySM*>& new_body_list,
bool keep_old_body,
DLIList<TopologyBridge*> *new_tbs = NULL,
- DLIList<TopologyBridge*> *att_tbs = NULL ) const;
+ DLIList<TopologyBridge*> *att_tbs = NULL,
+ double *tol_in = NULL,
+ bool clean_up_slivers = true) const;
//- Imprints a list of bodies with a list of vectors. Useful for
//- splitting curves and creating hardpoints on surfaces.
@@ -310,18 +330,39 @@
//- Imprints a list of Bodies with a list of RefEdges which are projected
//- to a list of RefFaces
+ virtual CubitStatus remove_topology(DLIList<Curve*> &curves_to_remove,
+ DLIList<Surface*> &surfs_to_remove,
+ double backoff_distance,
+ double small_edge_size,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean preview) const;
+
+ virtual CubitStatus tolerant_imprint_surface_with_curves(
+ Surface *surface_to_imprint,
+ DLIList<Curve*> &curves,
+ DLIList<TopologyBridge*> &temporary_bridges,
+ BodySM *&new_body,
+ DLIList<TopologyBridge*> *new_tbs = NULL,
+ DLIList<TopologyBridge*> *att_tbs = NULL ) const;
+ //Imprints a surface with passed-in curves. Can imprint successfully
+ //and expectedly with sloppy/dirty geometry.
+
virtual CubitStatus tolerant_imprint( DLIList<BodySM*> &bodies_in,
DLIList<BodySM*> &new_bodies,
DLIList<TopologyBridge*> *new_tbs,
DLIList<TopologyBridge*> *att_tbs ) const;
//Imprints a list of bodies with each other. Can imprint successfully
//and expectedly with sloppy/dirty models.
+ virtual CubitStatus tolerant_imprint(DLIList<Surface*> &surfs_in,
+ DLIList<BodySM*> &new_bodysm_list) const;
virtual CubitStatus project_edges( DLIList<Surface*> &ref_face_list,
DLIList<Curve*> &ref_edge_list_in,
DLIList<Curve*> &ref_edge_list_new,
bool print_error = true ) const;
//- Projects list RefEdges to a list of RefFaces
+ virtual void get_possible_invalid_tbs(DLIList<TopologyBridge*> &bridges_in,
+ DLIList<TopologyBridge*> &bridges_out);
virtual CubitStatus intersect( BodySM* tool_body_ptr,
DLIList<BodySM*> &from_bodies,
@@ -452,7 +493,19 @@
Surface *stop_surf = NULL,
BodySM* stop_body = NULL) const;
+ virtual CubitStatus sweep_to_body(
+ DLIList<Curve*> curve_list,
+ BodySM *target_body,
+ CubitVector distance,
+ DLIList<BodySM*> &new_bodies,
+ bool unite) const;
+ virtual CubitStatus sweep_to_body(
+ Surface *source_surface,
+ BodySM *target_body,
+ CubitVector distance,
+ DLIList<BodySM*> &new_bodies) const;
+
//HEADER- Functions for webcut operations
virtual CubitStatus webcut(
@@ -460,8 +513,10 @@
const CubitVector &v1,
const CubitVector &v2,
const CubitVector &v3,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*>& results_list,
- bool imprint = false ) const;
+ ImprintType imprint_type = NO_IMPRINT,
+ bool preview = false) const ;
//R int
//R- Number of bodies that were webcut ( >= 0 )
//I webcut_body_list
@@ -478,11 +533,12 @@
//- The newly created bodies are merged and imprinted depeding on
//- the respective flags.
- virtual CubitStatus webcut(
- DLIList<BodySM*>& webcut_body_list,
- BodySM const* tool_body,
- DLIList<BodySM*>& results_list,
- bool imprint = false) const;
+ virtual CubitStatus webcut( DLIList<BodySM*>& webcut_body_list,
+ BodySM const* tool_body,
+ DLIList<BodySM*>& neighbor_imprint_list,
+ DLIList<BodySM*>& results_list,
+ ImprintType imprint_type = NO_IMPRINT,
+ bool preview = false) const ;
//R int
//R- Number of bodies that were webcut ( >= 0 )
//I webcut_body_list
@@ -504,8 +560,10 @@
double radius,
const CubitVector &axis,
const CubitVector ¢er,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*>& results_list,
- bool imprint = false );
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean preview = false);
*/
//- cores the bodies with a cylinder formed by the given
//- parameters and the height larger than the model.
@@ -515,8 +573,10 @@
const CubitVector ¢er,
const CubitVector axes[3],
const CubitVector &extension,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*> &results_list,
- bool imprint = false );
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean preview = false);
*/
/**< Webcuts the bodies in the list with a cutting brick.
* The brick is created by the given parameters - center of
@@ -531,8 +591,10 @@
const CubitVector ¢er,
const CubitVector axes[2],
double width, double height,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*> &results_list,
- bool imprint = false );
+ ImprintType imprint_type = NO_IMPRINT,
+ bool preview = false );
*/
/**< Webcuts the bodies in the list with a cutting planar sheet.
* The sheet is created by the given parameters - center of
@@ -543,8 +605,10 @@
virtual CubitStatus webcut_with_curve_loop(
DLIList<BodySM*> &webcut_body_list,
DLIList<Curve*> &ref_edge_list,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*>& results_list,
- bool imprint = false);
+ ImprintType imprint_type = NO_IMPRINT,
+ bool preview = false);
*/
//- creates a sheet body with the given curve loop
//- uses the new sheet body to cut the body list
@@ -557,8 +621,10 @@
double angle,
Surface *stop_surf,
bool up_to_next,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*> &results_list,
- CubitBoolean imprint = false );
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean preview = false);
*/
/*
virtual CubitStatus webcut_with_sweep_curves_rotated(
@@ -568,8 +634,10 @@
const CubitVector& sweep_vector,
double angle,
Surface *stop_surf,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*> &results_list,
- CubitBoolean imprint = false );
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean preview = false);
*/
//-these 2 functions sweep a surface or curve about an axis, creating a swept
//volume or surface respectively, which is in turn used to webcut the blank_bodies.
@@ -587,8 +655,10 @@
bool up_to_next,
Surface *stop_surf,
Curve *curve_to_sweep_along,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*> &results_list,
- CubitBoolean imprint = false );
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean preview = false);
*/
//-sweeps a surface(s) along a vector, curve or perpendicular to the surface
//(last case implied when sweep_vector's length is zero) producing a swept body.
@@ -608,8 +678,10 @@
bool through_all,
Surface *stop_surf,
Curve *curve_to_sweep_along,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*> &results_list,
- CubitBoolean imprint = false );
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean preview = false);
*/
//-sweeps a curve(s) along a vector, curve. Swept surface(s)are stitched
//together and used as cutting tool to webcut blank_bodies. If surface(s)
@@ -634,7 +706,7 @@
//HEADER- Functions that create GeometryEntities
- virtual BodySM* copy_body ( BodySM* bodyPtr) const ;
+ virtual BodySM* copy_body( BodySM* body_sm ) const ;
//R Body*
//R- A pointer to the newly created body
//I bodyPtr
@@ -670,6 +742,9 @@
//- The third point is optional so it can be NULL. It is
//- or can be used for periodic curves that result.
+ virtual Curve* make_Curve( DLIList<CubitVector*>& point_list,
+ DLIList<CubitVector*>& point_tangents) const;
+
virtual Curve* make_Curve( GeometryType curve_type,
Point const* point1_ptr,
Point const* point2_ptr,
@@ -738,6 +813,21 @@
//- The new surface is attached to ACIS geometry. The acis
//- goemetry is attached to a full data structure, loop, lump, bodies..
+ virtual BodySM* make_extended_sheet( DLIList<Surface*> &surface_list,
+ CubitBox *clip_box = NULL,
+ bool preview = false) const;
+ //R BodySM*
+ //R- Pointer to a newly created BodySM object.
+ //I surface_list
+ //I- The surface_list from which we want to create an extended sheet.
+ //I clip_box
+ //I- An optional bounding box to clip the resultant sheet body by.
+ //I preview
+ //I- If true just draw the sheet instead of creating it
+ //- This function creates a sheet body by extending the input surfaces.
+ //- The result can be optionally clipped to fit inside of the given
+ //- bounding box.
+
virtual Surface* make_Surface( GeometryType surface_type,
DLIList<Curve*>& curve_list,
Surface *old_surface_ptr = NULL,
@@ -810,8 +900,10 @@
/*
virtual CubitStatus webcut_with_sheet(DLIList<BodySM*>& webcut_body_list,
BodySM *sheet_body,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*> &new_bodies,
- bool imprint = false);
+ ImprintType imprint_type = NO_IMPRINT,
+ bool preview = false);
*/
//- webcuts a body using a sheet body.
//- It splits the sheet into two single sided bodies.
@@ -824,25 +916,38 @@
BODY *sheet_body,
BODY *&webcut_body_1,
BODY *&webcut_body_2,
- CubitBoolean imprint = CUBIT_FALSE);
+ ImprintType imprint_type = NO_IMPRINT,
+ bool preview = false);
*/
//- webcuts a body using a sheet body.
//- It splits the sheet into two single sided bodies.
/*
- virtual CubitStatus webcut_with_extended_surf(DLIList<BodySM*> &webcut_body,
- Surface *extend_from,
+ virtual CubitStatus webcut_with_extended_sheet(DLIList<BodySM*> &webcut_body,
+ DLIList<Surface*> &surface_list,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*> &new_bodies,
int &num_cut,
- bool imprint = false);
+ ImprintType imprint_type = NO_IMPRINT,
+ bool preview = false);
*/
- //- creates a surface by extending one from the given surface then
- //- webcuts using the this sheet.(see webcut_with_sheet.
+ //- creates a sheet by extending the given surfaces then webcuts using
+ //- this sheet.(see webcut_with_sheet)
+ virtual CubitStatus split_free_curve( Curve *curve,
+ CubitVector &split_location,
+ DLIList<Curve*> &new_curves );
+ //- split a free curve a given location
+
virtual CubitStatus split_body( BodySM *body_ptr,
DLIList<BodySM*> &new_bodies );
//- splits a body into several bodies (multiple volumes in
//- a single body go to multiple bodies.
+ virtual CubitStatus separate_surfaces( DLIList<Surface*> &surf_list,
+ DLIList<BodySM*> &new_bodies );
+ //- Separates surfaces from sheet bodies into separate bodies. Connected
+ //- surfaces will remain connected but be placed in a new body.
+
virtual CubitStatus split_periodic( BodySM *body_ptr,
BodySM *&new_body);
//- splits the periodic bodies
@@ -857,7 +962,8 @@
DLIList<Surface*> &ref_face_list,
DLIList<BodySM*> &new_bodies,
bool keep_old = false,
- bool heal = true) const;
+ bool heal = true,
+ bool sheet = false) const;
//- This function assumes that the reffaces sent into
//- this function are either sheet bodies, or free surfaces. This
//- Will have been taken care of in the calling function. GT?
@@ -878,8 +984,10 @@
virtual CubitStatus webcut_across_translate( DLIList<BodySM*>& body_list,
Surface* plane_surf1,
Surface* plane_surf2,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*>& results_list,
- bool imprint = false) const;
+ ImprintType imprint_type = NO_IMPRINT,
+ bool preview = false) const;
// In-process function to webcut a flat plate suitable for singe-single sweeping.
CubitStatus offset_curves( DLIList<Curve*>& ref_edge_list,
@@ -892,6 +1000,14 @@
//- is calculated by ACIS (the cross product of the wires tangent and the
//- planar normal). The gap type is 0 - rounded, 1 - extended, 2 - natural.
+ CubitStatus
+ split_curve( Curve* curve_to_split,
+ const CubitVector& split_location,
+ DLIList<Curve*>& created_curves );
+ //- Splits a curve at the specified location.
+ //- the single passed in curve is split into two curves at the split location
+ //- the two resulting curves are added to the passed in list
+
Curve* trim_curve( Curve* trim_curve,
const CubitVector& trim_vector,
const CubitVector& keep_vector,
@@ -993,16 +1109,32 @@
BodySM *body_to_trim_to,
BodySM *&midsurface_body ) const;
+ CubitStatus tweak_bend( DLIList<BodySM*> &bend_bodies,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitVector& neutral_root,
+ CubitVector& bend_axis,
+ CubitVector& bend_direction,
+ double radius,
+ double angle,
+ DLIList<CubitVector*> bend_regions,
+ double width = -1,
+ CubitBoolean center_bend = CUBIT_FALSE,
+ int num_points = 0,
+ CubitBoolean keep_old_body = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE ) const;
+ /**< Bend solid bodies based on a bend radius and angle.
+ */
+
virtual CubitStatus tweak_chamfer( DLIList<Curve*> &curve_list,
double left_offset,
DLIList<BodySM*> &new_bodysm_list,
double right_offset = -1.0,
CubitBoolean keep_old_body = CUBIT_FALSE,
CubitBoolean preview = CUBIT_FALSE ) ;
- /**< Chamfer curves on solid bodies. The left and right offsets are with
- * respect to the curve direction. If the given right offset is negative,
- * the left offset is used. Users can preview to clarify the meaning of
- * left and right.
+ /**< Chamfer curves on solid or sheet bodies. The left and right offsets
+ * are with respect to the curve direction. If the given right offset is
+ * negative, the left offset is used. Users can preview to clarify the
+ * meaning of left and right.
*/
virtual CubitStatus tweak_chamfer( DLIList<Point*> &point_list,
@@ -1026,7 +1158,8 @@
DLIList<BodySM*> &new_bodysm_list,
CubitBoolean keep_old_body = CUBIT_FALSE,
CubitBoolean preview = CUBIT_FALSE ) ;
- /**< Create a round fillet (or blend) at the given curves on solid bodies.
+ /**< Create a round fillet (or blend) at the given curves on solid or sheet
+ * bodies.
*/
virtual CubitStatus tweak_fillet( Curve *curve_ptr,
@@ -1035,8 +1168,9 @@
BodySM *&new_body_ptr,
CubitBoolean keep_old_body = CUBIT_FALSE,
CubitBoolean preview = CUBIT_FALSE ) ;
- /**< Create a round fillet (or blend) at the given curve on a solid body.
- * The fillet has a variable radius from the start to the end of the curve.
+ /**< Create a round fillet (or blend) at the given curve on a solid or sheet
+ * body. The fillet has a variable radius from the start to the end of the
+ * curve.
*/
virtual CubitStatus tweak_fillet( DLIList<Point*> &point_list,
@@ -1065,26 +1199,29 @@
virtual CubitStatus tweak_offset( DLIList<Surface*> &surface_list,
double offset_distance,
+ DLIList<Surface*> *add_surface_list_ptr,
+ DLIList<double> *add_offset_list_ptr,
DLIList<BodySM*> &new_bodysm_list,
CubitBoolean keep_old_body = CUBIT_FALSE,
CubitBoolean preview = CUBIT_FALSE ) const;
/**< Tweak specified faces of a volume or volumes by offsetting those faces
- * by the offset distance.
+ * by the offset distance(s).
*/
virtual CubitStatus tweak_offset( DLIList<Curve*> &curve_list,
double offset_distance,
+ DLIList<Curve*> *add_curve_list_ptr,
+ DLIList<double> *add_offset_list_ptr,
DLIList<BodySM*> &new_bodysm_list,
CubitBoolean keep_old_body = CUBIT_FALSE,
CubitBoolean preview = CUBIT_FALSE ) const;
/**< Tweak specified curves of a sheet body or bodies by offsetting those
- * curves by the offset distance.
+ * curves by the offset distance(s).
*/
virtual CubitStatus tweak_remove( DLIList<Surface*> &surface_list,
DLIList<BodySM*> &new_bodysm_list,
CubitBoolean extend_adjoining = CUBIT_TRUE,
- CubitBoolean keep_surface = CUBIT_FALSE,
CubitBoolean keep_old_body = CUBIT_FALSE,
CubitBoolean preview = CUBIT_FALSE ) const;
/**< Remove surfaces from a body or bodies and then extend the adjoining
@@ -1103,34 +1240,80 @@
virtual CubitStatus tweak_target( DLIList<Surface*> &surface_list,
DLIList<Surface*> &target_surf_list,
DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean extend_flg = CUBIT_TRUE,
+ CubitPlane *limit_plane = NULL,
CubitBoolean reverse_flg = CUBIT_FALSE,
CubitBoolean keep_old_body = CUBIT_FALSE,
CubitBoolean preview = CUBIT_FALSE ) const;
/**< Tweak specified faces of a volume or volumes up to target surfaces.
+ * If extend flag is true, extend out the targets before tweaking to them
+ * (only used for multiple targets; single targets are always extended).
+ * The optional limit plane is only valid if extend_flg is TRUE; it will
+ * limit the tweak to not go past this plane in the case where the tweaked
+ * body would only partially intersect the extended targets. The reverse
+ * flag should never be needed - if it is, there may be a bug or a bad
+ * normal on a body (i.e., negative volume body), and is only retained for
+ * debugging.
*/
virtual CubitStatus tweak_target( DLIList<Curve*> &curve_list,
DLIList<Surface*> &target_surf_list,
DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean extend_flg = CUBIT_TRUE,
+ CubitPlane *limit_plane = NULL,
CubitBoolean reverse_flg = CUBIT_FALSE,
CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE ) const;
+ CubitBoolean preview = CUBIT_FALSE ,
+ double max_area_increase = 0) const;
/**< Tweak specified edges of a surface or set of surfaces (in sheet
* bodies) up to a set of target surfaces. This essentially extends or
- * trims the attached surfaces of the sheet body.
+ * trims the attached surfaces of the sheet body. If extend flag
+ * is true, extend out the targets before tweaking to them (only used for
+ * multiple targets; single targets are always extended). The optional
+ * limit plane is only valid if extend_flg is TRUE; it will limit the
+ * tweak to not go past this plane in the case where the tweaked body
+ * would only partially intersect the extended targets. The reverse flag
+ * should never be needed - if it is, there may be a bug or a bad normal
+ * on a body (i.e., negative volume body), and is only retained for
+ * debugging.
*/
virtual CubitStatus tweak_target( DLIList<Curve*> &curve_list,
DLIList<Curve*> &target_curve_list,
DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean extend_flg = CUBIT_TRUE,
+ CubitPlane *limit_plane = NULL,
CubitBoolean reverse_flg = CUBIT_FALSE,
CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE ) const;
+ CubitBoolean preview = CUBIT_FALSE,
+ double max_area_increase = 0 ) const;
/**< Tweak specified edges of a sheet body or bodies up to a list of target
- * curves that are part of a sheet body. The target is a surface created by
- * thickening the owning surfaces of the target curves.
+ * curves that are part of a sheet body. The target is a surface created
+ * by thickening the owning surfaces of the target curves. If extend flag
+ * is true, extend out the targets before tweaking to them (only used for
+ * multiple targets; single targets are always extended). The optional
+ * limit plane is only valid if extend_flg is TRUE; it will limit the
+ * tweak to not go past this plane in the case where the tweaked body
+ * would only partially intersect the extended targets. The reverse flag
+ * should never be needed - if it is, there may be a bug or a bad normal
+ * on a body (i.e., negative volume body), and is only retained for
+ * debugging.
*/
+ virtual CubitStatus tweak_target( Point *point_ptr,
+ DLIList<Surface*> &modify_surface_list,
+ CubitVector &target_loc,
+ BodySM *&new_bodysm_ptr,
+ CubitBoolean keep_old_body = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE ) const;
+ /**< Tweak specified vertex of a sheet body to a given location. The
+ * given vertex must be part of a planar surface or surfaces attached to
+ * linear curves only. The user specified which of those surfaces to
+ * actually modify. The given location will be projected to be on the
+ * given planar surface(s) before being used - this projected location
+ * must be the same on all surfaces.
+ */
+
virtual CubitStatus remove_curve_slivers( BodySM *body_sm, double lengthlimit ) const;
virtual CubitStatus create_net_surface( DLIList<Surface*>& ref_face_list, BodySM *& new_body,
@@ -1146,9 +1329,24 @@
virtual CubitStatus create_offset_surface( Surface* ref_face_ptr, BodySM*& new_body, double offset_distance ) const;
+ virtual CubitStatus create_offset_sheet( DLIList<Surface*> &surface_list,
+ double offset_distance,
+ DLIList<Surface*> *add_surface_list_ptr,
+ DLIList<double> *add_offset_list_ptr,
+ DLIList<BodySM*> &new_body_list,
+ CubitBoolean preview = CUBIT_FALSE ) const;
+ /**< Create a sheet body (or bodies) by offsetting the given faces. The
+ * optional additional face list and double list (must be same length)
+ * allow different offset distances for different faces. Adjoining faces
+ * are extended or trimmed to remain joined in the new sheet body. Radial
+ * faces that cannot be so offset are removed and the resulting wound
+ * healed by the surrounding faces.
+ */
+
virtual CubitStatus create_offset_body( BodySM* body_ptr, BodySM*& new_body, double offset_distance ) const;
- virtual CubitStatus create_skin_surface( DLIList<Curve*>& curves, BodySM*& new_body ) const;
+ virtual CubitStatus create_skin_surface( DLIList<Curve*>& curves, BodySM*& new_body,
+ DLIList<Curve*>& guides) const;
virtual CubitStatus loft_surfaces( Surface *face1, const double &takeoff1,
Surface *face2, const double &takeoff2,
@@ -1160,25 +1358,90 @@
CubitBoolean simplify_option = CUBIT_FALSE) const;
virtual CubitStatus loft_surfaces_to_body( Surface *face1, const double &takeoff1,
- Surface *face2, const double &takeoff2,
- BodySM*& new_body,
- CubitBoolean arc_length_option,
- CubitBoolean twist_option,
- CubitBoolean align_direction,
- CubitBoolean perpendicular,
- CubitBoolean simplify_option) const;
+ Surface *face2, const double &takeoff2,
+ BodySM*& new_body,
+ CubitBoolean arc_length_option,
+ CubitBoolean twist_option,
+ CubitBoolean align_direction,
+ CubitBoolean perpendicular,
+ CubitBoolean simplify_option) const;
virtual CubitStatus create_surface( DLIList<CubitVector*>& vec_list,
BodySM *&new_body,
Surface *ref_face_ptr,
- CubitBoolean project_points ) const;
+ CubitBoolean project_points ) const;
+ virtual CubitStatus create_surface( DLIList<Point*>& vec_list,
+ BodySM *&new_body ) const;
+
virtual CubitStatus create_weld_surface( CubitVector &root,
- Surface *ref_face1, double leg1, Surface *ref_face2, double leg2,
+ Surface *ref_face1, double leg1,
+ Surface *ref_face2, double leg2,
BodySM *&new_body ) const;
CubitStatus scale( BodySM *&body, const CubitVector& f );
+ virtual CubitStatus curve_surface_intersection( Surface *surface,
+ Curve* curve,
+ DLIList<Curve*> &new_curves ) const;
+ //Intersects input surface with input curve to produce intersection curve(s).
+ //If intersection results is nothing or a point, CUBIT_FAILURE is returned.
+ EDGE* project_EDGE( EDGE* EDGE_in_ptr, FACE* FACE_ptr, bool print_error = true ) const;
+ //- Projects a EDGE to a FACE returning the newly created EDGE
+ EDGE* make_surface_EDGE( VERTEX* from,
+ VERTEX* to,
+ FACE *FACE_ptr,
+ const CubitVector &plane_normal,
+ const CubitVector *third_point = NULL) const;
+ FACE* make_FACE( GeometryType FACE_type,
+ DLIList<EDGE*>& EDGE_list,
+ Surface *old_surface_ptr = NULL) const;
+ //R FACE*
+ //R- Returned FACE pointer
+ //I FACE_type
+ //I- The type of geometry entity to be associated with the FACE
+ //I- that is created
+ //I EDGE_list
+ //I- Input list of EDGEs that bound the FACE to be made.
+ //- This function creates an ACIS FACE using the EDGEs in EDGE_list.
+ //- The type of the underlying geometry is determined by the
+ //- FACE_type argument.
+ //- All other associated ACIS entities are also created.
+ BODY* make_extended_sheet( DLIList<FACE*> &FACE_list,
+ CubitBox *clip_box = NULL,
+ bool suppress_errors = false) const;
+ //R BODY*
+ //R- Pointer to a newly created BODY object.
+ //I FACE_list
+ //I- The FACE_list from which we want to create an extended sheet.
+ //I clip_box
+ //I- An optional bounding box to clip the resultant sheet body by.
+ //- This function creates a sheet body by extending the input FACEs.
+ //- The result can be optionally clipped to fit inside of the given
+ //- bounding box.
+ CubitStatus imprint( BODY *BODY_ptr,
+ FACE *FACE_ptr,
+ EDGE *EDGE_ptr,
+ DLIList<TopologyBridge*> &temporary_bridges,
+ bool expand = false) const;
+ //- Imprint given FACE with given EDGE. BODY_ptr is BODY that FACE_ptr is on.
+
+ BODY* copy_BODY (BODY* body_ptr,
+ bool remove_attribs = true ) const;
+ //- Make a copy of the input BODY, body_ptr, and return a pointer
+ //- to the new BODY. If the operation fails, a NULL pointer is returned.
+ //- If remove_attribs is set to CUBIT_TRUE, then the attributes from the
+ //- original BODY will be stripped off the new BODY (these are automatically
+ //- copied to the new BODY, by ACIS.
+
+ CubitBoolean bodies_interfering( BodySM *body1, BodySM *body2 ) const;
+
+ CubitStatus stitch( DLIList<BodySM*> &bodies_to_stitch,
+ DLIList<BodySM*> &new_bodies,
+ bool tighten_gaps,
+ double tolerance )const;
+
+
protected:
private:
@@ -1381,12 +1644,6 @@
SPAposition* ctr_ptr,
bool sense) const;
- EDGE* make_surface_EDGE( VERTEX* from,
- VERTEX* to,
- FACE *FACE_ptr,
- const CubitVector &plane_normal,
- const CubitVector *third_point = NULL) const;
-
EDGE* make_spline_EDGE( VERTEX* from,
VERTEX* to,
SPAposition* pos_array,
@@ -1410,13 +1667,21 @@
//- Create a spline curve from the input locations. Returns NULL if
//- unable to create a spline. Uses api_curve_spline
- FACE* make_type_FACE( CONE *CONE_ptr ) const;
+ EDGE* make_spline_EDGE( DLIList<CubitVector*> &vec_list,
+ CubitVector* start_direction,
+ CubitVector* end_direction );
+
+ FACE* make_type_FACE( CONE *CONE_ptr, FACE *FACE_ptr,
+ CubitBox *limit_box = 0 ) const;
//R FACE*
//R- face pointer connected to sheet body.
//I- Cone geometry where info is to be gleaned.
+ //I- Optional bounding box for determing size of FACE. If not supplied,
+ // uses the super bounding box of the model.
//- This function takes the input cone geometry and creates
//- another face using this to create a larger face that
- //- has a height fitting a factor larger than the model.
+ //- has a height fitting a factor larger than the model, or the supplied
+ //- limit_box.
FACE* make_type_FACE( SPHERE *SPHERE_ptr ) const;
//R FACE*
@@ -1434,46 +1699,42 @@
//- another face using this to create a full torus face.
//- it is just the shell of the torus.
- FACE* make_type_FACE( SPLINE *SPLINE_ptr ) const;
+#if CUBIT_ACIS_VERSION < 1900
+ FACE* make_type_FACE( SPLINE *SPLINE_ptr, CubitBox *limit_box_ptr = NULL ) const;
+#endif
+
+ FACE* make_type_FACE( FACE *FACE_ptr, CubitBox *limit_box_ptr = NULL ) const;
//R FACE*
//R- face pointer connected to sheet body.
- //I- Spline geometry where info is to be gleaned.
- //- This function takes the input spline geometry and creates
+ //WARNING: Input FACE's geometry must be of type spline!!!!!
+ //- This function takes the FACE and creates
//- another face using this to create a full spline face.
- //- it is just the shell of the spline.
+ //- It attempts to expand out 10% greater than the overall
+ //- cubit bounding box or to the given limit_box.
- FACE* make_type_FACE( PLANE *PLANE_ptr ) const;
+
+
+ FACE* make_type_FACE( PLANE *PLANE_ptr, CubitBox *limit_box = 0 ) const;
//R FACE*
//R- face pointer connected to sheet body.
//I- Plane geometry where info is to be gleaned.
- //- The super bounding box of the model is used to creat the limits of the
- //- new plane.
+ //I- Optional bounding box for determing size of FACE. If not supplied,
+ // uses the super bounding box of the model.
FACE* make_FACE( FACE* FACE_ptr,
- CubitBoolean extended_from = CUBIT_FALSE
+ CubitBoolean extended_from = CUBIT_FALSE,
+ CubitBox *limit_box = 0
) const;
//R FACE*
- //R- REturned FACE pointer
+ //R- Returned FACE pointer
//I- Existing FACE to make a copy from.
- //I- flag to tell whether to extend the face to its full geometric form or not.
+ //I- Flag to tell whether to extend the face to its full geometric form or not.
+ //I- Optional bounding box for determing size of FACE if extended_from is TRUE
+ // (used for planes, cones and cylinders). If not supplied, uses the overall
+ // Cubit model bounding box.
//- This function accepts apointer to a face and makes an api
//- call to copy this face and construct a sheet body from it.
- FACE* make_FACE( GeometryType FACE_type,
- DLIList<EDGE*>& EDGE_list,
- Surface *old_surface_ptr = NULL) const;
- //R FACE*
- //R- Returned FACE pointer
- //I FACE_type
- //I- The type of geometry entity to be associated with the FACE
- //I- that is created
- //I EDGE_list
- //I- Input list of EDGEs that bound the FACE to be made.
- //- This function creates an ACIS FACE using the EDGEs in EDGE_list.
- //- The type of the underlying geometry is determined by the
- //- FACE_type argument.
- //- All other associated ACIS entities are also created.
-
BODY* make_planar_quad_BODY ( const CubitVector& Point1,
const CubitVector& Point2,
const CubitVector& Point3,
@@ -1512,9 +1773,10 @@
CubitStatus webcut( DLIList<BodySM*>& webcut_body_list,
BODY* tool_BODY,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*>& results_list,
- bool imprint = false
- ) const ;
+ ImprintType imprint_type = NO_IMPRINT,
+ bool preview = false) const ;
//R int
//R- Number of bodies that were webcut ( >= 0 )
//I webcut_body_list
@@ -1568,41 +1830,50 @@
//- Deletes the Bodies in body_list and the Acis BODYs in BODY_list
-
+ CubitStatus stitch_FACEs( DLIList<FACE*> &faces,
+ FACE *&result_FACE,
+ BODY *&stitched_BODY );
+ //I List of FACEs you want stitched together
+ //IO Pointer to FACE...gets set if all FACEs can be stitched into single FACE
+ //IO If stitching of FACEs is successful, stitched_BODY is resultant BODY.
+ // Means that all faces could be stitched together, forming a single BODY,
+ // but not a single FACE.
+ //returns CUBIT_SUCCESS if stitching was successful, other return FAILURE
- void webcut_imprint(BODY* cutting_tool_BODY_ptr,
- DLIList<BodySM*> &old_body_list,
- DLIList<BODY*>& new_webcut_BODY_list,
- DLIList<BODY*>& just_webcut_BODY_list,
- DLIList<BodySM*>& results_list,
- DLIList<BodySM*> &imprinted_model_Body_list,
- DLIList<BODY*> &imprinted_model_BODY_list) const ;
- //I cutting_tool_BODY_ptr
- //I- Pointer to the Cutting Tool BODY. This is required in the case
- //I- where an existing Body - is used as the CT. In that case, its BODY
- //I- is kept out of the imprint operations.
- //IO new_webcut_BODY_list
- //IO- List of BODYs created by webcutting the list of RefBodies
- //IO- specified in the webcut command. New BODYs created as a product
- //IO- of performing imprints on the existing BODYs in the Model are
- //IO- appended to this list.
- //- Performs the required imprint operations to ensure that the topologies
- //- of the boundaries of the new webcut BODYs "match" those of their
- //- neighbouring BODYs (for mesh compatibility reasons).
+ CubitStatus finish_webcut( BODY *tool_BODY,
+ DLIList<BodySM*> &original_bodysm_list, //original BodySMs of successfully webcut bodies
+ DLIList<BODY*> &original_BODY_list, //original ACIS BODYs
+ DLIList<BODY*> &new_webcut_BODY_list, //BODYs resulting from successful webcuts
+ DLIList<BodySM*> &neighbor_imprint_list, //
+ //with bodies that were webcut
+ ImprintType imprint_type,
+ DLIList<BodySM*> &results_list ) const;
+ //tool_BODY -- tool body...just to make sure a neighbor isn't the tool body
+ // so the tool doesn't get imprinted
+ //original_bodysm_list -- original BodySMs that were successfully webcut
+ //original_BODY_list -- original ACIS BODYs that whose copy was successfully webcut
+ //new_webcut_BODY_list -- copied ACIS BODYs that were successfully
+ //neighbor_imprint_list -- neighbor BodySMs that need to be imprinted with bodies
+ // that were webcut
+ //imprint_type -- type of imprint
+ //results_list -- BodySMs resulting from the webcut and all neighbors
+
+ CubitStatus webcut_bodies_with_sheet_body( BODY *sheet_BODY,
+ DLIList<BodySM*> &blank_bodysms,
+ DLIList<BodySM*> &neighbor_imprint_list,
+ DLIList<BodySM*> &result_bodysms,
+ ImprintType imprint_type,
+ int &num_cut,
+ CubitBoolean preview );
+
+
BODY* create_infinite_plane_cutting_tool( const CubitVector &vecVertex1,
const CubitVector &vecVertex2,
const CubitVector &vecVertex3,
const SPAbox& super_box,
bool just_face = false ) const;
- BODY* copy_BODY (BODY* body_ptr,
- bool remove_attribs = true ) const;
- //- Make a copy of the input BODY, body_ptr, and return a pointer
- //- to the new BODY. If the operation fails, a NULL pointer is returned.
- //- If remove_attribs is set to CUBIT_TRUE, then the attributes from the
- //- original BODY will be stripped off the new BODY (these are automatically
- //- copied to the new BODY, by ACIS.
//HEADER- Functions related to geometric sweep operations
@@ -1756,13 +2027,13 @@
//- to be done first using the GeometryTool::is_interfering procedure.
CubitStatus imprint( BODY *BODY_ptr, DLIList<FACE*> &FACE_list,
- DLIList<EDGE*> &EDGE_list ) const;
+ DLIList<EDGE*> &EDGE_list, DLIList<TopologyBridge*> &temporary_bridges ) const;
//- Imprints a list of FACEs with a list of EDGEs. The FACEs must
//- be from the same BODY that is passed in. FACEs are modified but
//- EDGEs are not.
CubitStatus imprint( BODY *BODY_ptr, DLIList<FACE*> &FACE_list,
- DLIList<DLIList<EDGE*>*> &EDGE_lists_list ) const;
+ DLIList<DLIList<EDGE*>*> &EDGE_lists_list, bool expand = false ) const;
//- Same as above function, except more efficient if it is known exactly
//- which EDGEs need to be imprinted with which FACEs. Note as input
//- there is a corresponding EDGE_list for each input FACE. The function
@@ -1793,13 +2064,21 @@
//- This function removes topology that is not essential
//- to the existance of the body.
CubitStatus regularize_entity( GeometryEntity *old_refentity_ptr,
- BodySM *&new_body_ptr );
+ BodySM *&new_body_ptr);
//- clean RefEntity
+ CubitStatus test_regularize_entity( GeometryEntity *old_refentity_ptr);
+ CubitStatus get_copied_FACES_and_EDGES_of_body( DLIList<SurfaceACIS*>& ref_face_list,
+ DLIList<CurveACIS*>& ref_edge_list,
+ DLIList<FACE*>& FACE_list,
+ DLIList<EDGE*>& EDGE_list,
+ DLIList<SurfaceACIS*>& removed_ref_faces,
+ DLIList<CurveACIS*>& removed_ref_edges,
+ BODY*& copied_BODY_ptr ) const;
CubitStatus get_copied_FACES_of_body( DLIList<SurfaceACIS*>& ref_face_list,
DLIList<FACE*>& FACE_list,
BODY*& copied_BODY_ptr ) const;
- //- Given a list of RefFaces, this function returns a list of Acis FACE's
+ //- Given a list of Surfaces, this function returns a list of Acis FACE's
//- from a BODY that it copies from the parent BODY of the first RefFace in
//- the incoming list. This body is also returned, and still contains
//- all the CUBIT attributes that the original BODIES had. The referenced
@@ -1862,7 +2141,10 @@
CubitStatus embed_curves_into_surface( Surface *surface,
DLIList<Curve*> &curves_to_imprint,
- BodySM *&new_body ) const;
+ DLIList<TopologyBridge*> &temporary_bridges,
+ BodySM *&new_body,
+ DLIList<TopologyBridge*> *new_tbs = NULL,
+ DLIList<TopologyBridge*> *att_tbs = NULL ) const;
//Embeds the given curves into the surface. Equaivalent to imprinting, but
//works well for curves that have tolerance problems, (i.e. might not reach
//the bounding curves of the surface, or might be almost coincident with a
@@ -1872,7 +2154,16 @@
//api_embed_wire_in_faces returns unexpected results if the curve
//does not lie on the surface.
-
+ CubitStatus imprint_overlapping_curves( DLIList<Surface*> &surfs,
+ DLIList<BodySM*> &new_body_sms) const;
+ CubitStatus imprint_overlapping_curves( DLIList< DLIList<Curve*>* > &lists_of_mergeable_curves,
+ DLIList< DLIList<Curve*>* > &lists_of_overlapping_curves,
+ std::map<Curve*, DLIList<Curve*>* > &curve_to_list_map,
+ std::multimap<BodySM*, CubitVector> &body_vertex_imprint_map,
+ DLIList<BodySM*> &new_body_sms,
+ ProgressTool *progress_tool,
+ DLIList<TopologyBridge*> *new_tbs,
+ DLIList<TopologyBridge*> *att_tbs ) const;
CubitStatus imprint_overlapping_curves( DLIList<BodySM*> &body_sms,
DLIList<BodySM*> &new_body_sms,
ProgressTool *progress_tool = NULL,
@@ -1882,17 +2173,87 @@
//After a call to this function, all overlapping curves between the
//bodies are also mergeable.
+ CubitStatus imprint_overlapping_surfaces( DLIList<Surface*> &surfs,
+ DLIList<BodySM*> &new_body_sms,
+ DLIList<Surface*> *new_surface_list = NULL) const;
+ CubitStatus imprint_overlapping_surfaces(DLIList<Surface*> &overlapping_surfaces1,
+ DLIList<Surface*> &overlapping_surfaces2,
+ DLIList<BodySM*> &new_body_sms,
+ ProgressTool *progress_tool = NULL,
+ DLIList<Surface*> *new_surface_list = NULL) const;
CubitStatus imprint_overlapping_surfaces( DLIList<BodySM*> &body_sms,
DLIList<BodySM*> &new_body_sms,
ProgressTool *progress_tool = NULL) const;
//Given a list of bodies, if Surface A overlaps with surface B, imprints
//appropriate curves of surface A onto surface B then curves of B onto A.
-void get_new_ENTITIES(ENTITY *top_ENTITY, DLIList<ENTITY*> &new_ENTITIES) const;
-void get_att_ENTITIES(ENTITY *top_ENTITY, DLIList<ENTITY*> &att_ENTITIES, char *att_name) const;
+ void get_new_ENTITIES(ENTITY *top_ENTITY, DLIList<ENTITY*> &new_ENTITIES,
+ DLIList<DLIList<EDGE*>*> *list_of_EDGES_on_original_FACES = NULL,
+ DLIList<DLIList<EDGE*>*> *imprint_EDGE_lists = NULL) const;
+ void get_att_ENTITIES(ENTITY *top_ENTITY, DLIList<ENTITY*> &att_ENTITIES, const char *att_name) const;
DLIList<EDGE*> find_new_EDGES(BODY *copied_BODY_ptr);
// Marks all of the edges without Cubit owners as imprint features
+ CubitStatus remove_FACEs_from_BODY( BODY *BODY_ptr,
+ DLIList<FACE*> &remove_FACE_list,
+ CubitBoolean silent = CUBIT_FALSE );
+ //- Remove the given FACEs from the BODY (modifying the input BODY). The
+ //- input BODY is assumed to be a sheet body. All input FACEs must be from
+ //- a single BODY. Includes option to suppress any error messages.
+
+ CubitStatus remove_FACEs_from_BODY_except( BODY *BODY_ptr,
+ DLIList<FACE*> &keep_FACE_list,
+ CubitBoolean silent = CUBIT_FALSE );
+ //- Remove all FACEs from the BODY except those in the keep_FACE_list
+ //- (modifying the input BODY). The input BODY is assumed to be a sheet
+ //- BODY. All input FACEs must be from a single BODY. Includes option
+ //- to suppress any error messages.
+
+ CubitStatus remove_dup_owners( BODY *ref_BODY_ptr, BODY *BODY_ptr );
+ //- Remove duplicate Cubit owners from the BODY_ptr. The ref_BODY_ptr is
+ //- unchanged - Cubit owner attributes that exist in both BODY_ptr and
+ //- ref_BODY_ptr are removed from BODY_ptr.
+
+ CubitStatus remove_dup_owners( BODY *ref_BODY_ptr, BODY *BODY_ptr, const int type );
+ //- Remove duplicate Cubit owners from the BODY_ptr. The ref_BODY_ptr is
+ //- unchanged - Cubit owner attributes that exist in both BODY_ptr and
+ //- ref_BODY_ptr are removed from BODY_ptr. The type of ENTITY to operate
+ //- on is specified by the type: BODY_TYPE, LUMP_TYPE, SHELL_TYPE,
+ //- FACE_TYPE, LOOP_TYPE, COEDGE_TYPE, EDGE_TYPE or VERTEX_TYPE.
+
+ CubitStatus trim_BODY_to_box( BODY *&BODY_ptr, CubitBox &box ) const;
+ //- Trim the given BODY to fit within the given CubitBox.
+
+ CubitStatus stitch_simplify_and_tighten_gaps(ENTITY_LIST& bodies_imported_into_ACIS,
+ ENTITY_LIST& output_bodies,
+ bool tighten_gaps,
+ double tolerance )const;
+
+ CubitStatus stitch_entities( ENTITY_LIST& to_be_stitched,
+ ENTITY_LIST& output_bodies,
+ tolerant_stitch_options& sopts)const;
+
+ CubitStatus tighten_gaps_in_body(BODY*& body,
+ const double& desired_gap_tightness)const;
+
+ CubitStatus simplify_entity(ENTITY*& entity_to_simplify,
+ simplify_options& simp_opts)const;
+
+ bool handle_fatal_problem_reported_by_outcome(const outcome& api_outcome)const;
+
+ void handle_problems_reported_by_outcome(const outcome& api_outcome)const;
+
+ void display_problems_encountered(const error_info *einf)const;
+
+ void start_tracking_history( DLIList<TopologyBridge*> &bridges,
+ AcisHistory &history_object,
+ bool ignore_parents = false );
+
+ void stop_tracking_history( DLIList<BodySM*> &new_bodies,
+ AcisHistory &history_object );
+
+ void stop_tracking_history( DLIList<TopologyBridge*> &new_tbs,
+ AcisHistory &history_object );
};
#endif
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisQueryEngine.cpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisQueryEngine.cpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisQueryEngine.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -36,6 +36,7 @@
#include <ctype.h>
#include <assert.h>
#include <errno.h>
+#include <map>
// ********** END STANDARD INCLUDES **********
// ********** BEGIN ACIS INCLUDES **********
@@ -44,8 +45,10 @@
#include "cstrapi.hxx"
#include "eulerapi.hxx"
#include "intrapi.hxx"
+#include "raytest.hxx"
#include "api.hxx"
#include "kernapi.hxx"
+#include "kernopts.hxx"
#include "ptentrel.hxx"
#include "getbox.hxx"
#include "debug.hxx"
@@ -120,16 +123,28 @@
#include "module.hxx"
#include "option.hxx"
#include "getowner.hxx"
+#include "insanity_list.hxx"
-#if CUBIT_ACIS_VERSION >= 1600
-#include "clash_bodies.hxx"
+#if defined(WIN32)
+#if CUBIT_ACIS_VERSION >= 1700
+
+#ifdef CAT
+#include "spa_unlock_2380.cpp"
+#else
+#include "spa_unlock_2312.cpp"
#endif
+#endif
+#endif
+
#ifdef ACIS_IGES_TRANSLATOR
#include "errorcode.err"
-#include "acisiges_api.hxx"
-#include "SPAXUnit.h"
-#include "acis_unit_api.h"
+//#include "acisiges_api.hxx"
+//#include "SPAXUnit.h"
+//#include "acis_unit_api.h"
+#include "heal_api.hxx"
+
+#include "SPAIUnit.h"
#endif
#ifdef ACIS_PROE_TRANSLATOR
@@ -141,16 +156,30 @@
#include "cathusk/chl_api/apiwrite.hxx"
#endif
#ifdef ACIS_STEP_TRANSLATOR
-#include "acisstep_api.hxx"
+//#include "acisstep_api.hxx"
#endif
#if defined( ACIS_IGES_TRANSLATOR) || defined( ACIS_STEP_TRANSLATOR )
- #include "SPAXBase.h"
- #include "SPAXBoolean.h"
- #include "SPAXProgressReportCB.h"
+ #include "SPAIConverter.h"
+ #include "SPAIDocument.h"
+ #include "SPAIAcisDocument.h"
+ #include "SPAIProgressCallback.h"
+ #include "SPAIOptions.h"
+ #include "SPAIOptionName.h"
+ #include "SPAIValue.h"
#endif
+#ifdef IGTO
+// For iGTO, these includes need to happen
+#include "lop_api.hxx"
+#include "warp_api.hxx"
+#include "part_api.hxx"
+#include "skinapi.hxx"
+#endif
+#include "blendapi.hxx"
+
+
// ********** END ACIS INCLUDES **********
// ********** BEGIN CUBIT INCLUDES **********
@@ -200,6 +229,11 @@
#include "GfxDebug.hpp"
#include "AcisFeatureEngine.hpp"
+#ifdef CUBIT_GUI
+#ifndef NO_USAGE_TRACKING
+#include "GUIInterface.h"
+#endif
+#endif // CUBIT_GUI
const int AcisQueryEngine::MAX_NUM_CURVE_POINTS = 750;
const int AcisQueryEngine::AQE_SUBMINOR_VERSION = 0;
@@ -211,15 +245,19 @@
api_terminate_generic_attributes();
api_terminate_spline();
api_terminate_kernel();
+ api_terminate_blending();
api_terminate_intersectors();
api_terminate_constructors();
api_terminate_euler_ops();
+
+/*
#ifdef ACIS_IGES_TRANSLATOR
api_terminate_xiges();
#endif
#ifdef ACIS_STEP_TRANSLATOR
api_terminate_xstep();
#endif
+ */
#ifdef ACIS_PROE_TRANSLATOR
api_terminate_proe();
#endif
@@ -397,11 +435,19 @@
handled = CUBIT_FALSE;
else
{
- // Since the user is requesting this EDGE be exported freely,
- // copy it to a new entity (in case it's not really a free edge)
- copy_single_entity((ENTITY*)EDGE_ptr, copied_entity_ptr);
- entity_list.add(copied_entity_ptr);
- copied_entity_list.add(copied_entity_ptr);
+ ENTITY_LIST ent_list;
+ api_get_faces( (ENTITY*)EDGE_ptr, ent_list );
+
+ if( ent_list.count() )
+ {
+ // Since the user is requesting this EDGE be exported freely,
+ // copy it to a new entity (since it is not a free edge)
+ copy_single_entity((ENTITY*)EDGE_ptr, copied_entity_ptr);
+ entity_list.add(copied_entity_ptr);
+ copied_entity_list.add(copied_entity_ptr);
+ }
+ else
+ entity_list.add( EDGE_ptr );
edge_count++;
}
}
@@ -415,11 +461,18 @@
handled = CUBIT_FALSE;
else
{
- // Since the user is requesting this VERTEX be exported freely,
- // copy it to a new entity (in case it's not really a free vertex)
- copy_single_entity((ENTITY*)VERTEX_ptr, copied_entity_ptr);
- entity_list.add(copied_entity_ptr);
- copied_entity_list.add(copied_entity_ptr);
+ ENTITY_LIST ent_list;
+ api_get_edges( (ENTITY*)VERTEX_ptr, ent_list );
+ if( ent_list.count() )
+ {
+ // Since the user is requesting this VERTEX be exported freely,
+ // copy it to a new entity (since it is not a free vertex)
+ copy_single_entity((ENTITY*)VERTEX_ptr, copied_entity_ptr);
+ entity_list.add(copied_entity_ptr);
+ copied_entity_list.add(copied_entity_ptr);
+ }
+ else
+ entity_list.add( VERTEX_ptr );
vertex_count++;
}
}
@@ -539,36 +592,55 @@
PRINT_ERROR( "The IGES translator is not licensed for this installation\n" );
return CUBIT_FAILURE;
#else
- CubitString version = "Cubit ";
- version += cubit_version;
- // Author, organization, sending system, receiving system
- result = api_xiges_set_header( getenv("USERNAME"), getenv("USERDOMAIN"),
- version.c_str(), NULL, 1, 1.0 );
- if( !result.ok() )
- {
- ACIS_API_error(result);
- PRINT_WARNING("unable to define IGES header information for '%s'\n", filename);
- }
+ CubitString version = "Cubit ";
+ version += cubit_version;
- char* logfilename = NULL;
- if( !logfile_name || !strcmp( logfile_name, "" ) )
- strcpy(logfilename, "iges_export.log");
- else
- logfilename = (char *)logfile_name;
-
- result = api_xiges_write( entity_list, (char *)filename, logfilename );
+ char *username;
+ #if defined(WIN32)
+ username = getenv("USERNAME");
+ #else
+ username = getenv("USER");
+ #endif
- if( !result.ok() )
- {
- PRINT_ERROR("Acis could not export to the IGES file: '%s'\n", filename);
- ACIS_API_error(result);
- entity_list.clear();
- copied_entity_list.init();
- while ( (entity_ptr=copied_entity_list.next()) )
- api_delent( entity_ptr );
- return CUBIT_FAILURE;
- }
+ char *system_name;
+ #if defined(WIN32)
+ system_name = "Windows";
+ #endif
+
+ #if defined(CUBIT_LINUX)
+ system_name = "Linux";
+ #endif
+
+ #if defined(MACOSX)
+ system_name = "Apple";
+ #endif
+
+ SPAIOptions options;
+ options.Add( SPAIOptionName::AuthorName, username );
+ options.Add( SPAIOptionName::OrganizationName, version.c_str() );
+// options.Add( SPAIOptionName::SendingSystemName, system_name );
+ options.Add( SPAIOptionName::TranslateFreeCurves, true );
+
+ //create the destination document
+ SPAIAcisDocument src(&entity_list);
+ SPAIDocument dst( filename );
+ SPAIUnit spai_unit(SPAIUnitUnknown);
+ dst.SetUnit( spai_unit );
+
+ SPAIConverter converter;
+ converter.SetOptions( options );
+ SPAIFile log_file(logfile_name);
+ converter.StartLog(log_file);
+ SPAIResult tmp_result = converter.Convert(src, dst);
+ converter.StopLog(log_file);
+
+ if( tmp_result.IsFailure() )
+ {
+ PRINT_ERROR("%s\n", tmp_result.GetMessage() );
+ return CUBIT_FAILURE;
+ }
+
#endif //ACIS_IGES_TRANSLATOR
}
#ifdef ACIS_CATIA_TRANSLATOR
@@ -612,49 +684,29 @@
copied_entity_list.init();
while ( (entity_ptr=copied_entity_list.next()) )
api_delent( entity_ptr );
-#if defined(SGI)
- PRINT_ERROR("The STEP translator is not available for the 64-bit SGI platform\n");
-#else
PRINT_ERROR( "The STEP translator is not licensed for this installation\n" );
-#endif
return CUBIT_FAILURE;
-#else
- if ( !stepInitialized ) {
- PRINT_ERROR("The STEP translater has not been properly initialized.\n");
- entity_list.clear();
- copied_entity_list.init();
- while ( (entity_ptr = copied_entity_list.next()) )
- api_delent( entity_ptr );
-
- return CUBIT_FAILURE;
- }
-
- char* logfilename = NULL;
- if( !logfile_name || !strcmp( logfile_name, "" ) )
- strcpy(logfilename, "step_export.log");
- else
- logfilename = (char *)logfile_name;
+#else
+ char* logfilename = NULL;
+ if( !logfile_name || !strcmp( logfile_name, "" ) )
+ strcpy(logfilename, "step_export.log");
+ else
+ logfilename = (char *)logfile_name;
- result = api_xstep_write( entity_list, (char *)filename, logfilename );
+ SPAIAcisDocument src(&entity_list);
+ SPAIDocument dst( filename );
+ SPAIConverter converter;
+ SPAIFile log_file(logfile_name);
+ converter.StartLog(log_file);
+ SPAIResult tmp_result = converter.Convert(src, dst);
+ converter.StopLog(log_file);
-// BODY* block;
-// result = api_make_cuboid(10.0, 10.0, 10.0, block);
-// ENTITY_LIST elist;
-// elist.init();
-// elist.add(block);
-// result = api_step_convert_acisentlist_to_step(elist, "block.step", "block_step_write.log", NULL);
-// api_delent(block);
-
- if( !result.ok() )
- {
- PRINT_ERROR("ACIS could not export to the STEP file: '%s'\n", filename);
- ACIS_API_error(result);
- entity_list.clear();
- copied_entity_list.init();
- while ( (entity_ptr=copied_entity_list.next()) )
- api_delent( entity_ptr );
- return CUBIT_FAILURE;
- }
+ if( tmp_result.IsFailure() )
+ {
+ PRINT_ERROR("%s\n", tmp_result.GetMessage() );
+ return CUBIT_FAILURE;
+ }
+
#endif
}
@@ -832,12 +884,10 @@
CubitBoolean import_vertices,
CubitBoolean free_surfaces)
{
- int i;
CpuTimer import_solid_model_timer;
CubitBoolean step_import = CUBIT_FALSE;
CubitBoolean iges_import = CUBIT_FALSE;
-
// Check to make sure the requested type is supported
if (strcmp(file_type, "ACIS_SAT") != 0 &&
strcmp(file_type, "ACIS_SAB") != 0 &&
@@ -998,8 +1048,6 @@
Surface* surface_ptr;
Curve* curve_ptr;
Point* point_ptr;
- int percent_after = 0,
- number_splines_simplified = 0;
CubitStatus status = CUBIT_SUCCESS;
outcome result;
@@ -1552,6 +1600,79 @@
return about_spatially_equal(pos1, pos2, tolerance_factor);
}
+CubitBoolean AcisQueryEngine::about_spatially_equal (EDGE* E1, EDGE* E2) const
+{
+ CubitBoolean ret = CUBIT_TRUE;
+
+ if( E1 == E2 )
+ return CUBIT_TRUE;
+
+ SPAinterval e1_range = E1->param_range();
+ SPAinterval c1_range = e1_range;
+ if(E1->sense() == REVERSED)
+ c1_range.negate();
+ double c1_param = c1_range.start_pt() + (c1_range.end_pt() - c1_range.start_pt())/3.0;
+ const curve &c1 = E1->geometry()->equation();
+ SPAposition test_point_1, test_point_2;
+ // Find the point 1/3 along curve_1
+ c1.eval(c1_param, test_point_1);
+
+ // See if the 1/3 point on curve_1 lies on curve_2
+ const curve &c2 = E2->geometry()->equation();
+ c2.point_perp(test_point_1, test_point_2);
+
+ if (!about_spatially_equal(test_point_1, test_point_2 ))
+ ret = CUBIT_FALSE;
+
+ if(ret == CUBIT_TRUE)
+ {
+ /*
+ c2.eval(c2_param, test_point_2, c2_deriv);
+
+ //If one of the curves is zero-length, it will have a zero
+ //tangent vector.
+ double len_product = c1_deriv.len() * c2_deriv.len();
+ if( len_product > CUBIT_DBL_MIN )
+ {
+ double dot_product = c1_deriv % c2_deriv;
+ if (dot_product < 0)
+ relative_sense = CUBIT_REVERSED;
+ }
+ else
+ {
+ //If one of the tangents is zero-length, one of the curves had
+ //better be as well.
+ assert( (c1.length() * c2.length()) < CUBIT_RESABS );
+ }
+ */
+
+ VERTEX *E1V1 = E1->start();
+ VERTEX *E1V2 = E1->end();
+ VERTEX *E2V1 = E2->start();
+ VERTEX *E2V2 = E2->end();
+ if(about_spatially_equal(E1V1, E2V1))
+ {
+ if(!about_spatially_equal(E1V2, E2V2))
+ ret = CUBIT_FALSE;
+ }
+ else if(about_spatially_equal(E1V1, E2V2))
+ {
+ if(!about_spatially_equal(E1V2, E2V1))
+ ret = CUBIT_FALSE;
+ }
+ else
+ ret = CUBIT_FALSE;
+ }
+
+ if(ret == CUBIT_TRUE)
+ {
+ if(fabs(E1->length() - E2->length()) > GEOMETRY_RESABS)
+ ret = CUBIT_FALSE;
+ }
+
+ return ret;
+}
+
//-------------------------------------------------------------------------
// Purpose : Unhook the ENTITY's references in VGI. Call the next
// level of the series of functions to allow other
@@ -1921,7 +2042,49 @@
return CUBIT_TRUE;
}
}
+//-------------------------------------------------------------------------
+// Purpose : Save the input ENTITYs to a SAT file
+//
+// Special Notes :
+//
+// Creator : Corey Ernst
+//
+// Creation Date : 2/13/2008
+//-------------------------------------------------------------------------
+int AcisQueryEngine::save_ENTITYs_as_sat_file ( ENTITY_LIST *entity_list,
+ const char* filename,
+ const char* update_mode ) const
+{
+ FILE* ENTITY_file_ptr = fopen(filename, update_mode);
+ if (ENTITY_file_ptr == NULL)
+ {
+ PRINT_ERROR ("Cannot open file. ENTITY not saved.\n");
+ return CUBIT_FALSE;
+ }
+ else
+ {
+ CubitString version = "Cubit ";
+ CubitString cubit_version("12.0b");
+ version += cubit_version;
+ FileInfo info;
+ info.set_product_id(version.c_str());
+ info.set_units(1.0);
+ api_set_file_info((FileId | FileUnits), info);
+
+ outcome result = api_save_entity_list(ENTITY_file_ptr,
+ CUBIT_TRUE, *entity_list);
+ fclose(ENTITY_file_ptr);
+ if (!result.ok())
+ {
+ ACIS_API_error(result);
+ PRINT_ERROR ("Problem saving ENTITY to sat file.\n");
+ return CUBIT_FALSE;
+ }
+ return CUBIT_TRUE;
+ }
+}
+
//-------------------------------------------------------------------------
// Purpose : Return a bounding box that encompasses all the
// ENTITYs in the input ENTITY_LIST.
@@ -2210,14 +2373,10 @@
SPAposition &box_min,
SPAposition &box_max ) const
{
- int number_triangles, number_points, number_facets;
GMem gMem;
- CubitStatus status =
- get_graphics(face_ptr, number_triangles, number_points,
- number_facets, &gMem,
- 15, 0);
- if (status != CUBIT_SUCCESS || number_facets == 0) {
+ CubitStatus status = get_graphics(face_ptr, &gMem, 15, 0);
+ if (status != CUBIT_SUCCESS || gMem.fListCount == 0) {
status = CUBIT_FAILURE;
return status;
}
@@ -2226,7 +2385,7 @@
xmin = ymin = zmin = DBL_MAX;
xmax = ymax = zmax = -DBL_MAX;
GPoint* plist = gMem.point_list();
- for (int i = 0; i<number_points; i++) {
+ for (int i = 0; i<gMem.pointListCount; i++) {
if (plist[i].x > xmax) xmax = plist[i].x;
if (plist[i].y > ymax) ymax = plist[i].y;
if (plist[i].z > zmax) zmax = plist[i].z;
@@ -3432,7 +3591,6 @@
//-------------------------------------------------------------------------
CubitStatus AcisQueryEngine::get_graphics(
Surface* surface_ptr,
- int& number_triangles, int& number_points, int& facet_list_size,
GMem* g_mem, unsigned short normal_tolerance, double distance_tolerance,
double max_edge_length ) const
{
@@ -3440,27 +3598,15 @@
FACE* face_ptr = get_FACE(surface_ptr);
if (face_ptr == NULL)
return CUBIT_FAILURE;
- return get_graphics ( face_ptr, number_triangles, number_points,
- facet_list_size, g_mem, normal_tolerance,
+ return get_graphics ( face_ptr, g_mem, normal_tolerance,
distance_tolerance, max_edge_length );
}
CubitStatus AcisQueryEngine::get_graphics(
FACE* face_ptr,
- int& number_triangles, int& number_points, int& facet_list_size,
GMem* g_mem, unsigned short normal_tolerance, double distance_tolerance,
double max_edge_length ) const
{
- // Because this may be unnecessarily called twice,
- // say there is one triangle.
- if (!g_mem)
- {
- number_triangles = 1;
- number_points = 3;
- facet_list_size = 4;
- return CUBIT_SUCCESS;
- }
-
#if CUBIT_ACIS_VERSION >= 800
// distance tolerance ignore value was changed
// handle it here for everyone in cubit
@@ -3501,13 +3647,6 @@
return CUBIT_FAILURE;
}
- // Fill in the return variables and return.
- // These variables really aren't needed, because they
- // are returned as part of g_mem.
- number_points = g_mem->pointListCount;
- facet_list_size = g_mem->fListCount;
- number_triangles = facetManager->polygon_count();
-
return CUBIT_SUCCESS;
}
@@ -3523,11 +3662,9 @@
// Creation Date : 03/04/97
//-------------------------------------------------------------------------
CubitStatus AcisQueryEngine::get_graphics( Curve* curve_ptr,
- int& num_points,
GMem* g_mem,
double tolerance ) const
{
- CubitStatus rv;
EDGE* the_EDGE = get_EDGE(curve_ptr);
// NULL pointer is OK
@@ -3539,10 +3676,34 @@
tolerance = SPAresfit;
}
- rv = this->facet_EDGE(the_EDGE, num_points, g_mem, (double)tolerance);
- if (rv == CUBIT_FAILURE)
- PRINT_ERROR("Unable to facet curve\n");
- return rv;
+ SPAposition* io_points=NULL;
+ double* io_params=NULL;
+ int out_count;
+
+ outcome result = api_facet_edge(the_EDGE, tolerance, 0, 15, 0, out_count,
+ &io_points, &io_params);
+ if(!result.ok())
+ {
+ PRINT_ERROR("Unable to facet curve\n");
+ return CUBIT_FAILURE;
+ }
+
+ g_mem->allocate_polylines(out_count - 1);
+ g_mem->fListCount = 0;
+ g_mem->pointListCount = out_count;
+
+ GPoint* pts = g_mem->point_list();
+ for(int i=0; i<out_count; i++)
+ {
+ pts[i].x = io_points[i].x();
+ pts[i].y = io_points[i].y();
+ pts[i].z = io_points[i].z();
+ }
+
+ ACIS_DELETE [] io_points;
+ ACIS_DELETE [] STD_CAST io_params;
+
+ return CUBIT_SUCCESS;
}
CubitStatus AcisQueryEngine::facet_EDGE(const EDGE* EDGE_ptr, int& num_points,
@@ -3797,7 +3958,6 @@
}
AcisQueryEngine::AcisQueryEngine()
- : stepInitialized(false)
{
assert( !instance_ );
@@ -3814,6 +3974,15 @@
#endif
initialize_base(&base_config);
+#if defined(WIN32)
+ #if CUBIT_ACIS_VERSION >= 1700
+ #ifdef CAT
+ unlock_spatial_products_2380();
+ #else
+ unlock_spatial_products_2312();
+ #endif
+ #endif
+#endif
outcome error = api_start_modeller ( CUBIT_FALSE);
if ( !error.ok() )
@@ -3826,27 +3995,19 @@
api_initialize_generic_attributes();
api_initialize_spline();
api_initialize_kernel();
+ api_initialize_blending();
api_initialize_intersectors();
api_initialize_constructors();
api_initialize_euler_ops();
-#ifdef ACIS_IGES_TRANSLATOR
- error = api_initialize_xiges();
-#endif //end IGES TRANSLATOR
+#ifdef IGTO
+ // Need the next 4 calls for iGTO
+ api_initialize_local_ops() ;
+ api_initialize_part_manager() ;
+ api_initialize_skinning() ;
+ api_initialize_warp() ;
+#endif
-
-#ifdef ACIS_STEP_TRANSLATOR
-
- outcome my_result = api_initialize_xstep();
- ACIS_API_error(my_result);
- stepInitialized = true;
-
- // Convert assembly parts to separate bodies, as opposed as
- // one body with multiple lumps.
- api_set_int_option( "stp_assemb_part_as_body", 1 );
-
-#endif /* ACIS_STEP_TRANSLATOR */
-
#ifdef ACIS_PROE_TRANSLATOR
api_initialize_proe();
#endif
@@ -3874,11 +4035,17 @@
this_option = find_option ( "tight_torus_box" );
this_option -> set ( TRUE );
+#ifdef IGTO
+ // Need the next 2 lines for iGTO
+ this_option = find_option ( "annotation" );
+ this_option->set(FALSE);
+#endif
+
#ifdef ACIS_IGES_TRANSLATOR
- api_xiges_Ig2Ac_ConvFreeCurves_Set( TRUE );
+ //api_xiges_Ig2Ac_ConvFreeCurves_Set( TRUE );
//reads in file based on units in file....prevents scaling
- api_xacis_set_application_unit( spaxUnit_unknown );
+ //api_xacis_set_application_unit( spaxUnit_unknown );
#endif
this_option = find_option ( "compress_bb" );
@@ -3887,7 +4054,7 @@
// We can have a different refinement for each body passed in. For
// example, we may want to adjust the refinement according to the body
// size. But for demonstration, we will just use the same one for all.
- REFINEMENT *refinement_ptr;
+ REFINEMENT *refinement_ptr = 0;
// Create a refinement.
outcome result = api_create_refinement(refinement_ptr);
if (!result.ok())
@@ -4233,242 +4400,70 @@
return CUBIT_SUCCESS;
}
-CubitStatus AcisQueryEngine::fire_ray( BodySM *body,
- const CubitVector &ray_point,
- const CubitVector &unit,
- DLIList<double>& ray_params,
- DLIList<GeometryEntity*> *entity_list) const
+CubitStatus
+AcisQueryEngine::fire_ray( CubitVector &origin,
+ CubitVector &direction,
+ DLIList<TopologyBridge*> &at_entity_list,
+ DLIList<double> &ray_params,
+ int max_hits,
+ double ray_radius,
+ DLIList<TopologyBridge*> *hit_entity_list ) const
{
- ray_params.clean_out();
-
- // fire a ray at the specified body, returning the entities hit and
- // the parameters along the ray; return non-zero if error
-
- // since ACIS only returns a given entity once, even if it is hit
- // twice (goofy, huh?), we need to fire two rays, one from each direction,
- // and possibly more if the hits don't match
- const double SCALE_FACTOR = 1.05;
-
- SPAposition pos_low(ray_point.x(), ray_point.y(), ray_point.z());
- SPAunit_vector vector_low(unit.x(), unit.y(), unit.z());
-
- // use SPAresabs to get the surface when possible
- double ray_radius = GEOMETRY_RESABS;
- int hits_wanted = 0;
-
- ENTITY_LIST entities_low;
- double *params_low = NULL;
- outcome rc;
- GeometryEntity *geom_entity;
- BODY *body_ACIS = get_BODY( body );
-
-
- rc = api_ray_test_body (pos_low, vector_low, ray_radius, hits_wanted,
- body_ACIS, entities_low, params_low);
-
-
- if (!rc.ok()) {
- PRINT_ERROR("First ray fire failed for body\n");
- ACIS_API_error(rc, "Ray fire");
- entities_low.clear();
- return CUBIT_FAILURE;
- }
- else if (!entities_low.count())
- {
- entities_low.clear();
- return CUBIT_SUCCESS;
- }
- // get new position that's totally outside bounding SPAbox
- CubitBox box = bounding_box(bounding_box(get_BODY(body)));
- // use max range of bounding box - seems like it should be easier
- // than this!
- CubitVector ray_point2 = ray_point + SCALE_FACTOR * unit *
- CUBIT_MAX_4(box.x_range(), box.y_range(), box.z_range(), 0);
- SPAposition pos_high(ray_point2.x(), ray_point2.y(), ray_point2.z());
-
- ENTITY_LIST entities_high;
- double *params_high = NULL;
- SPAunit_vector vector_high = -vector_low;
- hits_wanted = 0;
-
- rc = api_ray_test_body (pos_high, vector_high, ray_radius, hits_wanted,
- body_ACIS, entities_high, params_high);
-
-
- if (!rc.ok()) {
- PRINT_ERROR("Second ray fire failed for body\n");
- ACIS_API_error(rc, "Ray fire");
- entities_low.clear();
- entities_high.clear();
- return CUBIT_FAILURE;
- }
- // now compare entities on list, marching backward on one list and
- // forward on the other; if a mismatch is found, need to fire another ray
-
- if (DEBUG_FLAG(1)) {
- CubitVector dum = ray_point;
- GfxDebug::draw_vector(dum, ray_point2, CUBIT_YELLOW);
- GfxDebug::flush();
- }
-
- int ilow = 0;
- int ihigh = entities_high.count()-1;
- ENTITY_LIST entities_hit;
+ // Get ACIS entities
+ DLIList<ENTITY*> at_ENTITY_list;
+ TopologyBridge *bridge_ptr;
+ AcisBridge *acis_bridge_ptr;
+ ENTITY *ENTITY_ptr;
+ int i;
+ at_entity_list.reset();
+ for( i=at_entity_list.size(); i--; )
+ {
+ bridge_ptr = at_entity_list.get_and_step();
+ acis_bridge_ptr = CAST_TO( bridge_ptr, AcisBridge );
+ if( !acis_bridge_ptr )
+ {
+ PRINT_WARNING( "non-ACIS entity encountered where ACIS entity expected\n" );
+ continue;
+ }
- double range_orig = (pos_high - pos_low).len();
- double range = range_orig;
- // RefEntity *ref_entity;
- double res_high = 5.0 * GEOMETRY_RESABS;
- double offset = 0.0;
-
- // step up the low list and down the high list; entity on low list is
- // always added; if it is the first hit on a repeated entity, it will
- // not match the entity on the high list; if this is the case, the low
- // ray will be fired again and the low list counter reset; continue until
- // we are at the beginning of the high list
- TopologyEntity* topo_entity_ptr;
-
- while (ihigh >= 0) {
- ray_params.append(params_low[ilow] + offset);
-
- // would have done this later, after while loop, if ACIS lists
- // were not brain dead (no duplicates allowed!!!)
- if (entity_list)
- {
- topo_entity_ptr = ATTRIB_CUBIT_OWNER::get_topology_entity( entities_low[ilow] );
- geom_entity = CAST_TO( topo_entity_ptr, GeometryEntity );
- if (geom_entity) entity_list->append(geom_entity);
- }
-
- // do both an entity check and a SPAposition check, in case a single
- // entity is repeated (like the side surf of a cylinder)
- if (entities_low[ilow] == entities_high[ihigh] &&
- fabs(params_low[ilow] - (range - params_high[ihigh])) < res_high)
- {
- ilow++;
- ihigh--;
- }
-
- else {
- if (DEBUG_FLAG(55)) {
- // fire another low ray; add in 0.1% of the distance between high
- // and low hit parameters to make sure pos_low isn't on the surf
- double factor = .001 * (range - params_high[ihigh] - params_low[ilow]);
- offset += params_low[ilow] + factor;
- pos_low += (params_low[ilow] + factor) * vector_low;
- entities_low.clear();
- hits_wanted = 0;
- delete [] params_low;
- rc = api_ray_test_body (pos_low, vector_low, ray_radius, hits_wanted,
- body_ACIS, entities_low, params_low);
- if (!rc.ok()) {
- PRINT_ERROR("Supplemental ray fire failed for body\n");
- ACIS_API_error(rc, "Ray fire");
-
- // finish off params array with last hit on body
- ray_params.append(range - params_high[0]);
- if (entity_list) {
- topo_entity_ptr = ATTRIB_CUBIT_OWNER::get_topology_entity( entities_low[ilow] );
- geom_entity = CAST_TO( topo_entity_ptr, GeometryEntity );
- if (geom_entity) entity_list->append(geom_entity);
- }
- if (ray_params.size() % 2 == 1) {
- ray_params.last();
- ray_params.append(ray_params.get());
- if (entity_list) {
- entity_list->last();
- entity_list->append(entity_list->get());
- }
- }
- return CUBIT_FAILURE;
- }
- else if (!entities_low.count()) {
- PRINT_ERROR("Imbalanced rays in ray_fire!!!\n");
- entities_low.clear();
- entities_high.clear();
- entities_hit.clear();
- return CUBIT_FAILURE;
- }
-
- ilow = 0;
- range = range_orig - offset;
- }
- else {
- // try this - don't even bother firing another low ray (it'll
- // fail anyway) - just put the first high hit on the list and
- // make sure we have an even number of hits
- ray_params.append(range - params_high[0]);
- if (entity_list) {
- topo_entity_ptr = ATTRIB_CUBIT_OWNER::get_topology_entity( entities_low[ilow] );
- geom_entity = CAST_TO( topo_entity_ptr, GeometryEntity );
- if (geom_entity) entity_list->append(geom_entity);
- }
- if (ray_params.size() % 2 == 1) {
- ray_params.last();
- ray_params.append(ray_params.get());
- if (entity_list) {
- entity_list->last();
- entity_list->append(entity_list->get());
- }
- }
- if (entities_low.count() == 1 && entities_high.count() == 1)
- {
- entities_low.clear();
- entities_high.clear();
- entities_hit.clear();
- return CUBIT_SUCCESS;
- }
- else
- {
- entities_low.clear();
- entities_high.clear();
- entities_hit.clear();
- return CUBIT_FAILURE;
- }
- }
- }
- }
-
- if (ray_params.size()%2) {
- // number of hits odd - put another hit in list in case it's a
- // tangency hit; for num_hit > 1, need a point_in_body check
- SPAposition pos;
- int index = 0;
- pos_low -= offset * vector_low;
- int i;
-
- ray_params.reset();
- for (i = 1; i < ray_params.size(); i+=2) {
- point_containment pc;
- pos = pos_low + 0.5 * (ray_params.next(i-1) + ray_params.next(i)) * vector_low;
- rc = api_point_in_body (pos, body_ACIS, pc);
- if (!rc.ok()) {
- PRINT_ERROR("Point in body during ray fire failed for body \n");
- ACIS_API_error(rc, "Ray fire point in body");
- entities_low.clear();
- entities_high.clear();
- entities_hit.clear();
- return CUBIT_FAILURE;
- }
-
- if (pc == point_outside) index = i-1;
- }
-
- // index is the point that needs to be repeated; first bubble
- // the list, then replace
- ray_params.reset();
- ray_params.step(index);
- ray_params.insert(ray_params.get());
- if (entity_list) {
- entity_list->reset();
- entity_list->step(index);
- entity_list->insert(entity_list->get());
- }
- }
- entities_low.clear();
- entities_high.clear();
- entities_hit.clear();
- return CUBIT_SUCCESS;
+ ENTITY_ptr = acis_bridge_ptr->ENTITY_ptr();
+
+ at_ENTITY_list.append( ENTITY_ptr );
+ }
+
+ if( at_ENTITY_list.size() == 0 )
+ return CUBIT_FAILURE;
+
+ if( ray_radius == 0.0 )
+ ray_radius = SPAresabs;
+
+ DLIList<double> tmp_ray_params;
+ DLIList<ENTITY*> hit_ENTITY_list;
+
+ // Fire the ray at the ACIS entities
+ if( fire_ray( origin, direction, at_ENTITY_list, tmp_ray_params,
+ &hit_ENTITY_list, ray_radius, max_hits ) == CUBIT_FAILURE )
+ return CUBIT_FAILURE;
+
+ // Populate output
+ tmp_ray_params.reset();
+ hit_ENTITY_list.reset();
+ for( i=tmp_ray_params.size(); i--; )
+ {
+ ray_params.append( tmp_ray_params.get_and_step() );
+
+ if( hit_entity_list )
+ {
+ // Get TopologyBridge from ENTITY
+ ENTITY_ptr = hit_ENTITY_list.get_and_step();
+
+ AcisBridge *ab_ptr = ATTRIB_CUBIT_OWNER::cubit_owner(ENTITY_ptr);
+ TopologyBridge *tb_ptr = CAST_TO( ab_ptr, TopologyBridge );
+ hit_entity_list->append( tb_ptr );
+ }
+ }
+
+ return CUBIT_SUCCESS;
}
int AcisQueryEngine::get_major_version()
@@ -4614,18 +4609,23 @@
this_minor = 0;
valid = true;
}
- else if (major == 16 && this_minor >= 0 && this_minor <= 3) {
+
+ else if (major == 16 && this_minor >= 0 && this_minor <= 9) {
this_minor = 0;
valid = true;
}
- else if (major == 16 && this_minor >= 0 && this_minor <= 5) {
+ else if (major == 17 && this_minor >= 0 && this_minor <= 2) {
this_minor = 0;
valid = true;
}
- else if (major == 16 && this_minor >= 0 && this_minor <= 7) {
+ else if (major == 18 && this_minor >= 0 && this_minor <= 3) {
this_minor = 0;
valid = true;
}
+ else if (major == 19 && this_minor >= 0 && this_minor <= 2) {
+ this_minor = 0;
+ valid = true;
+ }
else {
PRINT_ERROR("Unrecognized Acis version number %d.%d.\n", major, this_minor);
return CUBIT_FAILURE;
@@ -5565,9 +5565,17 @@
SPAposition pt1=cur->eval_position( new_end );
// create the vertices
- VERTEX *svert= ACIS_NEW VERTEX( ACIS_NEW APOINT(pt0) );
- VERTEX *evert= ACIS_NEW VERTEX( ACIS_NEW APOINT(pt1) );
+ APOINT *apoint_0 = NULL;
+ APOINT *apoint_1 = NULL;
+ API_BEGIN;
+ apoint_0 = ACIS_NEW APOINT( pt0 );
+ apoint_1 = ACIS_NEW APOINT( pt1 );
+ API_END;
+
+ VERTEX *svert= ACIS_NEW VERTEX( apoint_0 );
+ VERTEX *evert= ACIS_NEW VERTEX( apoint_1 );
+
// create the curve
CURVE *the_curve=make_curve( *cur );
#ifdef BOYD16
@@ -5940,7 +5948,7 @@
ACIS_API_error( result, "transforming BODY" );
return CUBIT_FAILURE;
}
-
+
TRANSFORM* identity = new TRANSFORM( scale_transf(1.0) );
result = api_change_body_trans( BODY_ptr, identity, FALSE );
identity->lose();
@@ -6109,6 +6117,19 @@
api_terminate_warp();
#endif
+ //scaling will scale up gaps in the model, which can corrupt it.
+ //do a quick check here to warn the user that he might want to heal
+ //the model if it got corrupted due to the scale
+ insanity_list *list_of_problems = NULL;
+ BODY* BODY_ptr = get_BODY( body );
+ api_check_entity( (ENTITY*)BODY_ptr, list_of_problems );
+
+ if ( list_of_problems && list_of_problems->count() )
+ {
+ PRINT_WARNING("Model may be corrupted from the scaling opeartion.\n");
+ PRINT_INFO(" Consider healing it.\n");
+ }
+
return result;
}
@@ -6237,10 +6258,7 @@
remove_cubit_owner_attrib_in_BODY(acis_body_1);
remove_cubit_owner_attrib_in_BODY(acis_body_2);
- CubitBoolean bodies_overlap = CUBIT_FALSE;
-
-#if CUBIT_ACIS_VERSION < 1600
- bodies_overlap = CUBIT_TRUE;
+ CubitBoolean bodies_overlap = CUBIT_TRUE;
BOOL_TYPE bool_type = INTERSECTION;
outcome result = api_boolean(acis_body_1, acis_body_2, bool_type );
if (acis_body_2 == NULL ||
@@ -6249,26 +6267,6 @@
{
bodies_overlap = CUBIT_FALSE;
}
-#else
- bodies_overlap = CUBIT_FALSE;
- body_clash_result clash_result;
- outcome result = api_clash_bodies( acis_body_1, acis_body_2,
- clash_result, CLASH_CLASSIFY_BODIES );
- if (!result.ok())
- {
- PRINT_ERROR("Intersection operation failed.\n");
- AcisQueryEngine::instance()->ACIS_API_error(result, "intersect Bodies");
- return CUBIT_FALSE;
- }
-
- if( clash_result.clash_type() == CLASH_CONTAINED ||
- clash_result.clash_type() == CLASH_CONTAINED_ABUTS ||
- clash_result.clash_type() == CLASH_COINCIDENT ||
- clash_result.clash_type() == CLASH_INTERLOCK )
- {
- bodies_overlap = CUBIT_TRUE;
- }
-#endif
if ( acis_body_1 != NULL )
AcisQueryEngine::instance()->delete_ACIS_BODY(acis_body_1);
@@ -6298,48 +6296,21 @@
BODY *acis_body_1_orig = AcisQueryEngine::get_BODY(body_ptr_1);
BODY *acis_body_2_orig = AcisQueryEngine::get_BODY(body_ptr_2);
- CubitBoolean bodies_overlap = CUBIT_FALSE;
+ CubitBoolean bodies_overlap = CUBIT_TRUE;
-#if CUBIT_ACIS_VERSION < 1600
- BODY *acis_body_1, *acis_body_2;
- api_copy_body(acis_body_1_orig, acis_body_1);
- api_copy_body(acis_body_2_orig, acis_body_2);
+ API_NOP_BEGIN;
+ BOOL_TYPE bool_type = INTERSECTION;
+ remove_cubit_owner_attrib_in_BODY(acis_body_1_orig);
+ remove_cubit_owner_attrib_in_BODY(acis_body_2_orig);
+ outcome result = api_boolean(acis_body_1_orig, acis_body_2_orig, bool_type );
+ if (acis_body_2_orig == NULL ||
+ acis_body_2_orig->lump() == NULL && acis_body_2_orig->wire() == NULL ||
+ !result.ok())
+ {
+ bodies_overlap = CUBIT_FALSE;
+ }
+ API_NOP_END;
- //remove the attributes
- remove_cubit_owner_attrib_in_BODY(acis_body_1);
- remove_cubit_owner_attrib_in_BODY(acis_body_2);
-
- bodies_overlap = CUBIT_TRUE;
- BOOL_TYPE bool_type = INTERSECTION;
- outcome result = api_boolean(acis_body_1, acis_body_2, bool_type );
- if (acis_body_2 == NULL ||
- acis_body_2->lump() == NULL && acis_body_2->wire() == NULL ||
- !result.ok())
- {
- bodies_overlap = CUBIT_FALSE;
- }
- if ( acis_body_2 != NULL )
- AcisQueryEngine::instance()->delete_ACIS_BODY(acis_body_2);
-#else
- bodies_overlap = CUBIT_FALSE;
- body_clash_result clash_result;
- outcome result = api_clash_bodies( acis_body_1_orig, acis_body_2_orig,
- clash_result, CLASH_CLASSIFY_BODIES );
- if (!result.ok())
- {
- PRINT_ERROR("Intersection operation failed.\n");
- AcisQueryEngine::instance()->ACIS_API_error(result, "intersect Bodies");
- return CUBIT_FALSE;
- }
-
- if( clash_result.clash_type() == CLASH_CONTAINED ||
- clash_result.clash_type() == CLASH_CONTAINED_ABUTS ||
- clash_result.clash_type() == CLASH_COINCIDENT ||
- clash_result.clash_type() == CLASH_INTERLOCK )
- {
- bodies_overlap = CUBIT_TRUE;
- }
-#endif
return bodies_overlap;
}
@@ -6374,6 +6345,9 @@
listcat( entity_list, tmp_list );
tmp_list.clear();
result = api_restore_entity_list( file_ptr, ascii, tmp_list );
+ if (!result.ok())
+ ACIS_API_error(result);
+
} while (result.ok());
remove_refinements( entity_list );
@@ -6392,17 +6366,31 @@
PRINT_INFO( "Reading IGES file '%s'...\n", file_name );
- FILE *logfile_ptr = fopen( logfilename, "w" );
- if( logfile_ptr == NULL )
- {
- PRINT_ERROR( "unable to open iges logfile '%s'\n", logfilename );
- return CUBIT_FAILURE;
- }
+ SPAIFile log_file( logfilename );
- SPAXProgressReport_fct = progress_report_function;
AppUtil::instance()->progress_tool()->start(0, 100, "Importing IGES File:" );
- outcome result = api_xiges_read(entity_list, (char *)file_name, (char *)logfilename, heal);
+ SPAIOptions options;
+ SPAIValue my_false(FALSE);
+ options.Add( SPAIOptionName::Healing, my_false);
+ SPAIValue my_rep("BRep+Assembly");
+ options.Add( SPAIOptionName::Representation, my_rep);
+ options.Add( SPAIOptionName::TranslateFreeCurves, true);
+
+ SPAIDocument src( file_name );
+ SPAIAcisDocument dst;
+ SPAIConverter converter;
+ converter.SetOptions( options );
+ converter.SetProgressCallback( (SPAIProgressCallback)progress_report_function );
+ converter.StartLog(log_file);
+ SPAIResult result = converter.Convert(src, dst );
+ converter.StopLog(log_file);
+
+ ENTITY_LIST *tmp_entity_list = NULL;
+ dst.GetEntities( tmp_entity_list );
+ dst.DetachEntities();
+ entity_list.add( *tmp_entity_list );
+
//convert all bodies to 2d sheet bodies
ENTITY *tmp_ent;
entity_list.init();
@@ -6411,23 +6399,71 @@
if (is_BODY( tmp_ent ) )
api_body_to_2d( (BODY*)tmp_ent );
}
-
- fclose( logfile_ptr );
PRINT_INFO( "Done\n" );
- if( !result.ok() )
+ if( result.IsFailure() )
{
- ACIS_API_error( result );
- PRINT_ERROR( "problem reading from IGES file '%s'\n", file_name );
- return CUBIT_FAILURE;
+ //spatial categorized these TOO_BIG/SMALL errors as fatal. We're
+ //going ahead anyhow, simply telling the user to scale down the model
+ if( result.GetNumber() & SPAX_ACIS_E_BOX_TOO_BIG )
+ {
+ PRINT_WARNING("'%s'", result.GetMessage() );
+ PRINT_INFO("Your model is very large. Operations on your model could be \n"
+ "numerically unstable. Consider scaling your model down.\n" );
+ }
+ else if( result.GetNumber() & SPAX_ACIS_E_BOX_TOO_SMALL )
+ {
+ PRINT_WARNING("'%s'", result.GetMessage() );
+ PRINT_INFO("Your model is very small. Operations on your model could be \n"
+ "numerically unstable. Consider scaling your model up.\n");
+ }
+ else
+ {
+ PRINT_ERROR( "problem reading from IGES file '%s'\n", file_name );
+ PRINT_ERROR("'%s'", result.GetMessage() );
+ return CUBIT_FAILURE;
+ }
+ }
+
+ // fix for MiST - healer may not have worked if
+ //midsurfaces were not sheet bodies during IGES import
+ if (heal)
+ {
+ entity_list.init();
+ AppUtil::instance()->progress_tool()->start(0, entity_list.count(), "Healing Model:" );
+
+ while( (tmp_ent = entity_list.next()) != NULL)
+ {
+ if(is_BODY( tmp_ent ) )
+ {
+ outcome result;
+ result = api_hh_init_body_for_healing( (BODY*)tmp_ent );
+ if( !result.ok() )
+ {
+ ACIS_API_error( result );
+ //Don't bail out if you have trouble healing a body
+ }
+ result = api_hh_auto_heal( (BODY*)tmp_ent );
+ if( !result.ok() )
+ {
+ ACIS_API_error( result );
+ //Don't bail out if you have trouble healing a body
+ }
+ api_hh_end_body_for_healing( (BODY*)tmp_ent );
+ }
+ AppUtil::instance()->progress_tool()->step();
+ }
}
+
return CUBIT_SUCCESS;
}
#endif
#ifdef ACIS_CATIA_TRANSLATOR
-CubitStatus AcisQueryEngine::read_catia_file(const char* file_name, const char* logfile_name, ENTITY_LIST &entity_list)
+CubitStatus AcisQueryEngine::read_catia_file(const char* file_name,
+ const char* logfile_name,
+ ENTITY_LIST &entity_list)
{
char* logfilename = NULL;
if( !logfile_name || !strcmp( logfile_name, "" ) )
@@ -6467,11 +6503,6 @@
CubitStatus AcisQueryEngine::read_step_file(const char* file_name, const char* logfile_name,
ENTITY_LIST &entity_list, bool heal )
{
- if ( !stepInitialized ) {
- PRINT_ERROR("The STEP translater has not been properly initialized.\n");
- return CUBIT_FAILURE;
- }
-
char* logfilename = NULL;
if( !logfile_name || !strcmp( logfile_name, "" ) )
strcpy(logfilename, "step_import.log");
@@ -6479,38 +6510,85 @@
logfilename = (char *)logfile_name;
PRINT_INFO( "Reading STEP file '%s'...\n", file_name );
-
- SPAXProgressReport_fct = progress_report_function;
- api_xstep_set_option("step_to_acis_attrib_transf", TRUE);
+ SPAIFile logFile( logfilename );
+
AppUtil::instance()->progress_tool()->start(0, 100, "Importing STEP File:" );
- outcome result = api_xstep_read( entity_list, (char *)file_name, (char *)logfilename, heal );
- if( !result.ok() )
+ SPAIOptions options;
+ SPAIValue my_true(TRUE);
+ options.Add( SPAIOptionName::TranslateAttributes, my_true);
+
+ SPAIConverter converter;
+ converter.SetOptions( options );
+ converter.SetProgressCallback( (SPAIProgressCallback)progress_report_function );
+ converter.StartLog(logFile);
+
+ SPAIAcisDocument dst;
+ SPAIDocument src( file_name );
+ SPAIResult import_result = converter.Convert(src, dst );
+ converter.StopLog(logFile);
+
+ ENTITY_LIST *tmp_entity_list = NULL;
+ dst.GetEntities( tmp_entity_list );
+ dst.DetachEntities();
+ entity_list.add( *tmp_entity_list );
+
+ AppUtil::instance()->progress_tool()->end();
+
+ if( !import_result.IsSuccess() )
{
- if( result.error_number() == SPAX_ACIS_E_BOX_TOO_BIG )
+ //spatial categorized these TOO_BIG/SMALL errors as fatal. We're
+ //going ahead anyhow, simply telling the user to scale down the model
+ if( import_result.GetNumber() & SPAX_ACIS_E_BOX_TOO_BIG )
{
- const char* warning = find_err_ident(result.error_number());
- PRINT_WARNING("%s\n", find_err_mess( result.error_number() ) );
+ PRINT_WARNING("'%s'", import_result.GetMessage() );
PRINT_INFO("Your model is very large. Operations on your model could be \n"
- "numerically unstable. Consider scaling your model down.\n", warning);
+ "numerically unstable. Consider scaling your model down.\n" );
}
- else if( result.error_number() == SPAX_ACIS_E_BOX_TOO_SMALL )
+ else if( import_result.GetNumber() & SPAX_ACIS_E_BOX_TOO_SMALL )
{
- const char* warning = find_err_ident(result.error_number());
- PRINT_WARNING("%s\n", find_err_mess( result.error_number() ) );
+ PRINT_WARNING("'%s'", import_result.GetMessage() );
PRINT_INFO("Your model is very small. Operations on your model could be \n"
- "numerically unstable. Consider scaling your model up.\n", warning);
+ "numerically unstable. Consider scaling your model up.\n");
}
else
{
- ACIS_API_error( result );
PRINT_ERROR( "problem reading from STEP file '%s'\n", file_name );
- AppUtil::instance()->progress_tool()->end();
+ PRINT_ERROR("'%s'", import_result.GetMessage() );
return CUBIT_FAILURE;
}
+ }
+
+ ENTITY *tmp_ent;
+ if (heal)
+ {
+ entity_list.init();
+ AppUtil::instance()->progress_tool()->start(0, entity_list.count(), "Healing Model:" );
+
+ while( (tmp_ent = entity_list.next()) != NULL)
+ {
+ if(is_BODY( tmp_ent ) )
+ {
+ outcome result;
+ result = api_hh_init_body_for_healing( (BODY*)tmp_ent );
+ if( !result.ok() )
+ {
+ ACIS_API_error( result );
+ //Don't bail out if you have trouble healing a body
+ }
+ result = api_hh_auto_heal( (BODY*)tmp_ent );
+ if( !result.ok() )
+ {
+ ACIS_API_error( result );
+ //Don't bail out if you have trouble healing a body
+ }
+ api_hh_end_body_for_healing( (BODY*)tmp_ent );
+ }
+ AppUtil::instance()->progress_tool()->step();
+ }
}
- AppUtil::instance()->progress_tool()->end();
+
return CUBIT_SUCCESS;
}
@@ -6532,6 +6610,20 @@
new ATTRIB_SNL_SIMPLE( currItem, tmp_attrib );
delete tmp_attrib;
}
+ //read in other names
+ label_attrib = NULL;
+ api_find_named_attribute( currItem, "ATTRIB_XACIS_NAME",(ATTRIB_GEN_NAME*&)(label_attrib) );
+ if (label_attrib != NULL)
+ {
+ const char *part_name = label_attrib->value();
+ CubitString tmp_string( part_name );
+ if( tmp_string.find( "Next assembly relationship" ) != MAX_POS )
+ continue;
+
+ CubitSimpleAttrib *tmp_attrib = new CubitSimpleAttrib( "ENTITY_NAME", part_name );
+ new ATTRIB_SNL_SIMPLE( currItem, tmp_attrib );
+ delete tmp_attrib;
+ }
}
}
@@ -6599,3 +6691,103 @@
}
#endif
+CubitStatus
+AcisQueryEngine::fire_ray( CubitVector &origin,
+ CubitVector &direction,
+ DLIList<ENTITY*> &at_ENTITY_list,
+ DLIList<double> &ray_params,
+ DLIList<ENTITY*> *hit_ENTITY_list,
+ double ray_radius,
+ int hits_wanted ) const
+{
+ int i;
+
+ // Compute the ray parameters
+ SPAposition ray_origin( origin.x(), origin.y(), origin.z() );
+ SPAunit_vector ray_dir( direction.x(), direction.y(), direction.z() );
+
+ // Get targets
+ int num_targets = at_ENTITY_list.size();
+ ENTITY** targets = ACIS_NEW ENTITY*[ num_targets ];
+ at_ENTITY_list.reset();
+ for( i=0; i<num_targets; i++ )
+ targets[i] = at_ENTITY_list.get_and_step();
+
+ outcome result;
+ hit *hit_list = NULL;
+
+ //WORKAROUND
+ //ask for all hits b/c ACIS doesn't always return the closest hit if only ask for 1
+ // To remove this workaround, delete the following variable and call the api function
+ // with hits_wanted. The code at the end of this function which 'minds the number of hits wanted'
+ // can also be deleted.
+ int hits_wanted_bugfix = 0; //return all hits
+
+ result = api_raytest_ents( ray_origin, ray_dir, ray_radius, hits_wanted_bugfix,
+ num_targets, targets, hit_list );
+
+ ACIS_DELETE [] STD_CAST targets;
+
+ if( hit_list )
+ {
+ // Walk through the list of hits
+ hit *hit_ptr = hit_list;
+
+ ray_params.append( (double)hit_ptr->ray_param );
+ if( hit_ENTITY_list )
+ hit_ENTITY_list->append( hit_ptr->entity_hit );
+
+ while( (hit_ptr = hit_ptr->next) != NULL )
+ {
+ if( hit_ptr->type_of_hit == hit_thru )
+ {
+ ray_params.append( (double)hit_ptr->ray_param );
+ if( hit_ENTITY_list )
+ hit_ENTITY_list->append( hit_ptr->entity_hit );
+ }
+ }
+ //now cleanup
+ hit_ptr = hit_list;
+ while( hit_ptr->next != NULL )
+ {
+ hit *next_ptr = hit_ptr->next;
+ ACIS_DELETE hit_ptr;
+ hit_ptr = next_ptr;
+ }
+
+ //mind the number of hits wanted. Don't return more than that number
+ // Sort ray_params (low to high) and sort hit_ENTITY_list to match
+ // This will ensure entities are in order of who got hit first
+ // Do the sort by adding to a map (should auto-sort)
+
+ int hits_returned = 0;
+ std::map<double, ENTITY*> temp_map;
+ ray_params.reset();
+ if( hit_ENTITY_list) hit_ENTITY_list->reset();
+
+ for( i=0; i<ray_params.size(); i++ )
+ temp_map.insert(std::map<double, ENTITY*>::value_type( ray_params.get_and_step(),
+ hit_ENTITY_list ? hit_ENTITY_list->get_and_step() : 0 ) );
+
+ // The map should be sorted, so iterate through it and add to the official lists
+ ray_params.clean_out();
+ if( hit_ENTITY_list) hit_ENTITY_list->clean_out();
+
+ std::map<double, ENTITY*>::iterator iter;
+ for (iter=temp_map.begin(); iter != temp_map.end(); iter++)
+ {
+ if ( (hits_wanted == 0) || (hits_returned < hits_wanted) )
+ {
+ ray_params.append(iter->first);
+ if( hit_ENTITY_list) hit_ENTITY_list->append(iter->second);
+ hits_returned++;
+ }
+ else
+ break;
+ }
+ }
+
+ return CUBIT_SUCCESS;
+}
+
+
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisQueryEngine.hpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisQueryEngine.hpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisQueryEngine.hpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -131,6 +131,9 @@
friend class AcisModifyEngine;
friend class AcisHealerTool;
friend class AcisSurfaceTool;
+#ifdef ACIS_TWEAK
+ friend class AcisTweakToolCAT;
+#endif
friend class AcisTweakTool;
friend class AcisEdgeTool;
friend class AcisToolUtil;
@@ -161,7 +164,6 @@
const char * modeler_type()
{ return "ACIS"; }
-
//HEADER- RTTI and safe casting functions.
virtual const type_info& entity_type_info() const ;
@@ -289,17 +291,11 @@
//HEADER- Functions related to faceting
virtual CubitStatus get_graphics(Surface* surface_ptr,
- int& number_triangles,
- int& number_points,
- int& number_facets,
GMem* gMem,
unsigned short normal_tolerance,
double distance_tolerance,
double max_edge_length ) const;
CubitStatus get_graphics( FACE* face_ptr,
- int& number_triangles,
- int& number_points,
- int& number_facets,
GMem* gMem,
unsigned short normal_tolerance,
double distance_tolerance,
@@ -326,7 +322,6 @@
//- CUBIT_FAILURE is returned.
virtual CubitStatus get_graphics( Curve* curve_ptr,
- int& num_points,
GMem* gMem = NULL,
double tolerance = 0.0 ) const;
//R CubitStatus
@@ -422,13 +417,20 @@
//- Gets the minimum distance between two entities and the closest positions
//- on those entities. Supports vertices, curves, surfaces, volumes and bodies.
- virtual CubitStatus fire_ray( BodySM *body,
- const CubitVector &ray_point,
- const CubitVector &unit,
- DLIList<double>& ray_params,
- DLIList<GeometryEntity*> *entity_list) const;
- //- Fire a ray at the specified body, returning the entities hit and
- // the parameters along the ray; return non-zero if error
+ virtual CubitStatus fire_ray( CubitVector &origin,
+ CubitVector &direction,
+ DLIList<TopologyBridge*> &at_entity_list,
+ DLIList<double> &ray_params,
+ int max_hits = 0,
+ double ray_radius = 0.0,
+ DLIList<TopologyBridge*> *hit_entity_list=0 ) const;
+ //- Fire a ray at specified entities, returning the parameters (distances)
+ //- along the ray and optionally the entities hit. Returned lists are
+ //- appended to. Input entities can be any of bodies, volumes, faces,
+ //- edges or vertices (note TopologyEntity is used because a Body is not a
+ //- GeometryEntity). Optionally you can specify the maximum number of hits
+ //- to return (default = 0 = unlimited), and the ray radius to use for
+ //- intersecting the entities (default = 0.0 = use modeller default).
virtual CubitStatus transform_vec_position(
CubitVector const& position_vector,
@@ -560,10 +562,18 @@
#endif
//HEADER- Functions that create TopologyEntities
+ public: // KGM expose this for now
BodySM *populate_topology_bridges(BODY *body_ptr) const;
Lump *populate_topology_bridges(LUMP *lump_ptr) const;
Surface *populate_topology_bridges(FACE *face_ptr) const;
Curve *populate_topology_bridges(EDGE *edge_ptr) const;
+
+ ENTITY* get_ENTITY_of_entity( TopologyBridge *topobridge_ptr ) const;
+ //- Returns the ENTITY of the given TopologyBridge
+
+
+
+ private:
Point *populate_topology_bridges(VERTEX *vertex_ptr) const;
//- go through the entity passed in, make sure it has TopologyBridge
//- entities (or create them)
@@ -580,6 +590,9 @@
//- Given a list of RefEdges, return all the EDGEs
//HEADER- Functions that create ACIS ENTITYs
+ int save_ENTITYs_as_sat_file ( ENTITY_LIST *entity_list,
+ const char* filename,
+ const char* update_mode ) const;
int save_ENTITY_as_sat_file (ENTITY* entity_ptr,
const char* filename,
@@ -618,6 +631,7 @@
//- own unhooking.
//HEADER- Functions related to geometric comparison operations
+ CubitBoolean about_spatially_equal (EDGE* E1, EDGE* E2) const;
CubitBoolean about_spatially_equal ( const SPAposition &pos1,
const SPAposition &pos2,
@@ -685,13 +699,10 @@
//- Return the BODY that "owns" the VERTEX associated with the input
//- RefVertex.
- ENTITY* get_ENTITY_of_entity( TopologyBridge *ref_entity_ptr ) const;
- //- Returns the ENTITY of the given RefEntity
-
ENTITY* get_ENTITY_of_entity( BODY* BODY_ptr,
- TopologyBridge* topoentity_ptr) const;
+ TopologyBridge* topobridge_ptr) const;
//- Returns the ENTITY in the input BODY_ptr whose parent attribute
- //- corresponds to the input TopologyEntity pointer
+ //- corresponds to the input TopologyBridge pointer
//HEADER- Bounding box functions.
@@ -873,6 +884,26 @@
CubitStatus remove_refinements( ENTITY_LIST& list );
//- Clear any refinements set on objects in .SAT file after
//- import.
+
+ CubitStatus fire_ray( CubitVector &origin,
+ CubitVector &direction,
+ DLIList<ENTITY*> &at_ENTITY_list,
+ DLIList<double> &ray_params,
+ DLIList<ENTITY*> *hit_ENTITY_list,
+ double ray_radius,
+ int hits_wanted) const;
+ //- Fire a ray at specified entities from the given ray origin in the given
+ //- ray direction, returning the parameters (distances) along the ray and
+ //- optionally the entities hit. Only entities in the forward direction
+ //- along the ray can be hit. Returned lists are appended to. The radius
+ //- of the ray can optionally be specified. The number of hits can be
+ //- limited by supplying hits_wanted (0 means return all hits). Note the
+ //- returned number of ray_params will always equal the number of returned
+ //- ENTITIES hit.
+ //- NOTE: returned entities hit might be "hidden" beneath virtual entities.
+ //- To resolve to visible entities, use "get_visible_ents_for_hits"
+ //- in GeometryQueryTool.
+
static const int MAX_NUM_CURVE_POINTS;
static const int AQE_SUBMINOR_VERSION;
@@ -880,8 +911,6 @@
static double *curveParams;
AcisFacetManager* facetManager;
- bool stepInitialized;
-
int exportVersion;
};
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisSurfaceTool.cpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisSurfaceTool.cpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisSurfaceTool.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -6,51 +6,6 @@
//- Version: $Id:
// ********** BEGIN ACIS INCLUDES **********
-#if CUBIT_ACIS_VERSION < 1100
-#include "kernel/acis.hxx"
-#include "kernel/kernapi/api/api.hxx"
-#include "kernel/kernapi/api/kernapi.hxx"
-#include "kernel/kerndata/geom/transfrm.hxx"
-#include "kernel/kerndata/top/edge.hxx"
-#include "kernel/kerndata/top/loop.hxx"
-#include "kernel/kerndata/top/coedge.hxx"
-#include "kernel/kerndata/top/face.hxx"
-#include "kernel/kerndata/top/wire.hxx"
-#include "kernel/kerndata/top/body.hxx"
-#include "kernel/kerndata/lists/lists.hxx"
-#include "kernel/kernutil/law/law.hxx"
-#include "kernel/spline/api/spl_api.hxx"
-#include "intersct/kernapi/api/intrapi.hxx"
-#include "constrct/kernapi/api/cstrapi.hxx"
-#include "skin/kernapi/api/skinapi.hxx"
-#include "skin/sg_husk/skin/skin.hxx"
-#include "offset/kernapi/api/ofstapi.hxx"
-#include "cover/kernapi/api/coverapi.hxx"
-#include "kernel/geomhusk/bnd_crv.hxx"
-#include "kernel/geomhusk/getowner.hxx"
-#include "baseutil/vector/interval.hxx"
-#include "intersct/kerngeom/curve/curextnd.hxx"
-#include "kernel/kerngeom/curve/extend.hxx"
-#include "kernel/kerngeom/curve/curdef.hxx"
-#include "kernel/kerndata/geom/curve.hxx"
-#include "kernel/kerndata/geom/point.hxx"
-#include "kernel/kerndata/geom/surface.hxx"
-#include "kernel/kerndata/top/shell.hxx"
-#include "kernel/kerndata/top/lump.hxx"
-#include "kernel/kerndata/top/vertex.hxx"
-#include "kernel/kerndata/geom/cnstruct.hxx"
-
-#include "baseutil/vector/position.hxx"
-#include "baseutil/vector/unitvec.hxx"
-#include "baseutil/logical.h"
-
-#ifdef ACIS_LOCAL_OPS
-#include "lop_husk/api/lop_api.hxx"
-#endif
-#include "boolean/kernapi/api/boolapi.hxx"
-#include "kernel/geomhusk/copyent.hxx" // copy single entity
-
-#else
#include "acis.hxx"
#include "api.hxx"
#include "kernapi.hxx"
@@ -86,15 +41,13 @@
#include "position.hxx"
#include "unitvec.hxx"
#include "logical.h"
+#include "boolapi.hxx"
+#include "copyent.hxx" // copy single entity
#ifdef ACIS_LOCAL_OPS
#include "lop_api.hxx"
#endif
-#include "boolapi.hxx"
-#include "copyent.hxx" // copy single entity
-#endif
-
// ********** END ACIS INCLUDES **********
// ********** BEGIN CUBIT INCLUDES **********
@@ -108,6 +61,7 @@
#include "GeometryQueryTool.hpp"
#include "Body.hpp"
#include "BodyACIS.hpp"
+#include "PointACIS.hpp"
#include "CurveACIS.hpp"
#include "SurfaceACIS.hpp"
@@ -121,6 +75,7 @@
// For multiple surfaces
#include "Loop.hpp"
+#include "Point.hpp"
#include "RefVertex.hpp"
#include "CoEdge.hpp"
@@ -739,7 +694,8 @@
CubitStatus
AcisSurfaceTool::create_skin_surface( DLIList<Curve*>& curves,
- BodySM*& new_body )
+ BodySM*& new_body,
+ DLIList<Curve*>& guides)
{
new_body = NULL;
int i;
@@ -756,6 +712,9 @@
// Create the wires from the edges
BODY** wires = new BODY*[curves.size()];
+ EDGE** edge_guides = NULL;
+ if (guides.size())
+ edge_guides = new EDGE*[guides.size()];
Curve* curve_ptr;
EDGE* EDGE_ptr;
@@ -814,6 +773,31 @@
num_wires++;
}
+ int num_guides = 0;
+ guides.reset();
+ for (i = 0; i < guides.size(); i++)
+ {
+ curve_ptr = guides.get_and_step();
+ CurveACIS* acis_curve_ptr = dynamic_cast<CurveACIS*>(curve_ptr);
+
+ // Get the EDGE ptr from the RefEdge
+ if( !acis_curve_ptr || !(EDGE_ptr = acis_curve_ptr->get_EDGE_ptr()) )
+ {
+ PRINT_ERROR( "Curve guide is not an ACIS curve\n" );
+ for( i=0; i<num_wires; i++ )
+ api_delent( wires[i] );
+ for( i=0; i<num_guides; i++)
+ api_delent( edge_guides[i] );
+ delete [] wires;
+ delete [] edge_guides;
+ return CUBIT_FAILURE;
+ }
+
+ result = api_edge( EDGE_ptr, copied_EDGE_ptr );
+ edge_guides[i] = copied_EDGE_ptr;
+ num_guides++;
+ }
+
BODY *skin_body = NULL;
PRINT_INFO( "Creating skin surface...\n" );
@@ -825,13 +809,19 @@
tmp_skin_options.set_solid(1);
}
- result = api_skin_wires( num_wires, wires, skin_body, &tmp_skin_options );
+ if (num_guides == 0)
+ result = api_skin_wires( num_wires, wires, skin_body, &tmp_skin_options );
+ else
+ result = api_skin_wires( num_wires, wires, num_guides, edge_guides, skin_body, &tmp_skin_options );
// Cleanup memory
for( i=0; i<num_wires; i++ )
api_delent( wires[i] );
delete [] wires;
-
+ for( i=0; i<num_guides; i++)
+ api_delent( edge_guides[i] );
+ delete [] edge_guides;
+
if( !result.ok() )
{
AcisQueryEngine::instance()->ACIS_API_error(result);
@@ -1311,6 +1301,152 @@
return CUBIT_SUCCESS;
}
+CubitStatus
+AcisSurfaceTool::create_surface( DLIList<Point*>& points,
+ BodySM *&new_body )
+{
+ int i, j;
+ outcome result;
+
+ // Create curves connecting the points
+ DLIList<EDGE*> EDGE_list;
+ EDGE *EDGE_ptr;
+
+ points.reset();
+ Point *start_point = points.get_and_step();
+ PointACIS* acis_s_point = CAST_TO(const_cast<Point*>(start_point), PointACIS) ;
+ VERTEX *start_vert = acis_s_point->get_VERTEX_ptr();
+
+ CubitVector coord1 = start_point->coordinates();
+ SPAposition start( coord1.x(), coord1.y(), coord1.z() );
+ SPAposition end;
+ for( i=0; i<points.size(); i++ )
+ {
+ Point *end_point = points.get_and_step();
+ CubitVector coord2 = end_point->coordinates();
+ end.set_x( coord2.x() );
+ end.set_y( coord2.y() );
+ end.set_z( coord2.z() );
+
+ if( coord1.within_tolerance( coord2, GEOMETRY_RESABS ) )
+ {
+ PRINT_ERROR( "Attempt to create a line between coincident points at (%f, %f, %f)\n",
+ start.x(), start.y(), start.z() );
+ for( j=0; j<EDGE_list.size(); j++ )
+ {
+ EDGE_ptr = EDGE_list.get_and_step();
+ api_delent( EDGE_ptr );
+ }
+ return CUBIT_FAILURE;
+ }
+
+ PointACIS* acis_e_point = CAST_TO(const_cast<Point*>(end_point), PointACIS) ;
+ VERTEX *end_vert = acis_e_point->get_VERTEX_ptr();
+
+
+ STRAIGHT *tmp_straight;
+ API_BEGIN;
+ tmp_straight = new STRAIGHT( start, normalise( end - start ) );
+ API_END;
+
+ EDGE *tmp_edge = new EDGE( start_vert, end_vert, tmp_straight, FORWARD );
+
+ EDGE_list.append( tmp_edge );
+ start_vert = end_vert;
+ start = end;
+ coord1 = coord2;
+ }
+
+ // Make a WIRE from the EDGES
+ int edge_count = points.size();
+ EDGE** EDGEs = new EDGE* [edge_count];
+ EDGE_list.reset();
+ for( i=0; i<edge_count; i++ )
+ EDGEs[i] = EDGE_list.get_and_step();
+
+ BODY* wire_BODY = NULL;
+ result = api_make_ewire(edge_count, EDGEs, wire_BODY) ;
+ delete [] EDGEs;
+ if ( !result.ok() || wire_BODY == NULL )
+ {
+ AcisQueryEngine::instance()->ACIS_API_error( result );
+ if (wire_BODY)
+ api_delent(wire_BODY);
+ else
+ {
+ for( j=0; j<EDGE_list.size(); j++ )
+ {
+ EDGE_ptr = EDGE_list.get_and_step();
+ api_delent( EDGE_ptr );
+ }
+ }
+ return CUBIT_FAILURE;
+ }
+
+ // Check to make sure the wire is closed
+ result = api_closed_wire( wire_BODY );
+ if( !result.ok() )
+ {
+ AcisQueryEngine::instance()->ACIS_API_error( result );
+ PRINT_ERROR( "ACIS reports that a closed loop was not found\n" );
+ api_delent( wire_BODY ); // This deletes the underlying EDGEs
+ return CUBIT_FAILURE;
+ }
+
+ // Use the WIRE to make a FACE.
+ // Note that the call to api_cover_wires creates not
+ // only the FACE but the entire topological data
+ // structure above FACE (till BODY).
+ ENTITY_LIST acis_FACE_list;
+ result = api_cover_wires ( wire_BODY,
+ *(surface*)NULL_REF,
+ acis_FACE_list );
+
+ if ( !result.ok() || acis_FACE_list.count() == 0 )
+ {
+ AcisQueryEngine::instance()->ACIS_API_error( result );
+ wire_BODY->lose();
+ for (int i=0; i<edge_count; i++)
+ EDGE_list.get_and_step()->lose();
+ return CUBIT_FAILURE;
+ }
+
+ if (acis_FACE_list.count() != 1)
+ {
+ PRINT_ERROR("ACIS api_cover_wires function created more than one FACE.\n"
+ " At this time, we cannot deal with this.\n");
+ wire_BODY->lose();
+ for (int i=0; i<edge_count; i++)
+ EDGE_list.get_and_step()->lose();
+ return CUBIT_FAILURE;
+ }
+
+ //make this a 2d body.
+ result = api_body_to_2d( wire_BODY );
+ if ( !result.ok() )
+ {
+ AcisQueryEngine::instance()->ACIS_API_error( result );
+ PRINT_ERROR("ACIS api_body_to_2d function failed.\n");
+ wire_BODY->lose();
+ for (int i=0; i<edge_count; i++)
+ EDGE_list.get_and_step()->lose();
+ return CUBIT_FAILURE;
+ }
+ FACE *FACE_ptr = (FACE*) acis_FACE_list.next();
+ if ( FACE_ptr == NULL || FACE_ptr->geometry() == NULL )
+ {
+ PRINT_ERROR("a surface could not be constructed from the resultant polygon.\n");
+ wire_BODY->lose();
+ for (int i=0; i<edge_count; i++)
+ EDGE_list.get_and_step()->lose();
+ return CUBIT_FAILURE;
+ }
+
+ Surface *new_surface_ptr = AcisQueryEngine::instance()->populate_topology_bridges( FACE_ptr );
+ new_body = AcisModifyEngine::instance()->make_BodySM( new_surface_ptr );
+
+ return CUBIT_SUCCESS;
+}
static SPAtransf const &get_edge_trans(EDGE *edge)
{
// Find the body
@@ -1642,6 +1778,12 @@
PRINT_ERROR("Invalid ACIS Surface -- aborting.\n");
return CUBIT_FAILURE;
}
+
+ if(!FACE_ptr1->loop() || !FACE_ptr2->loop())
+ {
+ PRINT_ERROR("Surfaces must have at least one loop for lofting -- aborting.\n");
+ return CUBIT_FAILURE;
+ }
api_copy_entity_contents( (ENTITY *)FACE_ptr1, ENTITY_ptr);
FACE_ptr1 = (FACE *)ENTITY_ptr;
@@ -1662,15 +1804,15 @@
//CubitBoolean solid = perpendicular;
result = api_loft_faces(FACE_ptr1,
- takeoff1,
- FACE_ptr2,
- takeoff2,
- loft_body,
- arc_length_option,
- twist_option,
- align_direction,
- perpendicular,
- simplify_option);
+ takeoff1,
+ FACE_ptr2,
+ takeoff2,
+ loft_body,
+ arc_length_option,
+ twist_option,
+ align_direction,
+ perpendicular,
+ simplify_option);
if( !result.ok() )
{
@@ -1855,14 +1997,17 @@
CubitStatus
AcisSurfaceTool::create_skin_surface( DLIList<RefEdge*>& ref_edge_list,
- Body*& new_body )
+ Body*& new_body,
+ DLIList<RefEdge*>& guide_list)
{
CubitStatus result;
BodySM* this_bodysm;
DLIList<Curve*> curve_list(ref_edge_list.size());
+ DLIList<Curve*> guide_curve_list(guide_list.size());
new_body = 0;
+ // get ACIS curves from ref_edge_list
ref_edge_list.reset();
for (int i = ref_edge_list.size(); i--; )
{
@@ -1877,8 +2022,22 @@
if (curve_list.size() != ref_edge_list.size())
return CUBIT_FAILURE;
+ // get ACIS curves from guide_list
+ guide_list.reset();
+ for (int i = guide_list.size(); i--; )
+ {
+ RefEdge* edge = guide_list.get_and_step();
+ CurveACIS* curve = get_acis_curve(edge);
+ if (!curve)
+ PRINT_ERROR("Curve %d is not an ACIS Curve.\n", edge->id());
+ else
+ guide_curve_list.append(curve);
+ }
+ if (guide_curve_list.size() != guide_list.size())
+ return CUBIT_FAILURE;
- result = create_skin_surface( curve_list, this_bodysm );
+
+ result = create_skin_surface( curve_list, this_bodysm, guide_curve_list );
if (!result)
return result;
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisSurfaceTool.hpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisSurfaceTool.hpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisSurfaceTool.hpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -10,6 +10,7 @@
class EDGE;
template <class X> class DLIList;
+class Point;
class Curve;
class Surface;
class BodySM;
@@ -87,8 +88,10 @@
double offset_distance );
//- Creates a new body by offsetting from another body
- CubitStatus create_skin_surface( DLIList<Curve*>& curves, BodySM*& new_body );
- CubitStatus create_skin_surface( DLIList<RefEdge*>& curves, Body*& new_body );
+ CubitStatus create_skin_surface( DLIList<Curve*>& curves, BodySM*& new_body,
+ DLIList<Curve*>& guides);
+ CubitStatus create_skin_surface( DLIList<RefEdge*>& curves, Body*& new_body,
+ DLIList<RefEdge*>& guides);
//- Skinning puts a surface through a set of curves that are somewhat
//- parallel to each other.
@@ -132,11 +135,15 @@
CubitStatus create_surface( DLIList<CubitVector*>& vec_list,
BodySM *&new_body,
Surface *surface_ptr,
- CubitBoolean project_points );
+ CubitBoolean project_points );
+
+ CubitStatus create_surface( DLIList<Point*> &vec_list,
+ BodySM *&new_body );
+
CubitStatus create_surface( DLIList<CubitVector*>& vec_list,
Body *&new_body,
RefFace *ref_face_ptr,
- CubitBoolean project_points );
+ CubitBoolean project_points );
//- Creates a surface out of a list of points. The points must form
//- a polygon (there must be at least 3 points), but do not need to be
//- absolutely planar. The resultant surface will have one loop with
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisToolUtil.cpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisToolUtil.cpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisToolUtil.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -14,7 +14,9 @@
#include "DLIList.hpp"
+#include "CubitUtil.hpp"
#include "AcisToolUtil.hpp"
+#include "AcisToolUtil.hpp"
#include "AcisQueryEngine.hpp"
#include "AcisModifyEngine.hpp"
#include "GeometryQueryTool.hpp"
@@ -23,11 +25,17 @@
#include "Body.hpp"
#include "RefFace.hpp"
#include "RefEdge.hpp"
+#include "RefVertex.hpp"
+#include "CoEdge.hpp"
+#include "Loop.hpp"
+#include "Shell.hpp"
+
#include "BodyACIS.hpp"
#include "SurfaceACIS.hpp"
#include "CurveACIS.hpp"
#include "attrib_cubit_owner.hpp"
+#include "err_ent.hxx"
Body* AcisToolUtil::get_new_Body( Body* old_body, BODY* old_BODY,
BODY* new_BODY, bool keep_old,
@@ -197,5 +205,182 @@
return dynamic_cast<Body*>(ent_ptr);
}
+void AcisToolUtil::convert_entity_list( insanity_list *ent_list,
+ DLIList<TopologyEntity*> &topo_entity_list)
+{
+ if( ent_list->count() )
+ {
+ insanity_list *tmp_list = ent_list;
+ for(; tmp_list; tmp_list = tmp_list->next() )
+ {
+ insanity_data *error_data = tmp_list->data();
+ ENTITY *bad_ent = error_data->get_ent();
+ ENTITY_LIST bad_ents;
+ if(bad_ent->identity() == ERROR_ENTITY_TYPE )
+ {
+ ERROR_ENTITY *error_ent = (ERROR_ENTITY*)bad_ent;
+ bad_ents.add( error_ent->get_owner(0) );
+ bad_ents.add( error_ent->get_owner(1) );
+ }
+ else
+ bad_ents.add( bad_ent );
+
+ bad_ents.init();
+ PRINT_INFO("%s: ", error_data->get_message() );
+ while( (bad_ent = bad_ents.next()) != NULL )
+ {
+ TopologyEntity* te_ptr = NULL;
+ te_ptr = ATTRIB_CUBIT_OWNER::get_topology_entity( bad_ent );
+ if( te_ptr )
+ {
+ RefEntity *ref_ent = CAST_TO( te_ptr, RefEntity );
+ topo_entity_list.append_unique(te_ptr);
+ if( ref_ent )
+ PRINT_INFO(" %s %d", ref_ent->class_name(), ref_ent->id() );
+ }
+ else
+ PRINT_INFO("%s",bad_ent->type_name() );
+ }
+ PRINT_INFO("\n");
+ }
+ }
+}
+
+CubitStatus AcisToolUtil::show_bad_geom(DLIList <TopologyEntity*> &ent_list,
+ const CubitString &user_name)
+{
+ DLIList<RefVertex*> vertex_list;
+ DLIList<RefEdge*> edge_list;
+ DLIList<RefEdge*> curve_coedge_list;
+ DLIList<CoEdge*> coedge_list;
+ DLIList<Loop*> loop_list;
+ DLIList<RefFace*> face_list;
+ DLIList<Shell*> shell_list;
+ DLIList<RefVolume*> volume_list;
+ int i;
+
+ // We need an encapsulated class to handle this sort of thing...
+ for (i=0;i<ent_list.size();i++)
+ {
+ TopologyEntity* TE_ptr = ent_list.get_and_step();
+ RefVertex* ref_vertex;
+ RefEdge* ref_edge;
+ CoEdge* co_edge;
+ Loop* loop;
+ RefFace* face;
+ Shell* shell;
+ RefVolume* volume;
+
+ if( (ref_vertex = CAST_TO( TE_ptr, RefVertex ) ) != NULL )
+ vertex_list.append_unique(ref_vertex);
+ else if( (ref_edge = CAST_TO( TE_ptr, RefEdge ) ) != NULL )
+ edge_list.append_unique(ref_edge);
+ else if( (co_edge = CAST_TO( TE_ptr, CoEdge ) ) != NULL )
+ coedge_list.append_unique(co_edge);
+ else if( (loop = CAST_TO( TE_ptr, Loop ) ) != NULL )
+ loop_list.append_unique(loop);
+ else if( (face = CAST_TO( TE_ptr, RefFace ) ) != NULL )
+ face_list.append_unique(face);
+ else if( (shell = CAST_TO( TE_ptr, Shell ) ) != NULL )
+ shell_list.append_unique(shell);
+ else if( (volume = CAST_TO( TE_ptr, RefVolume ) ) != NULL )
+ volume_list.append_unique(volume);
+ }
+
+ char *pre = new char[user_name.length()+100];
+
+ if( vertex_list.size() )
+ {
+ sprintf( pre, "Found %d bad vertices in %s. The vertices: ", vertex_list.size(),
+ user_name.c_str() );
+ DLIList<CubitEntity*> cubit_list;
+ CAST_LIST( vertex_list, cubit_list, CubitEntity );
+ CubitUtil::list_entity_ids( pre, cubit_list );
+ }
+
+ if( edge_list.size() )
+ {
+ sprintf( pre, "Found %d bad curves in %s. The curves: ", edge_list.size(),
+ user_name.c_str() );
+ DLIList<CubitEntity*> cubit_list;
+ CAST_LIST( edge_list, cubit_list, CubitEntity );
+ CubitUtil::list_entity_ids( pre, cubit_list );
+ }
+
+ for( i=0; i<coedge_list.size(); i++ )
+ {
+ RefEdge* ref_edge_ptr = coedge_list.get_and_step()->get_ref_edge_ptr();
+ curve_coedge_list.append_unique( ref_edge_ptr );
+ }
+ if( coedge_list.size() )
+ {
+ sprintf( pre, "Found %d bad coedges in %s. The curves: ", coedge_list.size(),
+ user_name.c_str() );
+ DLIList<CubitEntity*> cubit_list;
+ CAST_LIST( curve_coedge_list, cubit_list, CubitEntity );
+ CubitUtil::list_entity_ids( pre, cubit_list );
+ }
+
+ // LOOPS
+ Loop* loop_ptr;
+ DLIList<RefEdge*> curve_loop_list;
+ for( i=0; i<curve_loop_list.size(); i++ )
+ {
+ loop_ptr = loop_list.get_and_step();
+ DLIList<RefEdge*> tmp_curve_list;
+ loop_ptr->ordered_ref_edges( tmp_curve_list );
+ curve_loop_list.merge_unique( tmp_curve_list );
+ }
+ curve_loop_list.reset();
+ if( curve_loop_list.size() )
+ {
+ sprintf( pre, "Found %d bad loops in %s. The curves: ", loop_list.size(), user_name.c_str() );
+ DLIList<CubitEntity*> cubit_list;
+ CAST_LIST( curve_loop_list, cubit_list, CubitEntity );
+ CubitUtil::list_entity_ids( pre, cubit_list );
+ }
+
+ // SURFACES
+ if( face_list.size() )
+ {
+ sprintf( pre, "Found %d bad surfaces in %s. The surfaces: ", face_list.size(), user_name.c_str() );
+ DLIList<CubitEntity*> cubit_list;
+ CAST_LIST( face_list, cubit_list, CubitEntity );
+ CubitUtil::list_entity_ids( pre, cubit_list );
+ }
+
+ // SHELLS
+ Shell* shell_ptr;
+ DLIList<RefFace*> face_shell_list;
+ for( i=0; i<shell_list.size(); i++ )
+ {
+ shell_ptr = shell_list.get_and_step();
+ DLIList<RefFace*> tmp_surface_list;
+ shell_ptr->ref_faces( tmp_surface_list );
+ face_shell_list.merge_unique( tmp_surface_list );
+ }
+ if( face_shell_list.size() )
+ {
+ sprintf( pre, "Found %d bad shells in %s. The surfaces: ", shell_list.size(), user_name.c_str() );
+ DLIList<CubitEntity*> cubit_list;
+ CAST_LIST( face_shell_list, cubit_list, CubitEntity );
+ CubitUtil::list_entity_ids( pre, cubit_list );
+ }
+
+ // LUMPS
+ if( volume_list.size() )
+ {
+ sprintf( pre, "Found %d bad volumes in %s. The volumes: ", volume_list.size(), user_name.c_str() );
+ DLIList<CubitEntity*> cubit_list;
+ CAST_LIST( volume_list, cubit_list, CubitEntity );
+ CubitUtil::list_entity_ids( pre, cubit_list );
+ }
+
+ delete [] pre;
+
+ return CUBIT_SUCCESS;
+}
+
+
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisToolUtil.hpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisToolUtil.hpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisToolUtil.hpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -18,11 +18,14 @@
#include "CubitDefines.h" /* for CubitStatus */
+#include "insanity_list.hxx"
+
template <class X> class DLIList;
class Body;
class RefEdge;
class RefFace;
+class TopologyEntity;
class ENTITY;
class BODY;
@@ -71,6 +74,15 @@
static Body* get_body_of_ENTITY(ENTITY*);
+ static void convert_entity_list( insanity_list *ent_list,
+ DLIList<TopologyEntity*> &topology_entities);
+ // Given the acis entities, gets the corrisponding topology entities in
+ // cubit by which they are represented.
+
+ static CubitStatus show_bad_geom( DLIList<TopologyEntity*> &ent_list,
+ const CubitString &user_name);
+ // This was put in only to display bad geometry from a validate. Needs to
+ // be encapsulated in another class...
};
#endif
Copied: cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisTopologyTool.cpp (from rev 3491, cgm/branches/cubit/geom/ACIS_SRC/AcisTopologyTool.cpp)
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisTopologyTool.cpp (rev 0)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisTopologyTool.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -0,0 +1,4330 @@
+//- Class: AcisTopologyTool
+//- File: AcisTopologyTool.cpp
+//- Type: class implemention
+//- Owner: Brett Clark
+
+// Include files
+
+#include "AcisTopologyTool.hpp"
+#include "CubitVector.hpp"
+#include "CubitPlane.hpp"
+#include "AcisDrawTool.hpp"
+#include "GeometryDefines.h"
+#include "AcisModifyEngine.hpp"
+#include "AcisHealerTool.hpp"
+#include "GeomMeasureTool.hpp"
+#include "attrib_cubit_owner.hpp"
+#include "attrib_snl_simple.hpp"
+#include "CubitString.hpp"
+#include "CubitSimpleAttrib.hpp"
+#include "TopologyBridge.hpp"
+#include "GfxDebug.hpp"
+
+#include "vertex.hxx"
+#include "point.hxx"
+#include "vector.hxx"
+#include "edge.hxx"
+#include "face.hxx"
+#include "lists.hxx"
+#include "unitvec.hxx"
+#include "surface.hxx"
+#include "surdef.hxx"
+#include "curve.hxx"
+#include "curdef.hxx"
+#include "strdef.hxx"
+#include "straight.hxx"
+#include "param.hxx"
+#include "position.hxx"
+#include "interval.hxx"
+#include "cstrapi.hxx"
+#include "esplit.hxx"
+#include "coedge.hxx"
+#include "intrapi.hxx"
+#include "pladef.hxx"
+#include "acistype.hxx"
+#include "body.hxx"
+#include "lump.hxx"
+#include "shell.hxx"
+#include "eulerapi.hxx"
+#include "stchapi.hxx"
+#include "boolapi.hxx"
+#include "err_ent.hxx"
+
+static double pi_over_two = CUBIT_PI/2.0;
+static double pi_over_four = pi_over_two/2.0;
+static double three_pi_over_two = 3.0*pi_over_two;
+static double three_pi_over_four = three_pi_over_two/2.0;
+static double five_pi_over_four = 5.0*pi_over_four;
+static double seven_pi_over_four = 7.0*pi_over_four;
+
+void f(RefFace* face, int color);
+void e(RefEdge* edge, int color);
+void v(RefVertex* vert, int color);
+void p(CubitVector* v, int color);
+void en(ENTITY* ent, int color);
+void pos(SPAposition* p, int color);
+
+void F(FACE* face, int color)
+{
+ AcisDrawTool::instance()->draw_FACE(face, color, CUBIT_FALSE, CUBIT_TRUE);
+ ENTITY_LIST verts;
+ api_get_vertices((ENTITY*)face, verts);
+ verts.init();
+ ENTITY *tmp_ent;
+ while((tmp_ent = verts.next()))
+ AcisDrawTool::instance()->draw_VERTEX((VERTEX*)tmp_ent, color, CUBIT_TRUE);
+}
+
+void E(EDGE* edge, int color)
+{
+ AcisDrawTool::instance()->draw_EDGE(edge, color, CUBIT_TRUE);
+ ENTITY_LIST verts;
+ api_get_vertices((ENTITY*)edge, verts);
+ verts.init();
+ ENTITY *tmp_ent;
+ while((tmp_ent = verts.next()))
+ AcisDrawTool::instance()->draw_VERTEX((VERTEX*)tmp_ent, color, CUBIT_TRUE);
+}
+
+void V(VERTEX* vert, int color)
+{
+ AcisDrawTool::instance()->draw_VERTEX(vert, color, CUBIT_TRUE);
+}
+
+void En(ENTITY* e, int color)
+{
+ AcisDrawTool::instance()->draw_ENTITY(e, color, CUBIT_FALSE, CUBIT_TRUE);
+ ENTITY_LIST verts;
+ api_get_vertices(e, verts);
+ verts.init();
+ ENTITY *tmp_ent;
+ while((tmp_ent = verts.next()))
+ AcisDrawTool::instance()->draw_VERTEX((VERTEX*)tmp_ent, color, CUBIT_TRUE);
+}
+
+void Clear()
+{
+ GfxDebug::clear();
+ GfxDebug::flush();
+}
+
+CubitStatus AcisTopologyTool::remove_topology(BODY *&body,
+ DLIList<EDGE*> &edges_to_remove,
+ DLIList<FACE*> &faces_to_remove,
+ double backoff_distance,
+ double small_edge_size)
+{
+ double tol_sq = GEOMETRY_RESABS*GEOMETRY_RESABS;
+ int i;
+ CubitStatus status = CUBIT_SUCCESS;
+ DLIList<VERTEXClump*> clumps;
+ DLIList<VERTEX*> all_verts_in_clumps;
+ DLIList<FACE*> faces_that_might_move, new_vol_faces, modified_faces;
+ DLIList<SPAposition> clump_positions, split_positions, projected_positions;
+ std::map <VERTEX*, VERTEXClump*, mapltid> old_vertex_to_clump_map;
+ std::map <VERTEXClump*, DLIList<FACE*>*, mapltclump> surrounding_faces_map;
+ std::map <FACE*, int, mapltid> face_clump_count_map;
+ std::map <VERTEXClump*, DLIList<FACE*>*, mapltclump> faces_that_dont_intersect_map;
+ std::map <EDGE*, EDGE*, mapltid> old_edge_to_new_edge_map;
+
+ // Put an attribute on all of the ACIS curves and verts to
+ // track what has been destroyed during the operation. Entities
+ // that still have the att after the operation will be considered
+ // unmodified.
+ ENTITY_LIST edges_and_verts, tmp_list;
+ api_get_edges((ENTITY*)body, edges_and_verts);
+ api_get_vertices((ENTITY*)body, tmp_list);
+ edges_and_verts.add(tmp_list);
+ ENTITY *tmp_ent;
+ edges_and_verts.init();
+ while((tmp_ent = edges_and_verts.next()))
+ add_named_att(tmp_ent, "UNMODIFIED");
+
+ // This will group points that are close together into clumps and will
+ // build a map from the points to the clump they are in.
+ if(!setup_clump_map(edges_to_remove, faces_to_remove, small_edge_size,
+ clumps, old_vertex_to_clump_map))
+ {
+ status = CUBIT_FAILURE;
+ }
+ // Create a global list of all of the pts that are in clumps.
+ else if(!get_all_verts_in_clumps(clumps, all_verts_in_clumps))
+ {
+ status = CUBIT_FAILURE;
+ }
+ // Build a map from a clump to the faces surrounding it.
+ else if(!find_faces_surrounding_clumps(clumps, surrounding_faces_map,
+ all_verts_in_clumps, old_vertex_to_clump_map, faces_to_remove))
+ {
+ status = CUBIT_FAILURE;
+ }
+ else if(!find_face_clump_counts(surrounding_faces_map, face_clump_count_map))
+ {
+ status = CUBIT_FAILURE;
+ }
+ else if(!find_faces_that_dont_intersect(surrounding_faces_map,
+ faces_that_dont_intersect_map, small_edge_size))
+ {
+ status = CUBIT_FAILURE;
+ }
+ else if(!ensure_possible_solution(faces_that_dont_intersect_map, faces_that_might_move))
+ {
+ status = CUBIT_FAILURE;
+ }
+ else if(!choose_best_face_to_move(faces_that_might_move,
+ face_clump_count_map, all_verts_in_clumps))
+ {
+ status = CUBIT_FAILURE;
+ }
+// else if(!find_new_pos_for_clump(surrounding_faces_map, faces_that_might_move, small_edge_size))
+// {
+// status = CUBIT_FAILURE;
+// }
+ else if(!build_clump_topology(clumps))
+ {
+ status = CUBIT_FAILURE;
+ }
+ else if(!find_new_edges_between_clumps(clumps, old_edge_to_new_edge_map, surrounding_faces_map))
+ {
+ status = CUBIT_FAILURE;
+ }
+ else if(!adjust_backoff_distance(clumps, old_vertex_to_clump_map,
+ old_edge_to_new_edge_map, backoff_distance))
+ {
+ status = CUBIT_FAILURE;
+ }
+ else if(!split_all_curves_coming_into_clumps(clumps, old_vertex_to_clump_map,
+ old_edge_to_new_edge_map, backoff_distance, split_positions))
+ {
+ status = CUBIT_FAILURE;
+ }
+ else
+ {
+ int display_clumps = 0;
+ if(display_clumps)
+ {
+ std::map <VERTEXClump*,DLIList<FACE*>*, mapltclump>::iterator iter;
+ for(iter=surrounding_faces_map.begin(); iter != surrounding_faces_map.end(); iter++ )
+ {
+ DLIList<FACE*> *face_list = iter->second;
+ for(i=face_list->size(); i--;)
+ {
+ FACE *cur_face = face_list->get_and_step();
+ F(cur_face, 8);
+ }
+ }
+ for(i=clumps.size(); i--;)
+ {
+ VERTEXClump *vc = clumps.get_and_step();
+ V(vc->new_vert, 4);
+ }
+ }
+ }
+
+ if(status == CUBIT_FAILURE ||
+ !generate_faces_for_surrounding_faces(surrounding_faces_map, old_edge_to_new_edge_map,
+ old_vertex_to_clump_map, new_vol_faces, modified_faces, backoff_distance, faces_to_remove,
+ projected_positions))
+ {
+ status = CUBIT_FAILURE;
+ }
+ else
+ {
+ for(i=faces_to_remove.size(); i--;)
+ api_remove_face(faces_to_remove.get_and_step());
+
+ for(i=clumps.size(); i--;)
+ {
+ VERTEXClump *vc = clumps.get_and_step();
+ clump_positions.append(vc->new_vert->geometry()->coords());
+ }
+
+ if(!combine_old_body_and_new_faces(body, new_vol_faces))
+ status = CUBIT_FAILURE;
+ }
+
+ int cleanup = 1;
+ if(status == CUBIT_SUCCESS && cleanup)
+ {
+ // Get a list of the edges and verts that were
+ // not modified.
+ DLIList<ENTITY*> unmodified_ents, new_ents;
+ edges_and_verts.clear();
+ tmp_list.clear();
+ api_get_edges((ENTITY*)body, edges_and_verts);
+ api_get_vertices((ENTITY*)body, tmp_list);
+ edges_and_verts.add(tmp_list);
+ ENTITY *tmp_ent;
+ edges_and_verts.init();
+ while((tmp_ent = edges_and_verts.next()))
+ {
+ ATTRIB_SNL_SIMPLE *att = find_named_att(tmp_ent, "UNMODIFIED");
+ if(att)
+ {
+ remove_att(tmp_ent, att);
+ unmodified_ents.append(tmp_ent);
+ }
+ else
+ new_ents.append(tmp_ent);
+ }
+
+ // Classify all of the new verts as either a clump, split,
+ // or projected vert.
+ int j;
+ DLIList<VERTEX*> clump_verts, split_verts, projected_verts;
+ DLIList<ENTITY*> vert_ents;
+ for(i=new_ents.size(); i--;)
+ {
+ ENTITY *ent = new_ents.get_and_step();
+ if(is_VERTEX(ent))
+ {
+ vert_ents.append(ent);
+ SPAposition vert_pos = ((VERTEX*)ent)->geometry()->coords();
+ int found = 0;
+ for(j=clump_positions.size(); j>0 && !found; j--)
+ {
+ SPAposition cur_pos = clump_positions.get();
+ if((cur_pos - vert_pos).len_sq() < tol_sq)
+ {
+ found = 1;
+ clump_verts.append_unique((VERTEX*)ent);
+ clump_positions.extract();
+ }
+ else
+ clump_positions.step();
+ }
+ for(j=split_positions.size(); j>0 && !found; j--)
+ {
+ SPAposition cur_pos = split_positions.get();
+ if((cur_pos - vert_pos).len_sq() < tol_sq)
+ {
+ found = 1;
+ split_verts.append_unique((VERTEX*)ent);
+ split_positions.extract();
+ }
+ else
+ split_positions.step();
+ }
+ for(j=projected_positions.size(); j>0 && !found; j--)
+ {
+ SPAposition cur_pos = projected_positions.get();
+ if((cur_pos - vert_pos).len_sq() < tol_sq)
+ {
+ found = 1;
+ projected_verts.append_unique((VERTEX*)ent);
+ projected_positions.extract();
+ }
+ else
+ projected_positions.step();
+ }
+ }
+ }
+
+ // Remove all of the vertices from the list so that we
+ // just have edges.
+ new_ents -= vert_ents;
+
+ // Look at each new edge and try to regularize or composite it
+ // out if appropriate.
+ ENTITY_LIST cur_body_edges;
+ api_get_edges((ENTITY*)body, cur_body_edges);
+ for(i=new_ents.size(); i--;)
+ {
+ EDGE *edge = (EDGE*)new_ents.get_and_step();
+ if(cur_body_edges.lookup((ENTITY*)edge) != -1)
+ {
+ int try_to_remove = 0;
+ // "REMOVE_EDGE" attributes were placed on edges that we want to
+ // try to regularize/composite out.
+ ATTRIB_SNL_SIMPLE *att = find_named_att((ENTITY*)edge, "REMOVE_EDGE");
+ if(att)
+ {
+ remove_att((ENTITY*)edge, att);
+ try_to_remove = 1;
+ }
+ if(try_to_remove)
+ {
+ int failed;
+ ENTITY_LIST edges_after;
+ API_TRIAL_BEGIN;
+ api_clean_entity((ENTITY*)edge);
+ api_get_edges((ENTITY*)body, edges_after);
+ failed = (cur_body_edges.count() == edges_after.count());
+ if(failed)
+ sys_error(12345);
+ API_TRIAL_END;
+ cur_body_edges = edges_after;
+ if(failed)
+ {
+ ATTRIB_SNL_SIMPLE *att = find_named_att((ENTITY*)edge, "COMPOSITE_GEOM");
+ if(!att)
+ add_named_att((ENTITY*)edge, "COMPOSITE_GEOM");
+ }
+ }
+ }
+ }
+
+ // Look at each new vertex (that is still in the model) and composite
+ // it out if appropriate.
+ ENTITY_LIST cur_body_verts;
+ api_get_vertices((ENTITY*)body, cur_body_verts);
+ for(i=vert_ents.size(); i--;)
+ {
+ VERTEX *vert = (VERTEX*)vert_ents.get_and_step();
+ if(cur_body_verts.lookup((ENTITY*)vert) != -1)
+ {
+ int try_to_remove = 0;
+ if(!clump_verts.is_in_list(vert))
+ {
+ ENTITY_LIST vert_edges;
+ api_get_edges((ENTITY*)vert, vert_edges);
+ int num_edges = vert_edges.count();
+ ENTITY *tmp_ent;
+ vert_edges.init();
+ while((tmp_ent = vert_edges.next()))
+ {
+ if(find_named_att(tmp_ent, "COMPOSITE_GEOM"))
+ num_edges--;
+ }
+ if(num_edges == 2)
+ try_to_remove = 1;
+ }
+
+ if(try_to_remove)
+ {
+ if(!find_named_att((ENTITY*)vert, "COMPOSITE_GEOM"))
+ add_named_att((ENTITY*)vert, "COMPOSITE_GEOM");
+ }
+ }
+ }
+ }
+
+ return status;
+}
+
+ATTRIB_SNL_SIMPLE* AcisTopologyTool::find_named_att(ENTITY* ent, const char *name)
+{
+ ATTRIB_SNL_SIMPLE *ret_attrib = NULL;
+ ATTRIB_SNL_SIMPLE *attribute =
+ (ATTRIB_SNL_SIMPLE *) find_attrib(ent,
+ ATTRIB_SNL_TYPE,
+ ATTRIB_SNL_SIMPLE_TYPE);
+ for(;attribute != NULL && !ret_attrib;attribute = (ATTRIB_SNL_SIMPLE *)
+ find_next_attrib(attribute,
+ ATTRIB_SNL_TYPE,
+ ATTRIB_SNL_SIMPLE_TYPE))
+ {
+ if( attribute->attribute_name() == name )
+ ret_attrib = attribute;
+ }
+ return ret_attrib;
+}
+
+void AcisTopologyTool::add_named_att(ENTITY* ent, const char *name_in)
+{
+ CubitString name(name_in);
+ DLIList<CubitString*> string_list;
+ string_list.append(&name);
+ CubitSimpleAttrib attrib(&string_list, 0, 0);
+ API_BEGIN;
+ new ATTRIB_SNL_SIMPLE(ent, &attrib);
+ API_END;
+}
+
+void AcisTopologyTool::remove_att(ENTITY* ent, ATTRIB_SNL_SIMPLE *att)
+{
+ API_BEGIN;
+ att->unhook();
+ API_END;
+}
+
+CubitStatus AcisTopologyTool::combine_old_body_and_new_faces(BODY *&b, DLIList<FACE*> &new_faces)
+{
+ int i, heal = 0;
+ ENTITY_LIST BODY_list;
+ for(i=new_faces.size(); i--;)
+ {
+ FACE *cur_face = new_faces.get_and_step();
+ ENTITY *owner;
+ api_get_owner((ENTITY*)cur_face, owner);
+ if(!owner || !is_BODY(owner))
+ {
+ FACE *face_list[1];
+ BODY *sheet_body;
+ face_list[0] = cur_face;
+ outcome rc = api_sheet_from_ff(1, face_list, sheet_body);
+ if (!rc.ok())
+ PRINT_ERROR("Couldn't build a BODY with FACE.\n") ;
+ rc = api_body_to_2d(sheet_body);
+ if (!rc.ok())
+ PRINT_ERROR("Couldn't build a volume with Surface.\n" );
+ // Make sure we were successful
+ if ( sheet_body->lump() == NULL ||
+ sheet_body->lump()->shell() == NULL ||
+ sheet_body->lump()->shell()->first_face() == NULL )
+ {
+ PRINT_ERROR("Couldn't build a volume with Surface.\n" );
+ }
+ BODY_list.add(sheet_body);
+ }
+ else
+ BODY_list.add((BODY*)owner);
+ }
+ api_body_to_2d(b);
+ BODY_list.add(b);
+
+ BODY* result_BODY = NULL;
+ if( !heal )
+ {
+ ENTITY_LIST dummy_list, resultant_bodies;
+ // exact_stitch_options stitch_opts;
+ tolerant_stitch_options stitch_opts;
+ //surfaces better be between GEOMETRY_RESABS or else fail
+ stitch_opts.set_max_stitch_tol( GEOMETRY_RESABS );
+ outcome result = api_stitch( BODY_list, dummy_list, resultant_bodies, &stitch_opts );
+
+ result_BODY = (BODY*)dummy_list.first();
+
+ int is_closed = 1;
+ if(result.ok() && result_BODY)
+ is_closed = is_closed_solid_body(result_BODY);
+
+ if(!is_closed)
+ PRINT_ERROR("Failed to make a closed body after removing the specified topology.\n"
+ "Possible remedies:\n"
+ " Check that input parameters are reasonable values for topology being removed and surrounding topology.\n"
+ " Check if narrow surfaces need to be split into simple 4-sided surfaces (see 'auto_clean split_narrow_regions' command).\n");
+
+ if (!result.ok() || (!result_BODY ) || !is_closed)
+ {
+ // If there are no LUMPs in the resulting BODY, return with a failure
+ if (result_BODY == NULL)
+ PRINT_ERROR("In AcisModifyEngine::create_solid_bodies_from_surfs\n");
+
+ if (result_BODY != NULL)
+ {
+ AcisQueryEngine::instance()->delete_ACIS_BODY(result_BODY);
+ b = NULL;
+ result_BODY = NULL;
+ }
+
+ return CUBIT_FAILURE;
+ }
+ }
+ /*
+ // If all went well, delete the old Bodies
+ DLIList<TopologyBridge*> old_entities;
+ body_list.reset() ;
+
+ CAST_LIST_TO_PARENT(body_list, old_entities);
+
+ for ( ii = free_faces.size(); ii > 0; ii-- )
+ old_entities.append(free_faces.get_and_step());
+ */
+
+
+#ifdef ACIS_HEALER
+// BODY *new_master = master;
+ if ( heal )
+ {
+#if 0
+ // Now heal the combined body
+ PRINT_INFO(" Healing the combined volume...\n");
+ if( AcisHealerTool::instance()->init_BODY_for_healing( master ) == CUBIT_SUCCESS )
+ {
+ int percent_before, percent_after, number_splines_simplified;
+ if( AcisHealerTool::instance()->heal_BODY( master, percent_before,
+ percent_after, number_splines_simplified ) == CUBIT_FAILURE )
+ PRINT_ERROR( "Error healing the combined volume\n" );
+ else
+ PRINT_INFO( "Healed the combined volume to %d%% good geometry.\n", percent_after );
+ AcisHealerTool::instance()->end_BODY_for_healing( master );
+ }
+#endif
+ }
+#else
+ PRINT_WARNING("Healer was not included with this version.\n"
+ " Volume healing is usually required for creating\n"
+ " volumes out of surfaces.\n");
+#endif
+
+ if(result_BODY)
+ b = result_BODY;
+
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus AcisTopologyTool::build_clump_topology(DLIList<VERTEXClump*> &clumps)
+{
+ int i;
+
+ for(i=clumps.size(); i--;)
+ {
+ VERTEXClump *cur_clump = clumps.get_and_step();
+ APOINT *p1 = new APOINT(cur_clump->ave_pos);
+ cur_clump->new_vert = new VERTEX(p1);
+ }
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus AcisTopologyTool::generate_faces_for_surrounding_faces(std::map <VERTEXClump*, DLIList<FACE*>*, mapltclump> &surrounding_faces_map,
+ std::map <EDGE*, EDGE*, mapltid> &old_edge_to_new_edge_map,
+ std::map <VERTEX*,VERTEXClump*, mapltid> &old_vertex_to_clump_map,
+ DLIList<FACE*> &new_vol_faces,
+ DLIList<FACE*> &modified_faces,
+ double &backoff_distance,
+ DLIList<FACE*> &dead_faces,
+ DLIList<SPAposition> &projected_positions)
+{
+ CubitStatus ret = CUBIT_SUCCESS;
+ int i, debug_display = 0;
+ std::map <VERTEXClump*,DLIList<FACE*>*, mapltclump>::iterator iter;
+ DLIList<FACE*> processed_faces;
+ for(iter=surrounding_faces_map.begin(); iter != surrounding_faces_map.end() && ret == CUBIT_SUCCESS; iter++ )
+ {
+ DLIList<FACE*> *face_list = iter->second;
+ for(i=face_list->size(); i && ret == CUBIT_SUCCESS; i--)
+ {
+ FACE *cur_face = face_list->get_and_step();
+ if(debug_display)
+ F(cur_face, i%4+3);
+ if(!generate_faces_for_surrounding_face(cur_face, backoff_distance, old_vertex_to_clump_map,
+ old_edge_to_new_edge_map, processed_faces, modified_faces, new_vol_faces, dead_faces,
+ projected_positions))
+ {
+ ret = CUBIT_FAILURE;
+ }
+ }
+ }
+ return ret;
+}
+
+int AcisTopologyTool::is_lateral_edge(EDGE *edge,
+ std::map <EDGE*, EDGE*, mapltid> &old_edge_to_new_edge_map)
+{
+ int ret = 0;
+
+ if(old_edge_to_new_edge_map.count(edge))
+ ret = 1;
+
+ return ret;
+}
+
+CubitStatus AcisTopologyTool::generate_faces_for_surrounding_face(FACE *face,
+ double &backoff_distance,
+ std::map <VERTEX*, VERTEXClump*, mapltid> &old_vertex_to_clump_map,
+ std::map <EDGE*, EDGE*, mapltid> &old_edge_to_new_edge_map,
+ DLIList<FACE*> &processed_faces,
+ DLIList<FACE*> &modified_faces,
+ DLIList<FACE*> &new_vol_faces,
+ DLIList<FACE*> &dead_faces,
+ DLIList<SPAposition> &projected_positions)
+{
+ CubitStatus ret = CUBIT_SUCCESS;
+ DLIList<VERTEX*> processed_verts;
+ DLIList<EDGE*> processed_edges;
+ DLIList<EDGE*> edges_to_imprint;
+ if(!processed_faces.is_in_list(face))
+ {
+ processed_faces.append(face);
+ modified_faces.append(face);
+ ENTITY_LIST face_edges;
+ api_get_edges((ENTITY*)face, face_edges);
+ ENTITY *tmp_ent;
+ face_edges.init();
+ while((tmp_ent = face_edges.next()) && ret == CUBIT_SUCCESS)
+ {
+ EDGE *cur_edge = (EDGE*)tmp_ent;
+ if(!processed_edges.is_in_list(cur_edge))
+ {
+ if(is_lateral_edge(cur_edge, old_edge_to_new_edge_map))
+ {
+ if(!generate_faces_for_lateral_edge(face, cur_edge, backoff_distance,
+ old_vertex_to_clump_map, old_edge_to_new_edge_map, processed_verts,
+ processed_edges, edges_to_imprint, new_vol_faces, dead_faces,
+ projected_positions))
+ {
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else if(edge_within_clump(cur_edge, old_vertex_to_clump_map))
+ {
+ }
+ else
+ {
+ if(!generate_faces_for_non_lateral_edge(face, cur_edge, backoff_distance,
+ old_vertex_to_clump_map, old_edge_to_new_edge_map, processed_verts,
+ processed_edges, edges_to_imprint, new_vol_faces, dead_faces,
+ projected_positions))
+ {
+ ret = CUBIT_FAILURE;
+ }
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+CubitStatus AcisTopologyTool::generate_faces_for_non_lateral_edge(FACE *&face, EDGE *edge,
+ double &backoff_distance,
+ std::map <VERTEX*, VERTEXClump*, mapltid> &old_vertex_to_clump_map,
+ std::map <EDGE*, EDGE*, mapltid> &old_edge_to_new_edge_map,
+ DLIList<VERTEX*> &processed_verts,
+ DLIList<EDGE*> &processed_edges,
+ DLIList<EDGE*> &edges_to_imprint,
+ DLIList<FACE*> &new_vol_faces,
+ DLIList<FACE*> &dead_faces,
+ DLIList<SPAposition> &projected_positions)
+{
+ CubitStatus ret = CUBIT_SUCCESS;
+ DLIList<VERTEX*> edge_verts;
+ SPAposition tmp_pos;
+ SPAunit_vector cur_dir, other_dir;
+ ENTITY *new_ent;
+
+ processed_edges.append(edge);
+
+ VERTEX *vert = NULL;
+ if(!processed_verts.is_in_list(edge->start()) && old_vertex_to_clump_map.count(edge->start()))
+ vert = edge->start();
+ else if(!processed_verts.is_in_list(edge->end()) && old_vertex_to_clump_map.count(edge->end()))
+ vert = edge->end();
+
+ if(vert)
+ {
+ VERTEX *clump_vert = old_vertex_to_clump_map[vert]->new_vert;
+ EDGE *next_edge;
+ VERTEX *next_vert;
+ get_next_edge_around_clump(edge, vert, face,
+ old_vertex_to_clump_map, next_edge, next_vert);
+ if(next_edge && next_vert)
+ {
+ double angle = this->angle_between(face, edge, vert, next_edge, next_vert);
+ if(is_lateral_edge(next_edge, old_edge_to_new_edge_map))
+ {
+ // If the next edge is a lateral edge this will get processed later.
+ }
+ else
+ {
+ SPAposition other_vert_pos = other_vertex(edge, vert)->geometry()->coords();
+ SPAposition next_other_pos = other_vertex(next_edge, next_vert)->geometry()->coords();
+ processed_verts.append(vert);
+ processed_verts.append(next_vert);
+ // Just create a triangular face.
+ if(angle < pi_over_four)
+ {
+ EDGE *new_edge1=NULL, *new_edge3=NULL, *new_edge4=NULL;
+ VERTEX *v1 = new_vert_from_pos(other_vert_pos);
+ VERTEX *v2 = new_vert_from_pos(next_other_pos);
+ new_edge1 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge1)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ face = this->find_keep_face(new_edge1, vert, dead_faces);
+ add_named_att((ENTITY*)new_edge1, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge1, new_ent);
+ new_edge1 = (EDGE*)new_ent;
+ v1 = new_vert_from_pos(other_vert_pos);
+ v2 = new_vert_from_pos(old_vertex_to_clump_map[vert]->new_vert->geometry()->coords());
+ STRAIGHT *s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ new_edge3 = new EDGE(v1, v2, s, FORWARD);
+ v1 = new_vert_from_pos(next_other_pos);
+ v2 = new_vert_from_pos(old_vertex_to_clump_map[next_vert]->new_vert->geometry()->coords());
+ s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ new_edge4 = new EDGE(v1, v2, s, FORWARD);
+ if(new_edge1 && new_edge3 && new_edge4)
+ {
+ // Now create the new face.
+ DLIList<EDGE*> edges_for_new_face;
+ edges_for_new_face.append(new_edge1);
+ edges_for_new_face.append(new_edge3);
+ edges_for_new_face.append(new_edge4);
+ FACE* FACE_ptr = AcisModifyEngine::instance()->make_FACE(PLANE_SURFACE_TYPE, edges_for_new_face);
+ if(FACE_ptr)
+ new_vol_faces.append(FACE_ptr);
+ else
+ {
+ PRINT_ERROR("Failed to build face from bounding curves.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to get all of the required edges for a new face.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ }
+ // We have two non-lateral edges coming into one or more vertices in a clump
+ // with no lateral edges in between them. So, there will be no new faces
+ // associated with lateral edges but we need to create one or more faces
+ // depending on the angle between the two edges.
+ else if(angle <= three_pi_over_four)
+ {
+ // Just create one face between this edge and the next edge.
+ // This will require two new edges projected into the face
+ // from the two split points on the edges.
+ SPAposition new_pos1;
+ EDGE *new_edge1=NULL, *new_edge2=NULL, *new_edge3, *new_edge4;
+ tangent_indir(face, edge, vert->geometry()->coords(), cur_dir);
+ tangent_indir(face, next_edge, next_vert->geometry()->coords(), other_dir);
+ SPAvector ave_dir = cur_dir + other_dir;
+ SPAvector ave_dir_norm = normalise(ave_dir);
+ angle /= 2.0;
+ double distance = backoff_distance/sin(angle);
+ SPAposition mid_pos((vert->geometry()->coords().x() + next_vert->geometry()->coords().x())/2.0,
+ (vert->geometry()->coords().y() + next_vert->geometry()->coords().y())/2.0,
+ (vert->geometry()->coords().z() + next_vert->geometry()->coords().z())/2.0);
+ tmp_pos = mid_pos + distance * ave_dir_norm;
+ face->geometry()->equation().point_perp(tmp_pos, new_pos1);
+
+ // Now create an edge going from the new position to the split
+ // position on each of the edges.
+ VERTEX *v1 = new_vert_from_pos(new_pos1);
+ VERTEX *v2 = new_vert_from_pos(other_vert_pos);
+ new_edge1 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge1)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge1, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge1, new_ent);
+ new_edge1 = (EDGE*)new_ent;
+ v1 = new_vert_from_pos(new_pos1);
+ v2 = new_vert_from_pos(next_other_pos);
+ new_edge2 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge2)
+ ret = CUBIT_FAILURE;
+ face = this->find_keep_face(new_edge2, vert, dead_faces);
+ if(!face)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge2, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge2, new_ent);
+ new_edge2 = (EDGE*)new_ent;
+ v1 = new_vert_from_pos(other_vert_pos);
+ v2 = new_vert_from_pos(old_vertex_to_clump_map[vert]->new_vert->geometry()->coords());
+ STRAIGHT *s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ new_edge3 = new EDGE(v1, v2, s, FORWARD);
+ v1 = new_vert_from_pos(next_other_pos);
+ v2 = new_vert_from_pos(old_vertex_to_clump_map[next_vert]->new_vert->geometry()->coords());
+ s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ new_edge4 = new EDGE(v1, v2, s, FORWARD);
+
+ if(new_edge1 && new_edge2 && new_edge3 && new_edge4)
+ {
+ // Now create the new face.
+ DLIList<EDGE*> edges_for_new_face;
+ edges_for_new_face.append(new_edge1);
+ edges_for_new_face.append(new_edge2);
+ edges_for_new_face.append(new_edge3);
+ edges_for_new_face.append(new_edge4);
+ FACE* FACE_ptr = AcisModifyEngine::instance()->make_FACE(PLANE_SURFACE_TYPE, edges_for_new_face);
+ if(FACE_ptr)
+ {
+ new_vol_faces.append(FACE_ptr);
+ projected_positions.append(new_pos1);
+ }
+ else
+ {
+ PRINT_ERROR("Failed to create face from bounding curves.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to get all of the required edges for a new face.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ }
+ }
+ else if(angle <= five_pi_over_four)
+ {
+ // Introduce two new faces between the two edges.
+ EDGE *new_edge1=NULL, *new_edge2=NULL, *new_edge3=NULL, *new_edge4=NULL, *new_edge5=NULL;
+ EDGE *new_edge6, *new_edge7, *new_edge8;
+ SPAposition new_pos1, new_pos2, new_pos3;
+ SPAposition mid_pos((vert->geometry()->coords().x() + next_vert->geometry()->coords().x())/2.0,
+ (vert->geometry()->coords().y() + next_vert->geometry()->coords().y())/2.0,
+ (vert->geometry()->coords().z() + next_vert->geometry()->coords().z())/2.0);
+
+ // Project from the current vert into the face at an average direction.
+ tangent_indir(face, edge, vert->geometry()->coords(), cur_dir);
+ tangent_indir(face, next_edge, next_vert->geometry()->coords(), other_dir);
+ SPAvector ave_dir = cur_dir + other_dir;
+ SPAvector ave_dir_norm = normalise(ave_dir);
+ angle /= 2.0;
+ double distance = backoff_distance/sin(angle);
+ tmp_pos = mid_pos + distance * ave_dir_norm;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos1);
+ int cntr = 0;
+ point_face_containment containment;
+ api_point_in_face(new_pos1, face, *(SPAtransf*)NULL_REF, containment);
+ // Try to make sure we have a point on the face.
+ while(containment == point_boundary_face && cntr++ < 10)
+ {
+ distance = (clump_vert->geometry()->coords()-new_pos1).len() / 2.0;
+ tmp_pos = mid_pos + distance * ave_dir_norm;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos1);
+ api_point_in_face(new_pos1, face, *(SPAtransf*)NULL_REF, containment);
+ }
+ double dist2 = backoff_distance;
+ // Project from each split position into the face to get the
+ // other two new positions.
+ // Now that we have the location of the new position projected into
+ // the face we will create the first new edge.
+ tangent_indir(face, edge, other_vert_pos, cur_dir);
+ tmp_pos = other_vert_pos + dist2*cur_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos2);
+
+ cntr = 0;
+ api_point_in_face(new_pos2, face, *(SPAtransf*)NULL_REF, containment);
+ while(containment == point_boundary_face && cntr++ < 10)
+ {
+ dist2 = (other_vert_pos-new_pos2).len() / 2.0;
+ tmp_pos = other_vert_pos + dist2*cur_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos2);
+ api_point_in_face(new_pos2, face, *(SPAtransf*)NULL_REF, containment);
+ }
+
+ tangent_indir(face, next_edge, next_other_pos, other_dir);
+ tmp_pos = next_other_pos + dist2*other_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos3);
+
+ cntr = 0;
+ api_point_in_face(new_pos3, face, *(SPAtransf*)NULL_REF, containment);
+ while(containment == point_boundary_face && cntr++ < 10)
+ {
+ dist2 = (next_other_pos-new_pos3).len() / 2.0;
+ tmp_pos = next_other_pos + dist2*other_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos3);
+ api_point_in_face(new_pos3, face, *(SPAtransf*)NULL_REF, containment);
+ }
+ // Create the edge going from the new clump vert to new_pos1.
+ VERTEX *v1 = new_vert_from_pos(new_pos1);
+ VERTEX *v2 = new_vert_from_pos(clump_vert->geometry()->coords());
+ STRAIGHT *s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ new_edge1 = new EDGE(v1, v2, s, FORWARD);
+ add_named_att((ENTITY*)new_edge1, "REMOVE_EDGE");
+ // Make another copy of this.
+ v1 = new_vert_from_pos(new_pos1);
+ v2 = new_vert_from_pos(clump_vert->geometry()->coords());
+ s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ new_edge8 = new EDGE(v1, v2, s, FORWARD);
+ add_named_att((ENTITY*)new_edge8, "REMOVE_EDGE");
+ // Create the edge going from the cur split to new_pos2.
+ v1 = new_vert_from_pos(new_pos2);
+ v2 = new_vert_from_pos(other_vert_pos);
+ new_edge2 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge2)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge2, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge2, new_ent);
+ new_edge2 = (EDGE*)new_ent;
+ // Create the edge going from the next split to new_pos3.
+ v1 = new_vert_from_pos(new_pos3);
+ v2 = new_vert_from_pos(next_other_pos);
+ new_edge3 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge3)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge3, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge3, new_ent);
+ new_edge3 = (EDGE*)new_ent;
+ // Create the edge going from new_pos1 to new_pos2.
+ v1 = new_vert_from_pos(new_pos1);
+ v2 = new_vert_from_pos(new_pos2);
+ new_edge4 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge4)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ face = this->find_keep_face(new_edge4, vert, dead_faces);
+ if(!face)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge4, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge4, new_ent);
+ new_edge4 = (EDGE*)new_ent;
+ // Create the edge going from new_pos1 to new_pos3.
+ v1 = new_vert_from_pos(new_pos1);
+ v2 = new_vert_from_pos(new_pos3);
+ new_edge5 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge5)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ face = this->find_keep_face(new_edge5, vert, dead_faces);
+ if(!face)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge5, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge5, new_ent);
+ new_edge5 = (EDGE*)new_ent;
+ v1 = new_vert_from_pos(other_vert_pos);
+ v2 = new_vert_from_pos(clump_vert->geometry()->coords());
+ s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ new_edge6 = new EDGE(v1, v2, s, FORWARD);
+ v1 = new_vert_from_pos(next_other_pos);
+ v2 = new_vert_from_pos(old_vertex_to_clump_map[next_vert]->new_vert->geometry()->coords());
+ s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ new_edge7 = new EDGE(v1, v2, s, FORWARD);
+ if(new_edge1 && new_edge2 && new_edge4 && new_edge6)
+ {
+ // Now create the new face.
+ DLIList<EDGE*> edges_for_new_face;
+ edges_for_new_face.append(new_edge1);
+ edges_for_new_face.append(new_edge2);
+ edges_for_new_face.append(new_edge4);
+ edges_for_new_face.append(new_edge6);
+ FACE* FACE_ptr = AcisModifyEngine::instance()->make_FACE(PLANE_SURFACE_TYPE, edges_for_new_face);
+ if(FACE_ptr)
+ {
+ new_vol_faces.append(FACE_ptr);
+ projected_positions.append(new_pos1);
+ projected_positions.append(new_pos2);
+ if(new_edge8 && new_edge3 && new_edge5 && new_edge7)
+ {
+ // Now create the new face.
+ DLIList<EDGE*> edges_for_new_face;
+ edges_for_new_face.append(new_edge8);
+ edges_for_new_face.append(new_edge3);
+ edges_for_new_face.append(new_edge5);
+ edges_for_new_face.append(new_edge7);
+ FACE* FACE_ptr = AcisModifyEngine::instance()->make_FACE(PLANE_SURFACE_TYPE, edges_for_new_face);
+ if(FACE_ptr)
+ {
+ new_vol_faces.append(FACE_ptr);
+ projected_positions.append(new_pos3);
+ }
+ else
+ {
+ PRINT_ERROR("Failed to build face from bounding curves.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to get all of the required edges for a new face.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to build face from bounding curves.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to get all of the required edges for a new face.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if(angle <= seven_pi_over_four)
+ {
+ // Add three new faces.
+ EDGE *new_edge1=NULL, *new_edge2=NULL, *new_edge3=NULL, *new_edge4=NULL, *new_edge5=NULL;
+ EDGE *new_edge6, *new_edge7, *new_edge8, *new_edge9, *new_edge10, *new_edge11, *new_edge12;
+ SPAposition new_pos1, new_pos2, new_pos3, new_pos4, new_pos5;
+ SPAposition mid_pos((vert->geometry()->coords().x() + next_vert->geometry()->coords().x())/2.0,
+ (vert->geometry()->coords().y() + next_vert->geometry()->coords().y())/2.0,
+ (vert->geometry()->coords().z() + next_vert->geometry()->coords().z())/2.0);
+
+ // Project from the current vert into the face at an average direction.
+ SPAunit_vector cur_in_dir, next_in_dir, cur_other_in_dir, next_other_in_dir;
+ tangent_indir(face, edge, vert->geometry()->coords(), cur_in_dir);
+ tangent_indir(face, next_edge, next_vert->geometry()->coords(), next_in_dir);
+ SPAvector ave_dir = cur_in_dir + next_in_dir;
+ SPAvector ave_dir_norm = normalise(ave_dir);
+ angle /= 2.0;
+ double distance = backoff_distance/sin(angle);
+ tmp_pos = mid_pos + distance * ave_dir_norm;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos1);
+ int cntr = 0;
+ point_face_containment containment;
+ api_point_in_face(new_pos1, face, *(SPAtransf*)NULL_REF, containment);
+ // Try to make sure we have a point on the face.
+ while(containment == point_boundary_face && cntr++ < 10)
+ {
+ distance = (clump_vert->geometry()->coords()-new_pos1).len() / 2.0;
+ tmp_pos = mid_pos + distance * ave_dir_norm;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos1);
+ api_point_in_face(new_pos1, face, *(SPAtransf*)NULL_REF, containment);
+ }
+ double dist2 = backoff_distance;
+ // Project from each split position into the face to get the
+ // other two new positions.
+ // Now that we have the location of the new position projected into
+ // the face we will create the first new edge.
+ tangent_indir(face, edge, other_vert_pos, cur_other_in_dir);
+ tmp_pos = other_vert_pos + dist2*cur_other_in_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos2);
+
+ cntr = 0;
+ api_point_in_face(new_pos2, face, *(SPAtransf*)NULL_REF, containment);
+ while(containment == point_boundary_face && cntr++ < 10)
+ {
+ dist2 = (other_vert_pos-new_pos2).len() / 2.0;
+ tmp_pos = other_vert_pos + dist2*cur_other_in_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos2);
+ api_point_in_face(new_pos2, face, *(SPAtransf*)NULL_REF, containment);
+ }
+
+ tangent_indir(face, next_edge, next_other_pos, next_other_in_dir);
+ tmp_pos = next_other_pos + dist2*next_other_in_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos3);
+
+ cntr = 0;
+ api_point_in_face(new_pos3, face, *(SPAtransf*)NULL_REF, containment);
+ while(containment == point_boundary_face && cntr++ < 10)
+ {
+ dist2 = (next_other_pos-new_pos3).len() / 2.0;
+ tmp_pos = next_other_pos + dist2*next_other_in_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos3);
+ api_point_in_face(new_pos3, face, *(SPAtransf*)NULL_REF, containment);
+ }
+
+ tmp_pos = vert->geometry()->coords() + dist2*cur_in_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos4);
+
+ cntr = 0;
+ api_point_in_face(new_pos4, face, *(SPAtransf*)NULL_REF, containment);
+ while(containment == point_boundary_face && cntr++ < 10)
+ {
+ dist2 = (vert->geometry()->coords()-new_pos4).len() / 2.0;
+ tmp_pos = vert->geometry()->coords() + dist2*cur_in_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos4);
+ api_point_in_face(new_pos4, face, *(SPAtransf*)NULL_REF, containment);
+ }
+
+ tmp_pos = next_vert->geometry()->coords() + dist2*next_in_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos5);
+
+ cntr = 0;
+ api_point_in_face(new_pos5, face, *(SPAtransf*)NULL_REF, containment);
+ while(containment == point_boundary_face && cntr++ < 10)
+ {
+ dist2 = (next_vert->geometry()->coords()-new_pos5).len() / 2.0;
+ tmp_pos = next_vert->geometry()->coords() + dist2*next_in_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos5);
+ api_point_in_face(new_pos5, face, *(SPAtransf*)NULL_REF, containment);
+ }
+
+ // Create the edge going from the new clump vert to new_pos4.
+ VERTEX *v1 = new_vert_from_pos(new_pos4);
+ VERTEX *v2 = new_vert_from_pos(clump_vert->geometry()->coords());
+ STRAIGHT *s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ new_edge1 = new EDGE(v1, v2, s, FORWARD);
+ add_named_att((ENTITY*)new_edge1, "REMOVE_EDGE");
+ // Make another copy of this.
+ v1 = new_vert_from_pos(new_pos4);
+ v2 = new_vert_from_pos(clump_vert->geometry()->coords());
+ s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ new_edge8 = new EDGE(v1, v2, s, FORWARD);
+ add_named_att((ENTITY*)new_edge8, "REMOVE_EDGE");
+ // Create the edge going from new clump vert to new_pos5
+ v1 = new_vert_from_pos(new_pos5);
+ v2 = new_vert_from_pos(clump_vert->geometry()->coords());
+ s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ new_edge2 = new EDGE(v1, v2, s, FORWARD);
+ add_named_att((ENTITY*)new_edge2, "REMOVE_EDGE");
+ // Make another copy of this.
+ v1 = new_vert_from_pos(new_pos5);
+ v2 = new_vert_from_pos(clump_vert->geometry()->coords());
+ s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ new_edge3 = new EDGE(v1, v2, s, FORWARD);
+ add_named_att((ENTITY*)new_edge3, "REMOVE_EDGE");
+
+ // Create the edge going from the cur split to new_pos2.
+ v1 = new_vert_from_pos(new_pos2);
+ v2 = new_vert_from_pos(other_vert_pos);
+ new_edge4 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge4)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge4, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge4, new_ent);
+ new_edge4 = (EDGE*)new_ent;
+ // Create the edge going from the next split to new_pos3.
+ v1 = new_vert_from_pos(new_pos3);
+ v2 = new_vert_from_pos(next_other_pos);
+ new_edge5 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge5)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge5, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge5, new_ent);
+ new_edge5 = (EDGE*)new_ent;
+ // Create the edge going from new_pos4 to new_pos2.
+ v1 = new_vert_from_pos(new_pos4);
+ v2 = new_vert_from_pos(new_pos2);
+ new_edge6 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge6)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ face = this->find_keep_face(new_edge6, vert, dead_faces);
+ if(!face)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge6, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge6, new_ent);
+ new_edge6 = (EDGE*)new_ent;
+ // Create the edge going from new_pos1 to new_pos4.
+ v1 = new_vert_from_pos(new_pos1);
+ v2 = new_vert_from_pos(new_pos4);
+ new_edge7 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge7)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ face = this->find_keep_face(new_edge7, vert, dead_faces);
+ if(!face)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge7, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge7, new_ent);
+ new_edge7 = (EDGE*)new_ent;
+ // Create the edge going from new_pos1 to new_pos5.
+ v1 = new_vert_from_pos(new_pos1);
+ v2 = new_vert_from_pos(new_pos5);
+ new_edge9 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge9)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ face = this->find_keep_face(new_edge9, next_vert, dead_faces);
+ if(!face)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge9, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge9, new_ent);
+ new_edge9 = (EDGE*)new_ent;
+ // Create the edge going from new_pos3 to new_pos5.
+ v1 = new_vert_from_pos(new_pos3);
+ v2 = new_vert_from_pos(new_pos5);
+ new_edge10 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge10)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ face = this->find_keep_face(new_edge10, next_vert, dead_faces);
+ if(!face)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge10, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge10, new_ent);
+ new_edge10 = (EDGE*)new_ent;
+ v1 = new_vert_from_pos(other_vert_pos);
+ v2 = new_vert_from_pos(clump_vert->geometry()->coords());
+ s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ new_edge11 = new EDGE(v1, v2, s, FORWARD);
+ v1 = new_vert_from_pos(next_other_pos);
+ v2 = new_vert_from_pos(old_vertex_to_clump_map[next_vert]->new_vert->geometry()->coords());
+ s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ new_edge12 = new EDGE(v1, v2, s, FORWARD);
+ if(new_edge1 && new_edge6 && new_edge4 && new_edge11)
+ {
+ // Now create the new face.
+ DLIList<EDGE*> edges_for_new_face;
+ edges_for_new_face.append(new_edge1);
+ edges_for_new_face.append(new_edge11);
+ edges_for_new_face.append(new_edge4);
+ edges_for_new_face.append(new_edge6);
+ FACE* FACE_ptr = AcisModifyEngine::instance()->make_FACE(PLANE_SURFACE_TYPE, edges_for_new_face);
+ if(FACE_ptr)
+ {
+ new_vol_faces.append(FACE_ptr);
+ projected_positions.append(new_pos4);
+ projected_positions.append(new_pos2);
+ if(new_edge8 && new_edge7 && new_edge2 && new_edge9)
+ {
+ // Now create the new face.
+ DLIList<EDGE*> edges_for_new_face;
+ edges_for_new_face.append(new_edge8);
+ edges_for_new_face.append(new_edge2);
+ edges_for_new_face.append(new_edge9);
+ edges_for_new_face.append(new_edge7);
+ FACE* FACE_ptr = AcisModifyEngine::instance()->make_FACE(PLANE_SURFACE_TYPE, edges_for_new_face);
+ if(FACE_ptr)
+ {
+ new_vol_faces.append(FACE_ptr);
+ projected_positions.append(new_pos1);
+ projected_positions.append(new_pos5);
+ if(new_edge3 && new_edge5 && new_edge10 && new_edge12)
+ {
+ // Now create the new face.
+ DLIList<EDGE*> edges_for_new_face;
+ edges_for_new_face.append(new_edge3);
+ edges_for_new_face.append(new_edge5);
+ edges_for_new_face.append(new_edge10);
+ edges_for_new_face.append(new_edge12);
+ FACE* FACE_ptr = AcisModifyEngine::instance()->make_FACE(PLANE_SURFACE_TYPE, edges_for_new_face);
+ if(FACE_ptr)
+ {
+ new_vol_faces.append(FACE_ptr);
+ projected_positions.append(new_pos3);
+ }
+ else
+ {
+ PRINT_ERROR("Failed to build face from bounding curves.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to get all of the required edges for a new face.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to build face from bounding curves.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to get all of the required edges for a new face.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to build face from bounding curves.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to get all of the required edges for a new face.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // Add 4 new faces.
+ EDGE *new_edge1=NULL, *new_edge2=NULL, *new_edge3=NULL, *new_edge4=NULL, *new_edge5=NULL;
+ EDGE *new_edge6, *new_edge7, *new_edge8, *new_edge9, *new_edge10, *new_edge11, *new_edge12;
+ EDGE *new_edge13, *new_edge14, *new_edge15, *new_edge16;
+ SPAposition new_pos1, new_pos2, new_pos3, new_pos4, new_pos5, new_pos6, new_pos7;
+ SPAposition mid_pos((vert->geometry()->coords().x() + next_vert->geometry()->coords().x())/2.0,
+ (vert->geometry()->coords().y() + next_vert->geometry()->coords().y())/2.0,
+ (vert->geometry()->coords().z() + next_vert->geometry()->coords().z())/2.0);
+
+ // Project from the current vert into the face at an average direction.
+ SPAunit_vector cur_in_dir, next_in_dir, cur_other_in_dir, next_other_in_dir, mid_dir;
+ SPAunit_vector cur_mid_dir, next_mid_dir;
+ tangent_indir(face, edge, vert->geometry()->coords(), cur_in_dir);
+ tangent_indir(face, next_edge, next_vert->geometry()->coords(), next_in_dir);
+ tangent_indir(face, edge, other_vert_pos, cur_other_in_dir);
+ tangent_indir(face, next_edge, next_other_pos, next_other_in_dir);
+ mid_dir = normalise(normalise(next_vert->geometry()->coords() - next_other_pos) +
+ normalise(vert->geometry()->coords() - other_vert_pos));
+ cur_mid_dir = normalise(mid_dir + cur_in_dir);
+ next_mid_dir = normalise(mid_dir + next_in_dir);
+
+ double distance = backoff_distance;
+ tmp_pos = mid_pos + distance * mid_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos1);
+ int cntr = 0;
+ point_face_containment containment;
+ api_point_in_face(new_pos1, face, *(SPAtransf*)NULL_REF, containment);
+ // Try to make sure we have a point on the face.
+ while(containment == point_boundary_face && cntr++ < 10)
+ {
+ distance = (clump_vert->geometry()->coords()-new_pos1).len() / 2.0;
+ tmp_pos = mid_pos + distance * mid_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos1);
+ api_point_in_face(new_pos1, face, *(SPAtransf*)NULL_REF, containment);
+ }
+
+ distance = sqrt(2.0)*backoff_distance;
+ tmp_pos = vert->geometry()->coords() + distance*cur_mid_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos2);
+ cntr = 0;
+ api_point_in_face(new_pos2, face, *(SPAtransf*)NULL_REF, containment);
+ while(containment == point_boundary_face && cntr++ < 10)
+ {
+ distance = (clump_vert->geometry()->coords()-new_pos2).len() / 2.0;
+ tmp_pos = vert->geometry()->coords() + distance*cur_mid_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos2);
+ api_point_in_face(new_pos2, face, *(SPAtransf*)NULL_REF, containment);
+ }
+
+ distance = sqrt(2.0)*backoff_distance;
+ tmp_pos = next_vert->geometry()->coords() + distance*next_mid_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos3);
+ cntr = 0;
+ api_point_in_face(new_pos3, face, *(SPAtransf*)NULL_REF, containment);
+ while(containment == point_boundary_face && cntr++ < 10)
+ {
+ distance = (clump_vert->geometry()->coords()-new_pos3).len() / 2.0;
+ tmp_pos = next_vert->geometry()->coords() + distance*next_mid_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos3);
+ api_point_in_face(new_pos3, face, *(SPAtransf*)NULL_REF, containment);
+ }
+
+ distance = backoff_distance;
+ tmp_pos = vert->geometry()->coords() + distance*cur_in_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos4);
+ cntr = 0;
+ api_point_in_face(new_pos4, face, *(SPAtransf*)NULL_REF, containment);
+ while(containment == point_boundary_face && cntr++ < 10)
+ {
+ distance = (vert->geometry()->coords()-new_pos4).len() / 2.0;
+ tmp_pos = vert->geometry()->coords() + distance*cur_in_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos4);
+ api_point_in_face(new_pos4, face, *(SPAtransf*)NULL_REF, containment);
+ }
+
+ distance = backoff_distance;
+ tmp_pos = next_vert->geometry()->coords() + distance*next_in_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos5);
+ cntr = 0;
+ api_point_in_face(new_pos5, face, *(SPAtransf*)NULL_REF, containment);
+ while(containment == point_boundary_face && cntr++ < 10)
+ {
+ distance = (next_vert->geometry()->coords()-new_pos5).len() / 2.0;
+ tmp_pos = next_vert->geometry()->coords() + distance*next_in_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos5);
+ api_point_in_face(new_pos5, face, *(SPAtransf*)NULL_REF, containment);
+ }
+
+ distance = backoff_distance;
+ tmp_pos = next_other_pos + distance*next_other_in_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos6);
+ cntr = 0;
+ api_point_in_face(new_pos6, face, *(SPAtransf*)NULL_REF, containment);
+ while(containment == point_boundary_face && cntr++ < 10)
+ {
+ distance = (next_other_pos-new_pos6).len() / 2.0;
+ tmp_pos = next_other_pos + distance*next_other_in_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos6);
+ api_point_in_face(new_pos6, face, *(SPAtransf*)NULL_REF, containment);
+ }
+
+ distance = backoff_distance;
+ tmp_pos = other_vert_pos + distance*cur_other_in_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos7);
+ cntr = 0;
+ api_point_in_face(new_pos7, face, *(SPAtransf*)NULL_REF, containment);
+ while(containment == point_boundary_face && cntr++ < 10)
+ {
+ distance = (other_vert_pos-new_pos7).len() / 2.0;
+ tmp_pos = other_vert_pos + distance*cur_other_in_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos7);
+ api_point_in_face(new_pos7, face, *(SPAtransf*)NULL_REF, containment);
+ }
+
+ // Create the edge going from the new clump vert to new_pos4.
+ VERTEX *v1 = new_vert_from_pos(new_pos4);
+ VERTEX *v2 = new_vert_from_pos(clump_vert->geometry()->coords());
+ STRAIGHT *s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ new_edge1 = new EDGE(v1, v2, s, FORWARD);
+ add_named_att((ENTITY*)new_edge1, "REMOVE_EDGE");
+ // Make another copy of this.
+ api_copy_entity_contents((ENTITY*)new_edge1, new_ent);
+ new_edge2 = (EDGE*)new_ent;
+ // Create the edge going from the new clump vert to new_pos1.
+ v1 = new_vert_from_pos(new_pos1);
+ v2 = new_vert_from_pos(clump_vert->geometry()->coords());
+ s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ new_edge3 = new EDGE(v1, v2, s, FORWARD);
+ add_named_att((ENTITY*)new_edge3, "REMOVE_EDGE");
+ // Make another copy of this.
+ api_copy_entity_contents((ENTITY*)new_edge3, new_ent);
+ new_edge4 = (EDGE*)new_ent;
+ // Create the edge going from the new clump vert to new_pos5.
+ v1 = new_vert_from_pos(new_pos5);
+ v2 = new_vert_from_pos(clump_vert->geometry()->coords());
+ s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ new_edge5 = new EDGE(v1, v2, s, FORWARD);
+ add_named_att((ENTITY*)new_edge5, "REMOVE_EDGE");
+ // Make another copy of this.
+ api_copy_entity_contents((ENTITY*)new_edge5, new_ent);
+ new_edge6 = (EDGE*)new_ent;
+
+ // Create the edge going from the cur split to new_pos7.
+ v1 = new_vert_from_pos(new_pos7);
+ v2 = new_vert_from_pos(other_vert_pos);
+ new_edge7 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge7)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge7, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge7, new_ent);
+ new_edge7 = (EDGE*)new_ent;
+ // Create the edge going from the next split to new_pos6.
+ v1 = new_vert_from_pos(new_pos6);
+ v2 = new_vert_from_pos(next_other_pos);
+ new_edge8 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge8)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge8, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge8, new_ent);
+ new_edge8 = (EDGE*)new_ent;
+ // Create the edge going from new_pos4 to new_pos7.
+ v1 = new_vert_from_pos(new_pos4);
+ v2 = new_vert_from_pos(new_pos7);
+ new_edge9 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge9)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ face = this->find_keep_face(new_edge9, vert, dead_faces);
+ if(!face)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge9, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge9, new_ent);
+ new_edge9 = (EDGE*)new_ent;
+ // Create the edge going from new_pos2 to new_pos4.
+ v1 = new_vert_from_pos(new_pos2);
+ v2 = new_vert_from_pos(new_pos4);
+ new_edge10 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge10)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge10, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge10, new_ent);
+ new_edge10 = (EDGE*)new_ent;
+ // Create the edge going from new_pos1 to new_pos2.
+ v1 = new_vert_from_pos(new_pos1);
+ v2 = new_vert_from_pos(new_pos2);
+ new_edge11 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge11)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ face = this->find_keep_face(new_edge11, vert, dead_faces);
+ if(!face)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge11, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge11, new_ent);
+ new_edge11 = (EDGE*)new_ent;
+ // Create the edge going from new_pos1 to new_pos3.
+ v1 = new_vert_from_pos(new_pos1);
+ v2 = new_vert_from_pos(new_pos3);
+ new_edge12 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge12)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge12, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge12, new_ent);
+ new_edge12 = (EDGE*)new_ent;
+ // Create the edge going from new_pos3 to new_pos5.
+ v1 = new_vert_from_pos(new_pos3);
+ v2 = new_vert_from_pos(new_pos5);
+ new_edge13 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge13)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ face = this->find_keep_face(new_edge13, next_vert, dead_faces);
+ if(!face)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge13, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge13, new_ent);
+ new_edge13 = (EDGE*)new_ent;
+ // Create the edge going from new_pos6 to new_pos5.
+ v1 = new_vert_from_pos(new_pos6);
+ v2 = new_vert_from_pos(new_pos5);
+ new_edge14 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge14)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ face = this->find_keep_face(new_edge14, next_vert, dead_faces);
+ if(!face)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge14, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge14, new_ent);
+ new_edge14 = (EDGE*)new_ent;
+ v1 = new_vert_from_pos(other_vert_pos);
+ v2 = new_vert_from_pos(clump_vert->geometry()->coords());
+ s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ new_edge15 = new EDGE(v1, v2, s, FORWARD);
+ v1 = new_vert_from_pos(next_other_pos);
+ v2 = new_vert_from_pos(old_vertex_to_clump_map[next_vert]->new_vert->geometry()->coords());
+ s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ new_edge16 = new EDGE(v1, v2, s, FORWARD);
+ if(new_edge1 && new_edge7 && new_edge9 && new_edge15)
+ {
+ // Now create the new face.
+ DLIList<EDGE*> edges_for_new_face;
+ edges_for_new_face.append(new_edge1);
+ edges_for_new_face.append(new_edge15);
+ edges_for_new_face.append(new_edge7);
+ edges_for_new_face.append(new_edge9);
+ FACE* FACE_ptr = AcisModifyEngine::instance()->make_FACE(PLANE_SURFACE_TYPE, edges_for_new_face);
+ if(FACE_ptr)
+ {
+ new_vol_faces.append(FACE_ptr);
+ projected_positions.append(new_pos4);
+ projected_positions.append(new_pos7);
+ if(new_edge2 && new_edge3 && new_edge10 && new_edge11)
+ {
+ // Now create the new face.
+ DLIList<EDGE*> edges_for_new_face;
+ edges_for_new_face.append(new_edge2);
+ edges_for_new_face.append(new_edge3);
+ edges_for_new_face.append(new_edge10);
+ edges_for_new_face.append(new_edge11);
+ FACE* FACE_ptr = AcisModifyEngine::instance()->make_FACE(PLANE_SURFACE_TYPE, edges_for_new_face);
+ if(FACE_ptr)
+ {
+ new_vol_faces.append(FACE_ptr);
+ projected_positions.append(new_pos2);
+ projected_positions.append(new_pos1);
+ if(new_edge4 && new_edge5 && new_edge12 && new_edge13)
+ {
+ // Now create the new face.
+ DLIList<EDGE*> edges_for_new_face;
+ edges_for_new_face.append(new_edge4);
+ edges_for_new_face.append(new_edge5);
+ edges_for_new_face.append(new_edge12);
+ edges_for_new_face.append(new_edge13);
+ FACE* FACE_ptr = AcisModifyEngine::instance()->make_FACE(PLANE_SURFACE_TYPE, edges_for_new_face);
+ if(FACE_ptr)
+ {
+ new_vol_faces.append(FACE_ptr);
+ projected_positions.append(new_pos3);
+ projected_positions.append(new_pos5);
+ if(new_edge6 && new_edge8 && new_edge14 && new_edge16)
+ {
+ // Now create the new face.
+ DLIList<EDGE*> edges_for_new_face;
+ edges_for_new_face.append(new_edge6);
+ edges_for_new_face.append(new_edge8);
+ edges_for_new_face.append(new_edge14);
+ edges_for_new_face.append(new_edge16);
+ FACE* FACE_ptr = AcisModifyEngine::instance()->make_FACE(PLANE_SURFACE_TYPE, edges_for_new_face);
+ if(FACE_ptr)
+ {
+ new_vol_faces.append(FACE_ptr);
+ projected_positions.append(new_pos6);
+ }
+ else
+ {
+ PRINT_ERROR("Failed to build face from bounding curves.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to get all of the required edges for a new face.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to build face from bounding curves.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to get all of the required edges for a new face.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to build face from bounding curves.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to get all of the required edges for a new face.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to build face from bounding curves.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to get all of the required edges for a new face.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ ret = CUBIT_FAILURE;
+ }
+ return ret;
+}
+
+EDGE* AcisTopologyTool::get_other_edge(EDGE *edge, VERTEX *vert, FACE *face)
+{
+ ENTITY_LIST face_edges;
+ api_get_edges((ENTITY*)face, face_edges);
+ face_edges.init();
+ ENTITY *tmp_ent;
+ EDGE *other_edge = NULL;
+ while((tmp_ent = face_edges.next()) && !other_edge)
+ {
+ if(tmp_ent != edge)
+ {
+ ENTITY_LIST edge_verts;
+ api_get_vertices(tmp_ent, edge_verts);
+ ENTITY *tmp_ent2;
+ edge_verts.init();
+ while((tmp_ent2 = edge_verts.next()) && !other_edge)
+ {
+ if(tmp_ent2 == vert)
+ other_edge = (EDGE*)tmp_ent;
+ }
+ }
+ }
+ return other_edge;
+}
+
+VERTEX* AcisTopologyTool::other_vertex(EDGE *edge, VERTEX *vert)
+{
+ VERTEX *other_vert = NULL;
+ if(edge->start() == edge->end())
+ {
+ }
+ else
+ {
+ if(edge->start() == vert)
+ other_vert = edge->end();
+ else
+ other_vert = edge->start();
+ }
+ return other_vert;
+}
+
+void AcisTopologyTool::get_next_edge_around_clump(EDGE *cur_edge, VERTEX *cur_vert,
+ FACE *cur_face,
+ std::map <VERTEX*, VERTEXClump*, mapltid> &old_vertex_to_clump_map,
+ EDGE *&next_edge, VERTEX *&next_vert)
+{
+ next_edge = NULL;
+ next_vert = NULL;
+
+ if(cur_edge && cur_vert && cur_face)
+ {
+ EDGE *tmp_edge = get_other_edge(cur_edge, cur_vert, cur_face);
+ if(tmp_edge)
+ {
+ VERTEX *tmp_vert = cur_vert;
+ while(edge_within_clump(tmp_edge, old_vertex_to_clump_map))
+ {
+ tmp_vert = other_vertex(tmp_edge, tmp_vert);
+ tmp_edge = get_other_edge(tmp_edge, tmp_vert, cur_face);
+ }
+ next_edge = tmp_edge;
+ next_vert = tmp_vert;
+ }
+ }
+}
+
+double AcisTopologyTool::angle_between(FACE *face, EDGE *e1, VERTEX *v1,
+ EDGE *e2, VERTEX *v2)
+{
+ double angle = 0.0;
+ SPAposition clos;
+ SPAunit_vector norm1, norm2;
+ SPAunit_vector tan1_norm, tan2_norm;
+ EDGE *cur_edge, *next_edge;
+ VERTEX *cur_vert, *next_vert;
+
+ CubitVector prev_tan;
+ cur_edge = e1;
+ cur_vert = v1;
+ while(cur_edge != e2)
+ {
+ ENTITY_LIST vert_edges;
+ api_get_edges((ENTITY*)cur_vert, vert_edges);
+ vert_edges.remove(cur_edge);
+ next_edge = NULL;
+ vert_edges.init();
+ ENTITY *tmp_ent;
+ // Find the next edge in the face (and next vert)
+ while((tmp_ent = vert_edges.next()) && !next_edge)
+ {
+ ENTITY_LIST edge_faces;
+ api_get_faces(tmp_ent, edge_faces);
+ if(edge_faces.lookup(face) != -1)
+ {
+ next_edge = (EDGE*)tmp_ent;
+ if(next_edge->start() == cur_vert)
+ next_vert = next_edge->end();
+ else
+ next_vert = next_edge->start();
+ }
+ }
+ SPAvector tan1, tan2;
+ if(cur_vert == cur_edge->start())
+ tan1 = cur_edge->start_deriv();
+ else
+ tan1 = -(cur_edge->end_deriv());
+ if(cur_vert == next_edge->start())
+ tan2 = next_edge->start_deriv();
+ else
+ tan2 = -(next_edge->end_deriv());
+ tan1_norm = normalise(tan1);
+ tan2_norm = normalise(tan2);
+ face->geometry()->equation().point_perp(cur_vert->geometry()->coords(), clos, norm1);
+ if(face->sense() == REVERSED)
+ norm1 = -norm1;
+
+ SPAvector ave_norm = normalise(norm1);
+
+ CubitVector cub_ave_norm(ave_norm.x(), ave_norm.y(), ave_norm.z());
+ CubitVector cub_tan1(tan1_norm.x(), tan1_norm.y(), tan1_norm.z());
+ CubitVector cub_tan2(tan2_norm.x(), tan2_norm.y(), tan2_norm.z());
+
+ double cur_angle;
+ COEDGE *co1 = cur_edge->coedge(face);
+ if(co1->end() == cur_vert)
+ cur_angle = cub_ave_norm.vector_angle(cub_tan2, cub_tan1);
+ else
+ cur_angle = cub_ave_norm.vector_angle(cub_tan1, cub_tan2);
+
+ // Get the angle that this curve has gone through from
+ // one end to another.
+ if(cur_edge != e1)
+ {
+ CubitVector temp_tan1 = -cub_tan1;
+ double dot = temp_tan1 % prev_tan;
+ if(dot < -1.0)
+ dot = -1.0;
+ else if(dot > 1.0)
+ dot = 1.0;
+ double temp_angle = acos(dot);
+ //temp_angle = cub_ave_norm.vector_angle(prev_tan, temp_tan1);
+ angle += temp_angle;
+ }
+
+ prev_tan = cub_tan2;
+
+ if(cur_angle == 0.0)
+ {
+ double dist = 10.0 * GEOMETRY_RESABS;
+ SPAposition test_pos = next_vert->geometry()->coords() - dist * tan2_norm;
+ SPApar_pos uv;
+ face->geometry()->equation().point_perp(test_pos, clos, *(SPApar_pos*)NULL_REF, uv);
+ point_face_containment containment;
+ api_point_in_face(clos, face, *(SPAtransf*)NULL_REF, containment, uv);
+ if(containment == point_inside_face)
+ cur_angle = 2.0*CUBIT_PI;
+ }
+
+ angle += cur_angle;
+ // For each time we set cur_edge equal to next_edge and
+ // traverse around we need to subtract PI to get the
+ // correct angle in the end.
+ if(cur_edge != e1)
+ angle -= CUBIT_PI;
+
+ cur_edge = next_edge;
+ cur_vert = next_vert;
+ }
+
+ return angle;
+}
+
+void AcisTopologyTool::tangent_indir( FACE *FACE_ptr, EDGE *EDGE_ptr,
+ const SPAposition &acis_pos, SPAunit_vector &in_dir )
+{
+ // Get the normal to the FACE at the position
+ SPAposition acis_pos_on_surf;
+ SPAunit_vector acis_face_norm;
+ (FACE_ptr->geometry()->equation()).point_perp( acis_pos,
+ acis_pos_on_surf, acis_face_norm );
+
+ // Adjust for the FACE sense
+ if( FACE_ptr->sense() == REVERSED )
+ acis_face_norm = -acis_face_norm;
+
+ // Get a vector tangent to the EDGE, adjusted for the EDGE sense on the FACE
+ SPAunit_vector acis_tangent_vec = (EDGE_ptr->geometry()->equation()).
+ point_direction( acis_pos );
+ if( EDGE_ptr->sense() == REVERSED )
+ acis_tangent_vec = -acis_tangent_vec;
+
+ COEDGE *COEDGE_ptr = EDGE_ptr->coedge( FACE_ptr );
+ if( COEDGE_ptr->sense() == REVERSED )
+ acis_tangent_vec = -acis_tangent_vec;
+
+ SPAvector tangent_indir = acis_tangent_vec * acis_face_norm;
+ in_dir = normalise(-tangent_indir);
+}
+
+EDGE* AcisTopologyTool::imprint_new_edge_on_face(FACE *face, VERTEX *v1,
+ VERTEX *v2)
+{
+ EDGE *ret_edge = NULL;
+ double tol = GEOMETRY_RESABS*GEOMETRY_RESABS;
+ SPAposition clos;
+ SPAunit_vector norm;
+ face->geometry()->equation().point_perp(v1->geometry()->coords(), clos, norm);
+ SPAvector edge0 = v2->geometry()->coords() - v1->geometry()->coords();
+ SPAvector edge1 = norm;
+ SPAvector plane_normal = edge0 * edge1;
+ SPAunit_vector plane_normal_normalized = normalise(plane_normal);
+ CubitVector plane_norm(plane_normal_normalized.x(), plane_normal_normalized.y(), plane_normal_normalized.z());
+ STRAIGHT *s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ EDGE *edge = new EDGE(v1, v2, s, FORWARD);
+ EDGE *new_edge = AcisModifyEngine::instance()->project_EDGE(edge, face);
+ if(new_edge)
+ {
+ ENTITY *body;
+ api_get_owner((ENTITY*)face, body);
+ ENTITY_LIST body_edges_before;
+ api_get_edges(body, body_edges_before);
+ DLIList<TopologyBridge*> temporary_bridges;
+ AcisModifyEngine::instance()->imprint((BODY*)body, face, new_edge, temporary_bridges);
+ temporary_bridges.uniquify_ordered();
+ while(temporary_bridges.size())
+ delete temporary_bridges.pop();
+ ENTITY_LIST body_edges_after;
+ api_get_edges(body, body_edges_after);
+ ENTITY *tmp_ent;
+ body_edges_after.remove(body_edges_before);
+ body_edges_after.init();
+ if(body_edges_after.iteration_count() == 1)
+ ret_edge = (EDGE*)body_edges_after.next();
+ else
+ {
+ while((tmp_ent = body_edges_after.next()) && !new_edge)
+ {
+ EDGE *cur_edge = (EDGE*)tmp_ent;
+ if((cur_edge->start_pos()-v1->geometry()->coords()).len_sq() < tol)
+ {
+ if((cur_edge->end_pos()-v2->geometry()->coords()).len_sq() < tol)
+ ret_edge = cur_edge;
+ }
+ else if((cur_edge->start_pos()-v2->geometry()->coords()).len_sq() < tol)
+ {
+ if((cur_edge->end_pos()-v1->geometry()->coords()).len_sq() < tol)
+ ret_edge = cur_edge;
+ }
+ }
+ }
+ }
+
+ return ret_edge;
+}
+
+FACE* AcisTopologyTool::find_keep_face(EDGE *edge,
+ VERTEX *vert,
+ DLIList<FACE*> &dead_faces)
+{
+ FACE *keep_face = NULL;
+ ENTITY_LIST edge_faces;
+ api_get_faces((ENTITY*)edge, edge_faces);
+ edge_faces.init();
+ if(edge_faces.count() == 1)
+ keep_face = (FACE*)edge_faces.next();
+ else if(edge_faces.count() == 2)
+ {
+ ENTITY *cur_face = edge_faces.next();
+ ENTITY_LIST tmp_verts;
+ api_get_vertices(cur_face, tmp_verts);
+ if(tmp_verts.lookup(vert) != -1)
+ {
+ keep_face = (FACE*)edge_faces.next();
+ dead_faces.append((FACE*)cur_face);
+ }
+ else
+ {
+ keep_face = (FACE*)cur_face;
+ dead_faces.append((FACE*)edge_faces.next());
+ }
+ }
+ else
+ PRINT_ERROR("Unexpected number of faces after split.\n");
+
+ if(!keep_face)
+ PRINT_ERROR("Failed to find the face to keep after imprinting.\n");
+
+ return keep_face;
+}
+
+VERTEX* AcisTopologyTool::new_vert_from_pos(const SPAposition &pos)
+{
+ APOINT *p = new APOINT(pos);
+ return new VERTEX(p);
+}
+
+CubitStatus AcisTopologyTool::generate_faces_for_lateral_edge(FACE *&face, EDGE *edge,
+ double &backoff_distance,
+ std::map <VERTEX*, VERTEXClump*, mapltid> &old_vertex_to_clump_map,
+ std::map <EDGE*, EDGE*, mapltid> &old_edge_to_new_edge_map,
+ DLIList<VERTEX*> &processed_verts,
+ DLIList<EDGE*> &processed_edges,
+ DLIList<EDGE*> &edges_to_imprint,
+ DLIList<FACE*> &new_vol_faces,
+ DLIList<FACE*> &dead_faces,
+ DLIList<SPAposition> &projected_positions)
+{
+ CubitStatus ret = CUBIT_SUCCESS;
+ int i;
+ int d, num_divisions = 5;
+ double start, end;
+ DLIList<EDGE*> new_face_edges;
+ DLIList<VERTEX*> edge_verts;
+ ENTITY *new_entity;
+ ENTITY *new_ent;
+ SPAunit_vector cur_dir, other_dir;
+ EDGE *next_edge;
+ VERTEX *next_vert;
+ DLIList<VERTEX*> split_verts;
+
+ processed_edges.append(edge);
+ // Put these in the list manually to make sure we go from the
+ // beginning of the edge to the end. This is the direction
+ // we assume below when stepping along the edge generating
+ // points for the slitting curve.
+ edge_verts.append(edge->start());
+ edge_verts.append(edge->end());
+ // Add the new edge corresponding to this old edge to the list of
+ // edges that will make up the new face.
+ api_copy_entity_contents((ENTITY*)old_edge_to_new_edge_map[edge], new_entity);
+ new_face_edges.append((EDGE*)new_entity);
+ // Make sure we do the start vertex first.
+ edge_verts.reset();
+ for(i=edge_verts.size(); i && ret == CUBIT_SUCCESS; i--)
+ {
+ VERTEX *vert = edge_verts.get_and_step();
+ EDGE *side_edge = NULL;
+ // Build any extra faces that are needed
+ // at the vertex
+ if(!processed_verts.is_in_list(vert))
+ {
+ get_next_edge_around_clump(edge, vert, face,
+ old_vertex_to_clump_map, next_edge, next_vert);
+ if(next_edge && next_vert)
+ {
+ double angle = this->angle_between(face, edge, vert, next_edge, next_vert);
+ if(!is_lateral_edge(next_edge, old_edge_to_new_edge_map))
+ {
+ processed_edges.append(next_edge);
+ processed_verts.append(vert);
+ if(angle <= three_pi_over_four)
+ {
+ // Just use the split point on the next edge
+ // to finish off this new face.
+ SPAposition other_vert_pos = other_vertex(next_edge, next_vert)->geometry()->coords();
+ VERTEXClump *clump = old_vertex_to_clump_map[vert];
+ VERTEX *vert1 = new_vert_from_pos(other_vert_pos);
+ VERTEX *vert2 = new_vert_from_pos(clump->new_vert->geometry()->coords());
+ STRAIGHT *s = new STRAIGHT(vert1->geometry()->coords(), normalise(vert2->geometry()->coords() - vert1->geometry()->coords()));
+ side_edge = new EDGE(vert1, vert2, s, FORWARD);
+ split_verts.append(vert1);
+ }
+ else if(angle <= five_pi_over_four)
+ {
+ // Introduce one extra face in addition to
+ // the new face we are constructing. This will require making
+ // 3 new edges. This will require projecting two new positions
+ // into the face.
+ VERTEX *vert1, *vert2, *vert3, *vert4;
+ EDGE *new_edge1, *new_edge2=NULL, *new_edge3=NULL, *new_edge4;
+ SPAposition new_pos1, new_pos2, split_pos_on_surf, tmp_pos;
+
+ SPAposition other_vert_pos = other_vertex(next_edge, next_vert)->geometry()->coords();
+ // Make the first new edge. This will be the edge going into the
+ // current face and separating the new face associated with the
+ // lateral (current) edge and the new face next to it linking up to the
+ // non-lateral edge.
+ tangent_indir(face, edge, vert->geometry()->coords(), cur_dir);
+ tangent_indir(face, next_edge, next_vert->geometry()->coords(), other_dir);
+ SPAvector ave_dir = cur_dir + other_dir;
+ SPAvector ave_dir_norm = normalise(ave_dir);
+ angle /= 2.0;
+ double distance = backoff_distance/sin(angle);
+ tmp_pos = vert->geometry()->coords() + distance * ave_dir_norm;
+ face->geometry()->equation().point_perp(tmp_pos, new_pos1);
+ // Now that we have the location of the new position projected into
+ // the face we will create the first new edge.
+ vert1 = new_vert_from_pos(new_pos1);
+ vert2 = new_vert_from_pos(old_vertex_to_clump_map[vert]->new_vert->geometry()->coords());
+ STRAIGHT *s = new STRAIGHT(vert1->geometry()->coords(), normalise(vert2->geometry()->coords() - vert1->geometry()->coords()));
+ new_edge1 = new EDGE(vert1, vert2, s, FORWARD);
+ // Create a new split edge associated with this new edge. It will be used below for
+ // building the new face associated with the lateral (current) edge.
+ add_named_att((ENTITY*)new_edge1, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge1, new_ent);
+ side_edge = (EDGE*)new_ent;
+ api_copy_entity_contents((ENTITY*)vert1, new_ent);
+ split_verts.append((VERTEX*)new_ent);
+ // Now create the second new edge we will need. This will be an edge projected
+ // into the face from the split position on the non-lateral edge. We won't create
+ // a split associated with it because it should never need to be retrieved later
+ // since we are processing the non-lateral edge at this time.
+ tangent_indir(face, next_edge, other_vert_pos, other_dir);
+ tmp_pos = other_vert_pos + backoff_distance*other_dir;
+ face->geometry()->equation().point_perp(tmp_pos, new_pos2);
+ vert3 = new_vert_from_pos(new_pos2);
+ vert4 = new_vert_from_pos(other_vert_pos);
+ new_edge2 = imprint_new_edge_on_face(face, vert3, vert4);
+ if(!new_edge2)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge2, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge2, new_ent);
+ new_edge2 = (EDGE*)new_ent;
+ // Now create the third new edge which will connect the two new edges we
+ // just created.
+ new_edge3 = imprint_new_edge_on_face(face, vert1, vert3);
+ if(!new_edge3)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ face = this->find_keep_face(new_edge3, vert, dead_faces);
+ if(!face)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge3, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge3, new_ent);
+ new_edge3 = (EDGE*)new_ent;
+ VERTEX *tmp_vert1 = new_vert_from_pos(other_vert_pos);
+ VERTEX *tmp_vert2 = new_vert_from_pos(old_vertex_to_clump_map[vert]->new_vert->geometry()->coords());
+ s = new STRAIGHT(tmp_vert1->geometry()->coords(), normalise(tmp_vert2->geometry()->coords() - tmp_vert1->geometry()->coords()));
+ new_edge4 = new EDGE(tmp_vert1, tmp_vert2, s, FORWARD);
+
+ if(new_edge1 && new_edge2 && new_edge3 && new_edge4)
+ {
+ DLIList<EDGE*> edge_list;
+ edge_list.append(new_edge1);
+ edge_list.append(new_edge3);
+ edge_list.append(new_edge2);
+ edge_list.append(new_edge4);
+ FACE* FACE_ptr = AcisModifyEngine::instance()->make_FACE(PLANE_SURFACE_TYPE, edge_list) ;
+ if(FACE_ptr)
+ {
+ new_vol_faces.append(FACE_ptr);
+ projected_positions.append(new_pos1);
+ projected_positions.append(new_pos2);
+ }
+ else
+ {
+ PRINT_ERROR("Failed to build face from bounding curves.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to get all of the new edges needed for new face.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ }
+ }
+ }
+ else if(angle <= seven_pi_over_four)
+ {
+ // Introduce two extra faces in addition to
+ // the new face we are constructing.
+ VERTEX *vert1, *vert2;
+ EDGE *new_edge1, *new_edge2, *new_edge3, *new_edge4;
+ EDGE *new_edge5, *new_edge6, *new_edge7, *new_edge8;
+ SPAposition new_pos1, new_pos2, new_pos3, new_pos4, tmp_pos;
+
+ SPAposition next_other_pos = other_vertex(next_edge, next_vert)->geometry()->coords();
+ // Make the first new edge. This will be the edge going into the
+ // current face and separating the new face associated with the
+ // lateral (current) edge and the new face next to it linking up to the
+ // non-lateral edge.
+ SPAunit_vector cur_in_dir, next_in_dir, next_other_in_dir;
+ tangent_indir(face, edge, vert->geometry()->coords(), cur_in_dir);
+ tangent_indir(face, next_edge, next_vert->geometry()->coords(), next_in_dir);
+ tangent_indir(face, next_edge, next_other_pos, next_other_in_dir);
+ SPAunit_vector ave_dir = normalise(cur_in_dir + next_in_dir);
+ angle /= 2.0;
+ double distance = backoff_distance/sin(angle);
+ SPAposition mid_pos((vert->geometry()->coords().x() + next_vert->geometry()->coords().x())/2.0,
+ (vert->geometry()->coords().y() + next_vert->geometry()->coords().y())/2.0,
+ (vert->geometry()->coords().z() + next_vert->geometry()->coords().z())/2.0);
+ // Create the 4 new positions needed.
+ tmp_pos = mid_pos + distance * ave_dir;
+ face->geometry()->equation().point_perp(tmp_pos, new_pos1);
+ tmp_pos = vert->geometry()->coords() + backoff_distance * cur_in_dir;
+ face->geometry()->equation().point_perp(tmp_pos, new_pos2);
+ tmp_pos = next_vert->geometry()->coords() + backoff_distance * next_in_dir;
+ face->geometry()->equation().point_perp(tmp_pos, new_pos3);
+ tmp_pos = next_other_pos + backoff_distance * next_other_in_dir;
+ face->geometry()->equation().point_perp(tmp_pos, new_pos4);
+
+ // Create the edge that will close off the face associated with the lateral
+ // edge.
+ vert1 = new_vert_from_pos(new_pos2);
+ vert2 = new_vert_from_pos(old_vertex_to_clump_map[vert]->new_vert->geometry()->coords());
+ STRAIGHT *s = new STRAIGHT(vert1->geometry()->coords(), normalise(vert2->geometry()->coords() - vert1->geometry()->coords()));
+ new_edge1 = new EDGE(vert1, vert2, s, FORWARD);
+ add_named_att((ENTITY*)new_edge1, "REMOVE_EDGE");
+ // Make a copy of this edge. It will be used below for
+ // building the new face associated with the lateral (current) edge.
+ api_copy_entity_contents((ENTITY*)new_edge1, new_ent);
+ side_edge = (EDGE*)new_ent;
+ // Keep track of this vertex.
+ api_copy_entity_contents((ENTITY*)vert1, new_ent);
+ split_verts.append((VERTEX*)new_ent);
+ // Create next new edge.
+ vert1 = new_vert_from_pos(new_pos3);
+ vert2 = new_vert_from_pos(old_vertex_to_clump_map[vert]->new_vert->geometry()->coords());
+ s = new STRAIGHT(vert1->geometry()->coords(), normalise(vert2->geometry()->coords() - vert1->geometry()->coords()));
+ new_edge2 = new EDGE(vert1, vert2, s, FORWARD);
+ if(!new_edge2)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge2, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge2, new_ent);
+ new_edge3 = (EDGE*)new_ent;
+ // Create next edge.
+ vert1 = new_vert_from_pos(new_pos4);
+ vert2 = new_vert_from_pos(next_other_pos);
+ new_edge4 = imprint_new_edge_on_face(face, vert1, vert2);
+ if(!new_edge4)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge4, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge4, new_ent);
+ new_edge4 = (EDGE*)new_ent;
+ vert1 = new_vert_from_pos(new_pos4);
+ vert2 = new_vert_from_pos(new_pos3);
+ new_edge5 = imprint_new_edge_on_face(face, vert1, vert2);
+ if(!new_edge5)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ face = this->find_keep_face(new_edge5, next_vert, dead_faces);
+ if(!face)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge5, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge5, new_ent);
+ new_edge5 = (EDGE*)new_ent;
+ vert1 = new_vert_from_pos(new_pos1);
+ vert2 = new_vert_from_pos(new_pos3);
+ new_edge6 = imprint_new_edge_on_face(face, vert1, vert2);
+ if(!new_edge6)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ face = this->find_keep_face(new_edge6, vert, dead_faces);
+ if(!face)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge6, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge6, new_ent);
+ new_edge6 = (EDGE*)new_ent;
+ vert1 = new_vert_from_pos(new_pos1);
+ vert2 = new_vert_from_pos(new_pos2);
+ new_edge7 = imprint_new_edge_on_face(face, vert1, vert2);
+ if(!new_edge7)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ face = this->find_keep_face(new_edge7, vert, dead_faces);
+ if(!face)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge7, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge7, new_ent);
+ new_edge7 = (EDGE*)new_ent;
+ vert1 = new_vert_from_pos(next_other_pos);
+ vert2 = new_vert_from_pos(old_vertex_to_clump_map[next_vert]->new_vert->geometry()->coords());
+ s = new STRAIGHT(vert1->geometry()->coords(), normalise(vert2->geometry()->coords() - vert1->geometry()->coords()));
+ new_edge8 = new EDGE(vert1, vert2, s, FORWARD);
+ if(!new_edge8)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ if(new_edge4 && new_edge8 && new_edge5 && new_edge2)
+ {
+ DLIList<EDGE*> edge_list;
+ edge_list.append(new_edge2);
+ edge_list.append(new_edge5);
+ edge_list.append(new_edge8);
+ edge_list.append(new_edge4);
+ FACE* FACE_ptr = AcisModifyEngine::instance()->make_FACE(PLANE_SURFACE_TYPE, edge_list) ;
+ if(FACE_ptr)
+ {
+ new_vol_faces.append(FACE_ptr);
+ projected_positions.append(new_pos3);
+ projected_positions.append(new_pos4);
+ if(new_edge3 && new_edge6 && new_edge7 && new_edge1)
+ {
+ DLIList<EDGE*> edge_list;
+ edge_list.append(new_edge3);
+ edge_list.append(new_edge6);
+ edge_list.append(new_edge7);
+ edge_list.append(new_edge1);
+ FACE* FACE_ptr = AcisModifyEngine::instance()->make_FACE(PLANE_SURFACE_TYPE, edge_list) ;
+ if(FACE_ptr)
+ {
+ new_vol_faces.append(FACE_ptr);
+ projected_positions.append(new_pos1);
+ projected_positions.append(new_pos2);
+ }
+ else
+ {
+ PRINT_ERROR("Failed to build face from bounding curves.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to get all of the new edges needed for new face.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to build face from bounding curves.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to get all of the new edges needed for new face.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // Add 4 new faces.
+ EDGE *new_edge1, *new_edge3, *new_edge4, *new_edge5;
+ EDGE *new_edge6, *new_edge8, *new_edge10, *new_edge11, *new_edge12;
+ EDGE *new_edge13, *new_edge14, *new_edge16;
+ SPAposition new_pos1, new_pos2, new_pos3, new_pos4, new_pos5, new_pos6;
+
+ SPAposition next_other_pos = other_vertex(next_edge, next_vert)->geometry()->coords();
+ SPAposition cur_other_vert_pos = other_vertex(edge, vert)->geometry()->coords();
+ // Project from the current vert into the face at an average direction.
+ SPAunit_vector cur_in_dir, next_in_dir, next_other_in_dir, mid_dir;
+ SPAunit_vector cur_mid_dir, next_mid_dir;
+ tangent_indir(face, edge, vert->geometry()->coords(), cur_in_dir);
+ tangent_indir(face, next_edge, next_vert->geometry()->coords(), next_in_dir);
+ tangent_indir(face, next_edge, next_other_pos, next_other_in_dir);
+ mid_dir = normalise(normalise(next_vert->geometry()->coords() - next_other_pos) +
+ normalise(vert->geometry()->coords() - cur_other_vert_pos));
+ cur_mid_dir = normalise(mid_dir + cur_in_dir);
+ next_mid_dir = normalise(mid_dir + next_in_dir);
+ SPAposition mid_pos((vert->geometry()->coords().x() + next_vert->geometry()->coords().x())/2.0,
+ (vert->geometry()->coords().y() + next_vert->geometry()->coords().y())/2.0,
+ (vert->geometry()->coords().z() + next_vert->geometry()->coords().z())/2.0);
+
+ VERTEX *clump_vert = old_vertex_to_clump_map[vert]->new_vert;
+ double distance = backoff_distance;
+ SPAposition tmp_pos = mid_pos + distance * mid_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos1);
+ int cntr = 0;
+ point_face_containment containment;
+ api_point_in_face(new_pos1, face, *(SPAtransf*)NULL_REF, containment);
+ // Try to make sure we have a point on the face.
+ while(containment == point_boundary_face && cntr++ < 10)
+ {
+ distance = (clump_vert->geometry()->coords()-new_pos1).len() / 2.0;
+ tmp_pos = mid_pos + distance * mid_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos1);
+ api_point_in_face(new_pos1, face, *(SPAtransf*)NULL_REF, containment);
+ }
+
+ distance = sqrt(2.0)*backoff_distance;
+ tmp_pos = vert->geometry()->coords() + distance*cur_mid_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos2);
+ cntr = 0;
+ api_point_in_face(new_pos2, face, *(SPAtransf*)NULL_REF, containment);
+ while(containment == point_boundary_face && cntr++ < 10)
+ {
+ distance = (clump_vert->geometry()->coords()-new_pos2).len() / 2.0;
+ tmp_pos = vert->geometry()->coords() + distance*cur_mid_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos2);
+ api_point_in_face(new_pos2, face, *(SPAtransf*)NULL_REF, containment);
+ }
+
+ distance = sqrt(2.0)*backoff_distance;
+ tmp_pos = next_vert->geometry()->coords() + distance*next_mid_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos3);
+ cntr = 0;
+ api_point_in_face(new_pos3, face, *(SPAtransf*)NULL_REF, containment);
+ while(containment == point_boundary_face && cntr++ < 10)
+ {
+ distance = (clump_vert->geometry()->coords()-new_pos3).len() / 2.0;
+ tmp_pos = next_vert->geometry()->coords() + distance*next_mid_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos3);
+ api_point_in_face(new_pos3, face, *(SPAtransf*)NULL_REF, containment);
+ }
+
+ distance = backoff_distance;
+ tmp_pos = vert->geometry()->coords() + distance*cur_in_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos4);
+ cntr = 0;
+ api_point_in_face(new_pos4, face, *(SPAtransf*)NULL_REF, containment);
+ while(containment == point_boundary_face && cntr++ < 10)
+ {
+ distance = (vert->geometry()->coords()-new_pos4).len() / 2.0;
+ tmp_pos = vert->geometry()->coords() + distance*cur_in_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos4);
+ api_point_in_face(new_pos4, face, *(SPAtransf*)NULL_REF, containment);
+ }
+
+ distance = backoff_distance;
+ tmp_pos = next_vert->geometry()->coords() + distance*next_in_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos5);
+ cntr = 0;
+ api_point_in_face(new_pos5, face, *(SPAtransf*)NULL_REF, containment);
+ while(containment == point_boundary_face && cntr++ < 10)
+ {
+ distance = (next_vert->geometry()->coords()-new_pos5).len() / 2.0;
+ tmp_pos = next_vert->geometry()->coords() + distance*next_in_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos5);
+ api_point_in_face(new_pos5, face, *(SPAtransf*)NULL_REF, containment);
+ }
+
+ distance = backoff_distance;
+ tmp_pos = next_other_pos + distance*next_other_in_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos6);
+ cntr = 0;
+ api_point_in_face(new_pos6, face, *(SPAtransf*)NULL_REF, containment);
+ while(containment == point_boundary_face && cntr++ < 10)
+ {
+ distance = (next_other_pos-new_pos6).len() / 2.0;
+ tmp_pos = next_other_pos + distance*next_other_in_dir;
+ api_find_cls_ptto_face(tmp_pos, face, new_pos6);
+ api_point_in_face(new_pos6, face, *(SPAtransf*)NULL_REF, containment);
+ }
+
+ // Create the edge going from the new clump vert to new_pos4.
+ VERTEX *v1 = new_vert_from_pos(new_pos4);
+ // Keep track of this vertex.
+ api_copy_entity_contents((ENTITY*)v1, new_ent);
+ split_verts.append((VERTEX*)new_ent);
+ VERTEX *v2 = new_vert_from_pos(clump_vert->geometry()->coords());
+ STRAIGHT *s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ new_edge1 = new EDGE(v1, v2, s, FORWARD);
+ add_named_att((ENTITY*)new_edge1, "REMOVE_EDGE");
+ // Make another copy of this.
+ api_copy_entity_contents((ENTITY*)new_edge1, new_ent);
+ side_edge = (EDGE*)new_ent;
+ // Create the edge going from the new clump vert to new_pos1.
+ v1 = new_vert_from_pos(new_pos1);
+ v2 = new_vert_from_pos(clump_vert->geometry()->coords());
+ s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ new_edge3 = new EDGE(v1, v2, s, FORWARD);
+ add_named_att((ENTITY*)new_edge3, "REMOVE_EDGE");
+ // Make another copy of this.
+ api_copy_entity_contents((ENTITY*)new_edge3, new_ent);
+ new_edge4 = (EDGE*)new_ent;
+ // Create the edge going from the new clump vert to new_pos5.
+ v1 = new_vert_from_pos(new_pos5);
+ v2 = new_vert_from_pos(clump_vert->geometry()->coords());
+ s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ new_edge5 = new EDGE(v1, v2, s, FORWARD);
+ add_named_att((ENTITY*)new_edge5, "REMOVE_EDGE");
+ // Make another copy of this.
+ api_copy_entity_contents((ENTITY*)new_edge5, new_ent);
+ new_edge6 = (EDGE*)new_ent;
+
+ // Create the edge going from the next split to new_pos6.
+ v1 = new_vert_from_pos(new_pos6);
+ v2 = new_vert_from_pos(next_other_pos);
+ new_edge8 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge8)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge8, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge8, new_ent);
+ new_edge8 = (EDGE*)new_ent;
+ // Create the edge going from new_pos2 to new_pos4.
+ v1 = new_vert_from_pos(new_pos2);
+ v2 = new_vert_from_pos(new_pos4);
+ new_edge10 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge10)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge10, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge10, new_ent);
+ new_edge10 = (EDGE*)new_ent;
+ // Create the edge going from new_pos1 to new_pos2.
+ v1 = new_vert_from_pos(new_pos1);
+ v2 = new_vert_from_pos(new_pos2);
+ new_edge11 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge11)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ face = this->find_keep_face(new_edge11, vert, dead_faces);
+ if(!face)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge11, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge11, new_ent);
+ new_edge11 = (EDGE*)new_ent;
+ // Create the edge going from new_pos1 to new_pos3.
+ v1 = new_vert_from_pos(new_pos1);
+ v2 = new_vert_from_pos(new_pos3);
+ new_edge12 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge12)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge12, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge12, new_ent);
+ new_edge12 = (EDGE*)new_ent;
+ // Create the edge going from new_pos3 to new_pos5.
+ v1 = new_vert_from_pos(new_pos3);
+ v2 = new_vert_from_pos(new_pos5);
+ new_edge13 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge13)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ face = this->find_keep_face(new_edge13, next_vert, dead_faces);
+ if(!face)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge13, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge13, new_ent);
+ new_edge13 = (EDGE*)new_ent;
+ // Create the edge going from new_pos6 to new_pos5.
+ v1 = new_vert_from_pos(new_pos6);
+ v2 = new_vert_from_pos(new_pos5);
+ new_edge14 = imprint_new_edge_on_face(face, v1, v2);
+ if(!new_edge14)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ face = this->find_keep_face(new_edge14, next_vert, dead_faces);
+ if(!face)
+ ret = CUBIT_FAILURE;
+ else
+ {
+ add_named_att((ENTITY*)new_edge14, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)new_edge14, new_ent);
+ new_edge14 = (EDGE*)new_ent;
+ v1 = new_vert_from_pos(next_other_pos);
+ v2 = new_vert_from_pos(old_vertex_to_clump_map[next_vert]->new_vert->geometry()->coords());
+ s = new STRAIGHT(v1->geometry()->coords(), normalise(v2->geometry()->coords() - v1->geometry()->coords()));
+ new_edge16 = new EDGE(v1, v2, s, FORWARD);
+ if(new_edge1 && new_edge3 && new_edge10 && new_edge11)
+ {
+ // Now create the new face.
+ DLIList<EDGE*> edges_for_new_face;
+ edges_for_new_face.append(new_edge1);
+ edges_for_new_face.append(new_edge3);
+ edges_for_new_face.append(new_edge10);
+ edges_for_new_face.append(new_edge11);
+ FACE* FACE_ptr = AcisModifyEngine::instance()->make_FACE(PLANE_SURFACE_TYPE, edges_for_new_face);
+ if(FACE_ptr)
+ {
+ new_vol_faces.append(FACE_ptr);
+ projected_positions.append(new_pos2);
+ projected_positions.append(new_pos1);
+ if(new_edge4 && new_edge5 && new_edge12 && new_edge13)
+ {
+ // Now create the new face.
+ DLIList<EDGE*> edges_for_new_face;
+ edges_for_new_face.append(new_edge4);
+ edges_for_new_face.append(new_edge5);
+ edges_for_new_face.append(new_edge12);
+ edges_for_new_face.append(new_edge13);
+ FACE* FACE_ptr = AcisModifyEngine::instance()->make_FACE(PLANE_SURFACE_TYPE, edges_for_new_face);
+ if(FACE_ptr)
+ {
+ new_vol_faces.append(FACE_ptr);
+ projected_positions.append(new_pos3);
+ projected_positions.append(new_pos5);
+ if(new_edge6 && new_edge8 && new_edge14 && new_edge16)
+ {
+ // Now create the new face.
+ DLIList<EDGE*> edges_for_new_face;
+ edges_for_new_face.append(new_edge6);
+ edges_for_new_face.append(new_edge8);
+ edges_for_new_face.append(new_edge14);
+ edges_for_new_face.append(new_edge16);
+ FACE* FACE_ptr = AcisModifyEngine::instance()->make_FACE(PLANE_SURFACE_TYPE, edges_for_new_face);
+ if(FACE_ptr)
+ {
+ new_vol_faces.append(FACE_ptr);
+ projected_positions.append(new_pos6);
+ }
+ else
+ {
+ PRINT_ERROR("Failed to build face from bounding curves.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to get all of the required edges for a new face.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to build face from bounding curves.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to get all of the required edges for a new face.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to build face from bounding curves.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Failed to get all of the required edges for a new face.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if(angle <= seven_pi_over_four)
+ {
+ // Introduce one edge to separate this new
+ // face with the one that will be created
+ // for the next lateral edge.
+ VERTEX *vert1, *vert2;
+ EDGE *new_edge1;
+ SPAposition new_pos1;
+ // Make the first new edge. This will be the edge going into the
+ // current face and separating the new face associated with this
+ // lateral (current) edge and the face associated with the adjacent
+ // lateral edge.
+ SPAposition mid_pos((vert->geometry()->coords().x() + next_vert->geometry()->coords().x())/2.0,
+ (vert->geometry()->coords().y() + next_vert->geometry()->coords().y())/2.0,
+ (vert->geometry()->coords().z() + next_vert->geometry()->coords().z())/2.0);
+ tangent_indir(face, edge, vert->geometry()->coords(), cur_dir);
+ tangent_indir(face, next_edge, next_vert->geometry()->coords(), other_dir);
+ SPAvector ave_dir = cur_dir + other_dir;
+ SPAvector ave_dir_norm = normalise(ave_dir);
+ angle /= 2.0;
+ double distance = backoff_distance/sin(angle);
+ SPAposition tmp_pos = mid_pos + distance * ave_dir_norm;
+ face->geometry()->equation().point_perp(tmp_pos, new_pos1);
+ // Now that we have the location of the new position projected into
+ // the face we will create the first new edge.
+ vert1 = new_vert_from_pos(new_pos1);
+ vert2 = new_vert_from_pos(old_vertex_to_clump_map[vert]->new_vert->geometry()->coords());
+ STRAIGHT *s = new STRAIGHT(vert1->geometry()->coords(), normalise(vert2->geometry()->coords() - vert1->geometry()->coords()));
+ new_edge1 = new EDGE(vert1, vert2, s, FORWARD);
+ // Create a new split edge associated with this new edge. It will be retrieved later for
+ // processing the adjacent lateral edge.
+ side_edge = new_edge1;
+ add_named_att((ENTITY*)side_edge, "REMOVE_EDGE");
+ split_verts.append(vert1);
+ projected_positions.append(new_pos1);
+ }
+ else
+ {
+ // Introduce three edges and two extra faces
+ // to separate this new
+ // face with the one that will be created
+ // for the next lateral edge.
+ PRINT_ERROR("Unhandled angle on adjacent face.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ }
+ else
+ ret = CUBIT_FAILURE;
+ }
+ if(side_edge)
+ {
+ new_face_edges.append(side_edge);
+ }
+ }
+ if(ret == CUBIT_SUCCESS)
+ {
+ // Make sure we have 2 split positions.
+ if(split_verts.size() != 2)
+ {
+ PRINT_ERROR("Problem finding new positions for building new topology.\n");
+ ret = CUBIT_FAILURE;
+ }
+ else
+ {
+ // Start with the split position at the start of the edge.
+ // We want to build a list of points used to split the surface.
+ split_verts.reset();
+
+ int num_in_array = 2;
+ SPAposition *pos_array = NULL;
+ // Check to see if the curve is basically a straight line. If it
+ // is we will just need the end points of the splitting curve.
+ // Otherwise we need to step along the curve and generate points
+ // to be used in generating the splitting curve.
+ if(edge->geometry()->equation().type() != straight_type &&
+ !this->is_roughly_straight_curve_wrt_surf(edge, face))
+ {
+ num_in_array += num_divisions-1;
+ pos_array = new SPAposition[num_in_array];
+ SPAposition pos;
+ SPAinterval range = edge->param_range();
+ if(edge->sense() == REVERSED)
+ range.negate();
+ start = range.start_pt();
+ end = range.end_pt();
+ double dt = (end-start)/(double)num_divisions;
+ double cur_t = start + dt;
+ for(d=1; d<num_divisions; d++)
+ {
+ edge->geometry()->equation().eval(cur_t, pos);
+ tangent_indir(face, edge, pos, cur_dir);
+ pos += backoff_distance * cur_dir;
+ SPAposition clos;
+ face->geometry()->equation().point_perp(pos, clos);
+ pos_array[d] = clos;
+ cur_t += dt;
+ }
+ pos_array[0] = split_verts.get()->geometry()->coords();
+ pos_array[num_in_array-1] = split_verts.next()->geometry()->coords();
+ }
+
+ EDGE *split_edge = NULL;
+ if(num_in_array == 2)
+ {
+ split_edge = imprint_new_edge_on_face(face, split_verts.get(), split_verts.next());
+ if(!split_edge)
+ {
+ PRINT_WARNING("Failed to imprint curve on surface.\n"
+ "Re-trying with a more accurate curve.\n");
+ num_in_array += num_divisions-1;
+ pos_array = new SPAposition[num_in_array];
+ SPAposition pos;
+ SPAinterval range = edge->param_range();
+ if(edge->sense() == REVERSED)
+ range.negate();
+ start = range.start_pt();
+ end = range.end_pt();
+ double dt = (end-start)/(double)num_divisions;
+ double cur_t = start + dt;
+ for(d=1; d<num_divisions; d++)
+ {
+ edge->geometry()->equation().eval(cur_t, pos);
+ tangent_indir(face, edge, pos, cur_dir);
+ pos += backoff_distance * cur_dir;
+ SPAposition clos;
+ face->geometry()->equation().point_perp(pos, clos);
+ pos_array[d] = clos;
+ cur_t += dt;
+ }
+ pos_array[0] = split_verts.get()->geometry()->coords();
+ pos_array[num_in_array-1] = split_verts.next()->geometry()->coords();
+ }
+ }
+ if(!split_edge && num_in_array > 2)
+ {
+ EDGE *new_edge = NULL;
+ api_curve_spline(num_in_array, pos_array, NULL, NULL, new_edge);
+ if(face->geometry()->equation().type() != plane_type)
+ new_edge = AcisModifyEngine::instance()->project_EDGE(new_edge, face, 0);
+ ENTITY *body;
+ api_get_owner((ENTITY*)face, body);
+ ENTITY_LIST face_edges_before;
+ api_get_edges((ENTITY*)face, face_edges_before);
+ DLIList<TopologyBridge*> temporary_bridges;
+ AcisModifyEngine::instance()->imprint((BODY*)body, face, new_edge, temporary_bridges);
+ temporary_bridges.uniquify_ordered();
+ while(temporary_bridges.size())
+ delete temporary_bridges.pop();
+ ENTITY_LIST face_edges_after;
+ api_get_edges((ENTITY*)face, face_edges_after);
+ face_edges_after.remove(face_edges_before);
+ if(face_edges_after.iteration_count() == 1)
+ {
+ face_edges_after.init();
+ split_edge = (EDGE*)face_edges_after.next();
+ }
+ }
+ if(pos_array)
+ delete [] pos_array;
+
+ if(!split_edge)
+ {
+ PRINT_ERROR("Failed to find curve to use in splitting face.\n");
+ ret = CUBIT_FAILURE;
+ }
+ else
+ {
+ ENTITY_LIST edge_faces;
+ api_get_faces((ENTITY*)split_edge, edge_faces);
+ if(edge_faces.count() == 2)
+ {
+ edge_faces.init();
+ FACE *f1 = (FACE*)edge_faces.next();
+ ENTITY_LIST tmp_edges;
+ api_get_edges((ENTITY*)f1, tmp_edges);
+ FACE *face_to_remove;
+ if(tmp_edges.lookup(edge) != -1)
+ {
+ face = (FACE*)edge_faces.next();
+ face_to_remove = f1;
+ }
+ else
+ {
+ face = f1;
+ face_to_remove = (FACE*)edge_faces.next();
+ }
+ dead_faces.append(face_to_remove);
+ }
+ if(split_edge)
+ {
+ add_named_att((ENTITY*)split_edge, "REMOVE_EDGE");
+ api_copy_entity_contents((ENTITY*)split_edge, new_ent);
+ split_edge = (EDGE*)new_ent;
+ new_face_edges.append(split_edge);
+ }
+ else
+ {
+ PRINT_ERROR("Failed to find curve to use in splitting face.\n");
+ ret = CUBIT_FAILURE;
+ }
+ if(ret == CUBIT_SUCCESS)
+ {
+ // Clean up memory.
+ if(new_face_edges.size() == 4)
+ {
+ FACE* FACE_ptr = AcisModifyEngine::instance()->make_FACE(PLANE_SURFACE_TYPE, new_face_edges);
+ if(FACE_ptr)
+ new_vol_faces.append(FACE_ptr);
+ else
+ {
+ PRINT_ERROR("Failed to build face from bounding curves.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ else
+ PRINT_ERROR("Unexpected number of edges for new face.\n");
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+int AcisTopologyTool::is_roughly_straight_curve_wrt_surf(EDGE *cur_edge, FACE *cur_face)
+{
+ SPAinterval range = cur_edge->geometry()->equation().param_range();
+ double start = range.start_pt();
+ double end = range.end_pt();
+ int num_divisions = 5;
+ double dt = (end-start)/(double)num_divisions;
+ double cur_t = start;
+ int i;
+ SPAunit_vector ref_dir;
+ SPAposition pos, clos;
+ SPAvector tan, cur_dir;
+ for(i=num_divisions+1; i--;)
+ {
+ cur_edge->geometry()->equation().eval(cur_t, pos, tan);
+ SPAunit_vector norm;
+ cur_face->geometry()->equation().point_perp(pos, clos, norm);
+ SPAunit_vector tan_norm = normalise(tan);
+ cur_dir = norm * tan_norm;
+ if(i == num_divisions)
+ ref_dir = normalise(cur_dir);
+ else
+ {
+ SPAunit_vector cur_normalized = normalise(cur_dir);
+ double dot = ref_dir % cur_normalized;
+ if(dot < .9)
+ return 0;
+ }
+ cur_t += dt;
+ }
+ return 1;
+}
+
+CubitStatus AcisTopologyTool::split_all_curves_coming_into_clumps(DLIList<VERTEXClump*> &clumps,
+ std::map <VERTEX*,VERTEXClump*, mapltid> &old_vertex_to_clump_map,
+ std::map <EDGE*, EDGE*, mapltid> &old_edge_to_new_edge_map,
+ double &backoff_distance,
+ DLIList<SPAposition> &split_positions)
+{
+ int i, j;
+ for(i=clumps.size(); i--;)
+ {
+ VERTEXClump *cur_clump = clumps.get_and_step();
+ for(j=cur_clump->verts.size(); j--;)
+ {
+ VERTEX *cur_vert = cur_clump->verts.get_and_step();
+ ENTITY_LIST vert_edges;
+ api_get_edges((ENTITY*)cur_vert, vert_edges);
+ ENTITY *tmp_ent;
+ vert_edges.init();
+ while((tmp_ent = vert_edges.next()))
+ {
+ EDGE *cur_edge = (EDGE*)tmp_ent;
+ if(!edge_within_clump(cur_edge, old_vertex_to_clump_map) && !old_edge_to_new_edge_map.count(cur_edge))
+ {
+ double param;
+ double len = cur_edge->length();
+ if(backoff_distance > 0.9*len)
+ {
+ PRINT_ERROR("Failed to back off from small topology a distance of %lf without\n"
+ "running into other topology. One possible solution is to increase\n"
+ "the small curve size so that more topology is included in the topology\n"
+ "to be removed.\n", backoff_distance);
+ return CUBIT_FAILURE;
+ }
+ SPAinterval range = cur_edge->param_range();
+ int is_periodic = cur_edge->geometry()->equation().periodic();
+ if(cur_edge->sense() == REVERSED)
+ range.negate();
+ double start_param = range.start_pt();
+ double end_param = range.end_pt();
+
+ double edge_param = cur_edge->geometry()->equation().param(cur_vert->geometry()->coords());
+ if(is_periodic)
+ {
+ double period = cur_edge->geometry()->equation().param_period();
+ while(edge_param < start_param - GEOMETRY_RESABS)
+ edge_param += period;
+ while(edge_param > end_param + GEOMETRY_RESABS)
+ edge_param -= period;
+ }
+ if(fabs(start_param-edge_param) < fabs(end_param-edge_param))
+ param = start_param + (end_param-start_param)*backoff_distance/len;
+ else
+ param = end_param + (start_param-end_param)*backoff_distance/len;
+ SPAposition pos;
+ cur_edge->geometry()->equation().eval(param, pos);
+ split_positions.append(pos);
+ APOINT *ap = new APOINT(pos);
+ VERTEX *v = new VERTEX(ap);
+ sg_split_edge_at_vertex(cur_edge, v);
+ }
+ }
+ }
+ }
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus AcisTopologyTool::adjust_backoff_distance(DLIList<VERTEXClump*> &clumps,
+ std::map <VERTEX*,VERTEXClump*, mapltid> &old_vertex_to_clump_map,
+ std::map <EDGE*, EDGE*, mapltid> &old_edge_to_new_edge_map,
+ double &backoff_distance)
+{
+ int i, j;
+ for(i=clumps.size(); i--;)
+ {
+ VERTEXClump *cur_clump = clumps.get_and_step();
+ for(j=cur_clump->verts.size(); j--;)
+ {
+ VERTEX *cur_vert = cur_clump->verts.get_and_step();
+ ENTITY_LIST vert_edges;
+ api_get_edges((ENTITY*)cur_vert, vert_edges);
+ ENTITY *tmp_ent;
+ vert_edges.init();
+ while((tmp_ent = vert_edges.next()))
+ {
+ EDGE *cur_edge = (EDGE*)tmp_ent;
+ if(!edge_within_clump(cur_edge, old_vertex_to_clump_map) && !old_edge_to_new_edge_map.count(cur_edge))
+ {
+ double len = cur_edge->length();
+ if(backoff_distance > 0.4*len)
+ {
+ backoff_distance = 0.4*len;
+ PRINT_WARNING("Changing backoff distance to %lf.\n", backoff_distance);
+ }
+ }
+ }
+ }
+ }
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus AcisTopologyTool::find_new_edges_between_clumps(DLIList<VERTEXClump*> &clumps,
+ std::map <EDGE*, EDGE*, mapltid> &old_edge_to_new_edge_map,
+ std::map <VERTEXClump*, DLIList<FACE*>*, mapltclump> &surrounding_faces_map)
+{
+ int i, j, k;
+ DLIList<VERTEXClump*> copy_of_clumps = clumps;
+
+ while(copy_of_clumps.size() > 1)
+ {
+ VERTEXClump *cur_clump = copy_of_clumps.extract();
+ DLIList<FACE*> *cur_clump_faces = surrounding_faces_map[cur_clump];
+ for(i=copy_of_clumps.size(); i--;)
+ {
+ VERTEXClump *other_clump = copy_of_clumps.get_and_step();
+ DLIList<EDGE*> common_edges;
+ for(j=cur_clump->verts.size(); j--;)
+ {
+ VERTEX *cur_vert = cur_clump->verts.get_and_step();
+ for(k=other_clump->verts.size(); k--;)
+ {
+ VERTEX *other_vert = other_clump->verts.get_and_step();
+ EDGE *common_edge = find_common_edge(cur_vert, other_vert);
+ if(common_edge)
+ {
+ ENTITY_LIST fs;
+ api_get_faces((ENTITY*)common_edge, fs);
+ ENTITY *tmp_ent;
+ fs.init();
+ int ok_to_proceed = 0;
+ while((tmp_ent = fs.next()) && !ok_to_proceed)
+ {
+ if(!cur_clump_faces->is_in_list((FACE*)tmp_ent))
+ ok_to_proceed = 1;
+ }
+
+ if(ok_to_proceed)
+ common_edges.append_unique(common_edge);
+ }
+ }
+ }
+ if(common_edges.size() > 0)
+ {
+ EDGE *new_edge = NULL;
+ int r;
+ int has_a_straight = 0;
+ for(r=common_edges.size(); r && !has_a_straight; r--)
+ {
+ EDGE *cur_com_edge = common_edges.get_and_step();
+ if(cur_com_edge->geometry()->equation().type() == straight_type)
+ has_a_straight = 1;
+ }
+
+ if(has_a_straight)
+ {
+ APOINT *p1 = new APOINT(cur_clump->ave_pos);
+ APOINT *p2 = new APOINT(other_clump->ave_pos);
+ VERTEX *v1 = new VERTEX(p1);
+ VERTEX *v2 = new VERTEX(p2);
+ STRAIGHT *s = new STRAIGHT(cur_clump->ave_pos, normalise(other_clump->ave_pos - cur_clump->ave_pos));
+ new_edge = new EDGE(v1, v2, s, FORWARD);
+ }
+ else
+ {
+ DLIList<EDGE*> copy = common_edges;
+ EDGE *guide_edge = copy.get();
+ copy.move_to(guide_edge);
+ copy.extract();
+
+ SPAposition closest;
+ double cur_t;
+ SPAparameter param;
+ int num_divisions = 20;
+ SPAposition* pos_array = new SPAposition[num_divisions+1];
+ SPAinterval range = guide_edge->param_range();
+ // Get range with respect to underlying curve.
+ if(guide_edge->sense() == REVERSED)
+ range.negate();
+ double dt = range.length()/(double)num_divisions;
+ double start = range.start_pt();
+ double end = range.end_pt();
+ guide_edge->geometry()->equation().point_perp(cur_clump->ave_pos, closest);
+ double start_dist = (closest - guide_edge->start_pos()).len_sq();
+ double end_dist = (closest - guide_edge->end_pos()).len_sq();
+ if(start_dist > end_dist)
+ {
+ double tmp = start;
+ start = end;
+ end = tmp;
+ dt *= -1.0;
+ }
+
+ cur_t = start + dt;
+ SPAposition pos;
+ pos_array[0] = cur_clump->ave_pos;
+ for(r=1; r<num_divisions; r++)
+ {
+ SPAposition ave_pos;
+ guide_edge->geometry()->equation().eval(cur_t, ave_pos);
+ pos = ave_pos;
+ for(int e=copy.size(); e--;)
+ {
+ EDGE *cur_e = copy.get_and_step();
+ cur_e->geometry()->equation().point_perp(pos, closest);
+ ave_pos.set_x(ave_pos.x() + closest.x());
+ ave_pos.set_y(ave_pos.y() + closest.y());
+ ave_pos.set_z(ave_pos.z() + closest.z());
+ }
+ ave_pos.set_x(ave_pos.x() / (copy.size() + 1));
+ ave_pos.set_y(ave_pos.y() / (copy.size() + 1));
+ ave_pos.set_z(ave_pos.z() / (copy.size() + 1));
+ pos_array[r] = ave_pos;
+ cur_t += dt;
+ }
+ pos_array[num_divisions] = other_clump->ave_pos;
+ outcome result = api_curve_spline(num_divisions+1, pos_array,
+ NULL, NULL, new_edge);
+ delete [] pos_array;
+ }
+
+ for(r=common_edges.size(); r--;)
+ {
+ EDGE *cur_com_edge = common_edges.get_and_step();
+ ENTITY* copy;
+ api_copy_entity_contents((ENTITY*)new_edge, copy);
+ old_edge_to_new_edge_map[cur_com_edge] = (EDGE*)copy;
+ }
+ api_del_entity((ENTITY*)new_edge);
+ }
+ }
+ }
+ return CUBIT_SUCCESS;
+}
+
+EDGE* AcisTopologyTool::find_common_edge (FACE *f1, FACE *f2)
+{
+ ENTITY_LIST f1_edge_list;
+ api_get_edges((ENTITY*)f1, f1_edge_list);
+ ENTITY *tmp_ent, *tmp_ent2;
+ f1_edge_list.init();
+ while((tmp_ent = f1_edge_list.next()))
+ {
+ ENTITY_LIST edge_faces;
+ api_get_faces(tmp_ent, edge_faces);
+ while((tmp_ent2 = edge_faces.next()))
+ {
+ if(tmp_ent2 == f2)
+ return (EDGE*)tmp_ent;
+ }
+ }
+ return NULL;
+}
+
+EDGE* AcisTopologyTool::find_common_edge (VERTEX *v1, VERTEX *v2)
+{
+ ENTITY_LIST v1_edge_list;
+ api_get_edges((ENTITY*)v1, v1_edge_list);
+ ENTITY *tmp_ent, *tmp_ent2;
+ v1_edge_list.init();
+ while((tmp_ent = v1_edge_list.next()))
+ {
+ ENTITY_LIST edge_verts;
+ api_get_vertices(tmp_ent, edge_verts);
+ while((tmp_ent2 = edge_verts.next()))
+ {
+ if(tmp_ent2 == v2)
+ return (EDGE*)tmp_ent;
+ }
+ }
+ return NULL;
+}
+
+CubitStatus AcisTopologyTool::find_new_pos_for_clump(std::map <VERTEXClump*, DLIList<FACE*>*, mapltclump> &surrounding_faces_map,
+ DLIList<FACE*> &faces_to_move,
+ double &size)
+{
+ std::map<VERTEXClump*, DLIList<FACE*>*, mapltclump>::iterator iter;
+ double tol = (2.0 * size) * (2.0 * size);
+
+ SPAposition clos;
+ SPAunit_vector norm;
+ for(iter=surrounding_faces_map.begin(); iter != surrounding_faces_map.end(); iter++ )
+ {
+ VERTEXClump *cur_clump = iter->first;
+ DLIList<FACE*> *surrounding_faces = iter->second;
+ DLIList<FACE*> copy_of_surrounding_faces = *surrounding_faces;
+ copy_of_surrounding_faces -= faces_to_move;
+ if(copy_of_surrounding_faces.size() > 1)
+ {
+ FACE *start_face = copy_of_surrounding_faces.extract();
+ start_face->geometry()->equation().point_perp(cur_clump->ave_pos, clos, norm);
+ CubitVector normal(norm.x(), norm.y(), norm.z());
+ CubitVector closest(clos.x(), clos.y(), clos.z());
+ CubitPlane plane1(normal, closest);
+ FACE *next_face = copy_of_surrounding_faces.extract();
+ EDGE *common_edge = find_common_edge(start_face, next_face);
+ if(common_edge)
+ {
+ if(cur_clump->verts.is_in_list(common_edge->start()))
+ cur_clump->ave_pos = common_edge->start()->geometry()->coords();
+ else if(cur_clump->verts.is_in_list(common_edge->end()))
+ cur_clump->ave_pos = common_edge->end()->geometry()->coords();
+ }
+ else
+ {
+ next_face->geometry()->equation().point_perp(cur_clump->ave_pos, clos, norm);
+ CubitVector normal2(norm.x(), norm.y(), norm.z());
+ CubitVector closest2(clos.x(), clos.y(), clos.z());
+ CubitPlane plane2(normal2, closest2);
+ CubitVector line_origin, line_dir;
+ if(plane1.intersect(plane2, line_origin, line_dir))
+ {
+ CubitVector ave_pos(cur_clump->ave_pos.x(), cur_clump->ave_pos.y(),
+ cur_clump->ave_pos.z());
+ if(ave_pos.about_equal(line_origin))
+ {
+ cur_clump->ave_pos.set_x(line_origin.x());
+ cur_clump->ave_pos.set_y(line_origin.y());
+ cur_clump->ave_pos.set_z(line_origin.z());
+ }
+ else
+ {
+ CubitVector v2(ave_pos - line_origin);
+ double dot = v2 % line_dir;
+ CubitVector pt3 = line_origin + dot * line_dir;
+ cur_clump->ave_pos.set_x(pt3.x());
+ cur_clump->ave_pos.set_y(pt3.y());
+ cur_clump->ave_pos.set_z(pt3.z());
+ }
+ }
+ }
+
+ if(common_edge && copy_of_surrounding_faces.size() > 0)
+ {
+ next_face = copy_of_surrounding_faces.extract();
+ next_face->geometry()->equation().point_perp(cur_clump->ave_pos, clos, norm);
+ CubitVector normal2(norm.x(), norm.y(), norm.z());
+ CubitVector closest2(clos.x(), clos.y(), clos.z());
+ CubitPlane plane2(normal2, closest2);
+ SPAunit_vector tang;
+ common_edge->geometry()->equation().point_perp(cur_clump->ave_pos, clos, tang);
+ CubitVector closest(clos.x(), clos.y(), clos.z());
+ CubitVector tangent(tang.x(), tang.y(), tang.z());
+ CubitVector new_pt = plane2.intersect(closest, tangent);
+ CubitVector clump_pos(cur_clump->ave_pos.x(), cur_clump->ave_pos.y(),
+ cur_clump->ave_pos.z());
+ if((new_pt - clump_pos).length_squared() < tol)
+ {
+ cur_clump->ave_pos.set_x(new_pt.x());
+ cur_clump->ave_pos.set_y(new_pt.y());
+ cur_clump->ave_pos.set_z(new_pt.z());
+ }
+ }
+ }
+ else if(copy_of_surrounding_faces.size() == 1)
+ {
+ FACE *start_face = copy_of_surrounding_faces.get();
+ start_face->geometry()->equation().point_perp(cur_clump->ave_pos, clos, norm);
+ cur_clump->ave_pos = clos;
+ }
+ }
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus AcisTopologyTool::choose_best_face_to_move(DLIList<FACE*> &faces_that_might_move,
+ std::map <FACE*, int, mapltid> &face_clump_count_map,
+ DLIList<VERTEX*> &all_verts_in_clumps)
+{
+ if(faces_that_might_move.size() == 2)
+ {
+ FACE *face1 = faces_that_might_move.get_and_step();
+ FACE *face2 = faces_that_might_move.get();
+ if(face_clump_count_map[face1] < face_clump_count_map[face2])
+ {
+ faces_that_might_move.move_to(face2);
+ faces_that_might_move.extract();
+ }
+ else if(face_clump_count_map[face2] < face_clump_count_map[face1])
+ {
+ faces_that_might_move.move_to(face1);
+ faces_that_might_move.extract();
+ }
+ else
+ {
+ DLIList<VERTEX*> face1_verts, face2_verts;
+ ENTITY_LIST face1_VERTS, face2_VERTS;
+ api_get_vertices((ENTITY*)face1, face1_VERTS);
+ api_get_vertices((ENTITY*)face2, face2_VERTS);
+ face1_VERTS.init();
+ face2_VERTS.init();
+ ENTITY *tmp_ent;
+ while((tmp_ent = face1_VERTS.next()))
+ face1_verts.append((VERTEX*)tmp_ent);
+ while((tmp_ent = face2_VERTS.next()))
+ face2_verts.append((VERTEX*)tmp_ent);
+ face1_verts.intersect(all_verts_in_clumps);
+ face2_verts.intersect(all_verts_in_clumps);
+ if(face1_verts.size() > face2_verts.size())
+ {
+ faces_that_might_move.move_to(face1);
+ faces_that_might_move.extract();
+ }
+ else
+ {
+ // face 2 has more than or equal the number of
+ // face 1 so remove face2 from the list so that
+ // face 1 is moved.
+ faces_that_might_move.move_to(face2);
+ faces_that_might_move.extract();
+ }
+ }
+ }
+
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus AcisTopologyTool::ensure_possible_solution(std::map <VERTEXClump*, DLIList<FACE*>*, mapltclump> &faces_that_dont_intersect_map,
+ DLIList<FACE*> &faces_that_might_move)
+{
+ std::map<VERTEXClump*, DLIList<FACE*>*, mapltclump>::iterator iter;
+
+ for(iter=faces_that_dont_intersect_map.begin(); iter != faces_that_dont_intersect_map.end(); iter++ )
+ faces_that_might_move += *(iter->second);
+
+ faces_that_might_move.uniquify_unordered();
+
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus AcisTopologyTool::find_faces_that_dont_intersect(std::map <VERTEXClump*, DLIList<FACE*>*, mapltclump> &surrounding_faces_map,
+ std::map <VERTEXClump*, DLIList<FACE*>*, mapltclump> &faces_that_dont_intersect_map,
+ double &small_dist)
+{
+ int i;
+ double tol = (2.0 * small_dist) * (2.0 * small_dist);
+ std::map<VERTEXClump*, DLIList<FACE*>*, mapltclump>::iterator iter;
+
+ // Find out which face(s) must move for each vertex in the clump.
+ for(iter=surrounding_faces_map.begin(); iter != surrounding_faces_map.end(); iter++ )
+ {
+ DLIList<FACE*> *no_intersection_list = new DLIList<FACE*>;
+ VERTEXClump *cur_clump = iter->first;
+ DLIList<FACE*> *cur_face_list = iter->second;
+ DLIList<FACE*> copy_of_face_list = *cur_face_list;
+ while(copy_of_face_list.size() > 1)
+ {
+ FACE *start_face = copy_of_face_list.extract();
+ ENTITY_LIST start_face_edges;
+ api_get_edges((ENTITY*)start_face, start_face_edges);
+ SPAposition clos;
+ SPAunit_vector norm;
+ start_face->geometry()->equation().point_perp(cur_clump->ave_pos, clos, norm);
+ CubitVector normal(norm.x(), norm.y(), norm.z());
+ CubitVector closest(clos.x(), clos.y(), clos.z());
+ CubitPlane plane1(normal, closest);
+ for(i=copy_of_face_list.size(); i--;)
+ {
+ FACE *other_face = copy_of_face_list.get_and_step();
+ EDGE *common_edge = find_common_edge(start_face, other_face);
+ if(!common_edge)
+ {
+ other_face->geometry()->equation().point_perp(cur_clump->ave_pos, clos, norm);
+ CubitVector normal2(norm.x(), norm.y(), norm.z());
+ CubitVector closest2(clos.x(), clos.y(), clos.z());
+ CubitPlane plane2(normal2, closest2);
+ CubitVector line_origin, line_dir;
+ if(plane1.intersect(plane2, line_origin, line_dir))
+ {
+ CubitVector ave_pos(cur_clump->ave_pos.x(), cur_clump->ave_pos.y(),
+ cur_clump->ave_pos.z());
+ double dist;
+ if(ave_pos.about_equal(line_origin))
+ dist = 0.0;
+ else
+ {
+ CubitVector v2(ave_pos - line_origin);
+ double dot = v2 % line_dir;
+ CubitVector pt3 = line_origin + dot * line_dir;
+ dist = (pt3 - ave_pos).length_squared();
+ }
+ if(dist > tol)
+ {
+ no_intersection_list->append_unique(start_face);
+ no_intersection_list->append_unique(other_face);
+ }
+ }
+ else
+ {
+ no_intersection_list->append_unique(start_face);
+ no_intersection_list->append_unique(other_face);
+ }
+ }
+ }
+ }
+ faces_that_dont_intersect_map[cur_clump] = no_intersection_list;
+ }
+
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus AcisTopologyTool::find_face_clump_counts(std::map <VERTEXClump*, DLIList<FACE*>*, mapltclump> &surrounding_faces_map,
+ std::map <FACE*, int, mapltid> &face_clump_count_map)
+{
+ int i;
+ std::map<VERTEXClump*, DLIList<FACE*>*, mapltclump>::iterator iter;
+
+ // Initialize all counts to zero.
+ for(iter=surrounding_faces_map.begin(); iter != surrounding_faces_map.end(); iter++ )
+ {
+ for(i=iter->second->size(); i--;)
+ {
+ FACE *cur_face = iter->second->get_and_step();
+ face_clump_count_map[cur_face] = 0;
+ }
+ }
+
+ // Find number of times face is referenced in a clump.
+ for(iter=surrounding_faces_map.begin(); iter != surrounding_faces_map.end(); iter++ )
+ {
+ for(i=iter->second->size(); i--;)
+ {
+ FACE *cur_face = iter->second->get_and_step();
+ face_clump_count_map[cur_face] = face_clump_count_map[cur_face] + 1;
+ }
+ }
+
+ return CUBIT_SUCCESS;
+}
+
+void AcisTopologyTool::find_ave_clump_pos(VERTEXClump *&clump)
+{
+ int i;
+
+ clump->ave_pos = SPAposition(0,0,0);
+ for(i=clump->verts.size(); i--;)
+ {
+ VERTEX *cur_vert = clump->verts.get_and_step();
+ clump->ave_pos.set_x(clump->ave_pos.x() + cur_vert->geometry()->coords().x());
+ clump->ave_pos.set_y(clump->ave_pos.y() + cur_vert->geometry()->coords().y());
+ clump->ave_pos.set_z(clump->ave_pos.z() + cur_vert->geometry()->coords().z());
+ }
+ clump->ave_pos.set_x(clump->ave_pos.x()/clump->verts.size());
+ clump->ave_pos.set_y(clump->ave_pos.y()/clump->verts.size());
+ clump->ave_pos.set_z(clump->ave_pos.z()/clump->verts.size());
+}
+
+CubitStatus AcisTopologyTool::get_all_verts_in_clumps(DLIList<VERTEXClump*> &clumps,
+ DLIList<VERTEX*> &all_verts_in_clumps)
+{
+ int i;
+ for(i=clumps.size(); i--;)
+ {
+ VERTEXClump *cur_clump = clumps.get_and_step();
+ all_verts_in_clumps += cur_clump->verts;
+ // While we are here calculate an average position for
+ // each clump.
+ find_ave_clump_pos(cur_clump);
+ }
+
+ all_verts_in_clumps.uniquify_ordered();
+
+ return CUBIT_SUCCESS;
+}
+
+/*
+void AcisTopologyTool::propagate_over_narrow_face(FACE *narrow_face,
+ EDGE *edge,
+ DLIList<FACE*> &processed_faces,
+ DLIList<EDGE*> &small_edges,
+ double small_edge_length)
+{
+ processed_faces.append(narrow_face);
+ ENTITY_LIST face_edges;
+ api_get_edges((ENTITY*)narrow_face, face_edges);
+ ENTITY *tmp_ent;
+ face_edges.init();
+ while((tmp_ent = face_edges.next()))
+ {
+ EDGE *cur_edge = (EDGE*)tmp_ent;
+ if(cur_edge != edge)
+ {
+ if(cur_edge->length() < small_edge_length)
+ {
+ if(!small_edges.is_in_list(cur_edge))
+ {
+ small_edges.append(cur_edge);
+ propagate_from_small_edge(cur_edge, small_edges,
+ processed_faces, small_edge_length);
+ }
+ }
+ ENTITY_LIST edge_faces;
+ api_get_faces((ENTITY*)cur_edge, edge_faces);
+ edge_faces.init();
+ while((tmp_ent = edge_faces.next()))
+ {
+ FACE *cur_face = (FACE*)tmp_ent;
+ if(cur_face != narrow_face)
+ {
+ if(!processed_faces.is_in_list(cur_face))
+ {
+ if(narrow_region_exists(cur_face, small_edge_length))
+ {
+ propagate_over_narrow_face(cur_face, cur_edge, processed_faces,
+ small_edges, small_edge_length);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+*/
+void AcisTopologyTool::point_perp_trimmed(EDGE *edge,
+ SPAposition &pos_in,
+ SPAposition &pos_out,
+ double *edge_param)
+{
+ SPAinterval range = edge->param_range();
+ SPAparameter crv_param, tmp_edge_param;
+ edge->geometry()->equation().point_perp(pos_in, pos_out, *(SPAparameter*)NULL_REF, crv_param);
+ if(edge->sense() == REVERSED)
+ {
+ if(crv_param > -range.start_pt())
+ {
+ tmp_edge_param = range.start_pt();
+ pos_out = edge->start_pos();
+ }
+ else if(crv_param < -range.end_pt())
+ {
+ tmp_edge_param = range.start_pt();
+ pos_out = edge->end_pos();
+ }
+ else
+ tmp_edge_param = -crv_param;
+ }
+ else
+ {
+ if(crv_param > range.end_pt())
+ {
+ tmp_edge_param = range.end_pt();
+ pos_out = edge->end_pos();
+ }
+ else if(crv_param < range.start_pt())
+ {
+ tmp_edge_param = range.start_pt();
+ pos_out = edge->start_pos();
+ }
+ else
+ tmp_edge_param = crv_param;
+ }
+
+ if(edge_param)
+ *edge_param = tmp_edge_param;
+}
+/*
+int AcisTopologyTool::is_narrow_region_at_point(EDGE *e1,
+ SPAposition &pt_on_e1,
+ EDGE *e2,
+ const double &tol_sq,
+ SPAposition &closest)
+{
+ int ret = 0;
+ SPAvector tan_1, tan_2;
+ double param;
+ point_perp_trimmed(e2, pt_on_e1, closest, ¶m);
+ double dist = (pt_on_e1-closest).len_sq();
+ if(dist < tol_sq)
+ {
+ if(e2->sense() == REVERSED)
+ param = -param;
+ SPAparameter e1_param;
+ SPAposition tmp_pos;
+ e1->geometry()->equation().point_perp(pt_on_e1, tmp_pos, *(SPAparameter*)NULL_REF, e1_param);
+ tan_1 = e1->geometry()->equation().eval_deriv(e1_param);
+ tan_2 = e2->geometry()->equation().eval_deriv(param);
+ SPAunit_vector utan1 = normalise(tan_1);
+ SPAunit_vector utan2 = normalise(tan_2);
+ if(fabs(utan1 % utan2) > .9)
+ ret = 1;
+ }
+ return ret;
+}
+*/
+/*
+int AcisTopologyTool::narrow_region_exists(FACE *face,
+ const double &tol)
+{
+ int ret = 0;
+ ENTITY_LIST face_edges;
+ api_get_edges((ENTITY*)face, face_edges);
+ while(face_edges.iteration_count() > 1 && !ret)
+ {
+ EDGE *cur_edge = (EDGE*)face_edges.first();
+ face_edges.remove(cur_edge);
+
+ face_edges.init();
+ ENTITY *tmp_ent;
+ // Compare this edge with the remaining edges on the face.
+ while((tmp_ent = face_edges.next()) && !ret)
+ {
+ EDGE *other_edge = (EDGE*)tmp_ent;
+
+ DLIList<SPAposition*> e1_pos_list, e2_pos_list;
+ DLIList<VERTEX*> e1_vert_list, e2_vert_list;
+ ret = narrow_region_exists(cur_edge, other_edge, face, tol,
+ e1_pos_list, e2_pos_list, e1_vert_list, e2_vert_list);
+ while(e1_pos_list.size())
+ delete e1_pos_list.pop();
+ while(e2_pos_list.size())
+ delete e2_pos_list.pop();
+ }
+ }
+ return ret;
+}
+*/
+/*
+int AcisTopologyTool::narrow_region_exists(EDGE *e1,
+ EDGE *e2,
+ FACE *face,
+ const double &tol,
+ DLIList<SPAposition*> &e1_pos_list,
+ DLIList<SPAposition*> &e2_pos_list,
+ DLIList<VERTEX*> &e1_vert_list,
+ DLIList<VERTEX*> &e2_vert_list)
+{
+ double same_pt_tol = GEOMETRY_RESABS*GEOMETRY_RESABS;
+ int ret = 0;
+ double tol_sq = tol*tol;
+ double small_step = 5.0*tol;
+ double small_step_sq = small_step*small_step;
+ VERTEX *e1_start_vert = e1->start();
+ VERTEX *e1_end_vert = e1->end();
+ double max_dist_sq = 0.0;
+
+ SPAposition closest;
+
+ // Project cur endpoints onto other.
+ if(is_narrow_region_at_point(e1, e1->start_pos(), e2, tol_sq, closest))
+ {
+ max_dist_sq = (closest - e1->start_pos()).len_sq();
+ e1_pos_list.append(new SPAposition(e1->start_pos()));
+ e2_pos_list.append(new SPAposition(closest));
+ e1_vert_list.append(e1_start_vert);
+ e2_vert_list.append(NULL);
+ }
+ if(is_narrow_region_at_point(e1, e1->end_pos(), e2, tol_sq, closest))
+ {
+ double cur_dist_sq = (closest - e1->end_pos()).len_sq();
+ max_dist_sq = max_dist_sq > cur_dist_sq ? max_dist_sq : cur_dist_sq;
+ e1_pos_list.append(new SPAposition(e1->end_pos()));
+ e2_pos_list.append(new SPAposition(closest));
+ e1_vert_list.append(e1_end_vert);
+ e2_vert_list.append(NULL);
+ }
+
+ if(e1_pos_list.size() < 2)
+ {
+ VERTEX *e2_start_vert = e2->start();
+ VERTEX *e2_end_vert = e2->end();
+ if(is_narrow_region_at_point(e2, e2->start_pos(), e1, tol_sq, closest))
+ {
+ double cur_dist_sq = (closest - e2->start_pos()).len_sq();
+ max_dist_sq = max_dist_sq > cur_dist_sq ? max_dist_sq : cur_dist_sq;
+ e2_pos_list.append(new SPAposition(e2->start_pos()));
+ e1_pos_list.append(new SPAposition(closest));
+ e2_vert_list.append(e2_start_vert);
+ e1_vert_list.append(NULL);
+ }
+ if(e1_pos_list.size() < 2)
+ {
+ if(is_narrow_region_at_point(e2, e2->end_pos(), e1, tol_sq, closest))
+ {
+ double cur_dist_sq = (closest - e2->end_pos()).len_sq();
+ max_dist_sq = max_dist_sq > cur_dist_sq ? max_dist_sq : cur_dist_sq;
+ e2_pos_list.append(new SPAposition(e2->end_pos()));
+ e1_pos_list.append(new SPAposition(closest));
+ e2_vert_list.append(e2_end_vert);
+ e1_vert_list.append(NULL);
+ }
+ }
+ }
+
+ if(e1_pos_list.size() == 2)
+ {
+ if((*e1_pos_list.get() - *e1_pos_list.next()).len_sq() < same_pt_tol)
+ {
+ if((*e2_pos_list.get() - *e2_pos_list.next()).len_sq() < same_pt_tol)
+ {
+ e1_pos_list.reset();
+ e2_pos_list.reset();
+ e1_vert_list.reset();
+ e2_vert_list.reset();
+ delete e1_pos_list.remove();
+ delete e2_pos_list.remove();
+ e1_vert_list.remove();
+ e2_vert_list.remove();
+ }
+ }
+ }
+
+ if(e1_pos_list.size() == 2)
+ {
+ double dist_tol = sqrt(max_dist_sq)*5.0;
+ e1_pos_list.reset();
+ e2_pos_list.reset();
+ SPAposition *cur1 = e1_pos_list.get_and_step();
+ SPAposition *cur2 = e1_pos_list.get();
+ SPAposition *other1 = e2_pos_list.get_and_step();
+ SPAposition *other2 = e2_pos_list.get();
+
+ SPAposition tmp_pos;
+ SPAparameter e1param1, e1param2;
+ e1->geometry()->equation().point_perp(*cur1, tmp_pos, *(SPAparameter*)NULL_REF, e1param1);
+ e1->geometry()->equation().point_perp(*cur2, tmp_pos, *(SPAparameter*)NULL_REF, e1param2);
+ double len1 = fabs(e1->geometry()->equation().length(e1param1, e1param2));
+ if(len1 > dist_tol)
+ {
+ SPAparameter e2param1, e2param2;
+ e2->geometry()->equation().point_perp(*other1, tmp_pos, *(SPAparameter*)NULL_REF, e2param1);
+ e2->geometry()->equation().point_perp(*other2, tmp_pos, *(SPAparameter*)NULL_REF, e2param2);
+ double len2 = fabs(e2->geometry()->equation().length(e2param1, e2param2));
+ if(len2 > dist_tol)
+ {
+ // Check mid point.
+ double mid_param = (e1param1 + e1param2)/2.0;
+ SPAposition cur3;
+ e1->geometry()->equation().eval(mid_param, cur3);
+ if(is_narrow_region_at_point(e1, cur3, e2, tol_sq, closest))
+ {
+ // Sanity check to make sure we aren't splitting off negative space.
+ SPAposition mid((cur3.x()+closest.x())/2.0, (cur3.y()+closest.y())/2.0, (cur3.z()+closest.z())/2.0);
+ SPAposition tmp_pt;
+ api_find_cls_ptto_face(mid, face, tmp_pt);
+ if((mid-tmp_pt).len_sq() < same_pt_tol)
+ ret = 1;
+ }
+ }
+ else
+ {
+ e1_pos_list.remove(cur1);
+ e1_pos_list.remove(cur2);
+ e2_pos_list.remove(other1);
+ e2_pos_list.remove(other2);
+ delete cur1;
+ delete cur2;
+ delete other1;
+ delete other2;
+ }
+ }
+ else
+ {
+ e1_pos_list.remove(cur1);
+ e1_pos_list.remove(cur2);
+ e2_pos_list.remove(other1);
+ e2_pos_list.remove(other2);
+ delete cur1;
+ delete cur2;
+ delete other1;
+ delete other2;
+ }
+ }
+
+ if(!ret && e1_pos_list.size() > 0)
+ {
+ int i;
+ e1_pos_list.reset();
+ e2_pos_list.reset();
+ e1_vert_list.reset();
+ e2_vert_list.reset();
+ for(i=e1_pos_list.size(); i--;)
+ {
+ SPAposition *e1_pos = e1_pos_list.get_and_step();
+ SPAposition *e2_pos = e2_pos_list.get_and_step();
+ VERTEX *e1_vert = e1_vert_list.get_and_step();
+ VERTEX *e2_vert = e2_vert_list.get_and_step();
+
+ VERTEX *cur_vert = NULL;
+ EDGE *cur_edge = NULL, *other_edge = NULL;
+ if(e1_vert)
+ {
+ cur_edge = e1;
+ other_edge = e2;
+ cur_vert = e1_vert;
+ }
+ else if(e2_vert)
+ {
+ cur_edge = e2;
+ other_edge = e1;
+ cur_vert = e2_vert;
+ }
+ if(cur_vert)
+ {
+ SPAposition prev_pos = cur_vert->geometry()->coords(), next_pos;
+ double num_incs = 20.0;
+ SPAinterval crv_range = cur_edge->param_range();
+ if(cur_edge->sense() == REVERSED)
+ crv_range.negate();
+ double start, end;
+ if((cur_vert != cur_edge->start()) != (cur_edge->sense() == REVERSED))
+ {
+ start = crv_range.end_pt();
+ end = crv_range.start_pt();
+ }
+ else
+ {
+ start = crv_range.start_pt();
+ end = crv_range.end_pt();
+ }
+ double step = (end-start)/num_incs;
+ double prev_param = start;
+ double next_param = start + step;
+ int still_good = 1;
+ // Do coarse traversal along curve to see where we start deviating from
+ // narrow.
+ int cntr = 0;
+ while(still_good)
+ {
+ cur_edge->geometry()->equation().eval(next_param, next_pos);
+ cntr++;
+ if(!is_narrow_region_at_point(cur_edge, next_pos, other_edge, tol_sq, closest) ||
+ cntr > num_incs)
+ still_good = 0;
+ else
+ {
+ prev_param = next_param;
+ prev_pos = next_pos;
+ next_param += step;
+ }
+ }
+ SPAparameter param1, param2;
+ SPAposition tmp_pos;
+ cur_edge->geometry()->equation().point_perp(prev_pos, tmp_pos, *(SPAparameter*)NULL_REF, param1);
+ cur_edge->geometry()->equation().point_perp(next_pos, tmp_pos, *(SPAparameter*)NULL_REF, param2);
+ double cur_arc_length = fabs(cur_edge->geometry()->equation().length(param1, param2));
+ // Do bisection of remaining interval to zero in on point where
+ // we go from narrow to non-narrow.
+ SPAposition mid_pos;
+ while(cur_arc_length > small_step)
+ {
+ double mid_param = (prev_param + next_param)/2.0;
+ cur_edge->geometry()->equation().eval(mid_param, mid_pos);
+ if(is_narrow_region_at_point(cur_edge, mid_pos, other_edge, tol_sq, closest))
+ {
+ prev_param = mid_param;
+ prev_pos = mid_pos;
+ }
+ else
+ {
+ next_param = mid_param;
+ next_pos = mid_pos;
+ }
+ cur_edge->geometry()->equation().point_perp(prev_pos, tmp_pos, *(SPAparameter*)NULL_REF, param1);
+ cur_edge->geometry()->equation().point_perp(next_pos, tmp_pos, *(SPAparameter*)NULL_REF, param2);
+ cur_arc_length = fabs(cur_edge->geometry()->equation().length(param1, param2));
+ }
+ if((cur_vert->geometry()->coords() - prev_pos).len_sq() > small_step_sq)
+ {
+ if(cur_edge == e1)
+ {
+ e1_pos_list.append(new SPAposition(mid_pos));
+ e2_pos_list.append(new SPAposition(closest));
+ }
+ else
+ {
+ e2_pos_list.append(new SPAposition(mid_pos));
+ e1_pos_list.append(new SPAposition(closest));
+ }
+ e1_vert_list.append(NULL);
+ e2_vert_list.append(NULL);
+ ret = 1;
+ }
+ }
+ }
+ }
+ return ret;
+}
+*/
+/*
+void AcisTopologyTool::propagate_from_small_edge(EDGE *edge,
+ DLIList<EDGE*> &small_edges,
+ DLIList<FACE*> &processed_faces,
+ double small_edge_length)
+{
+ // First find any small edges connected to this edge.
+ ENTITY_LIST edge_verts;
+ api_get_vertices((ENTITY*)edge, edge_verts);
+ ENTITY *tmp_ent;
+ edge_verts.init();
+ while((tmp_ent = edge_verts.next()))
+ {
+ ENTITY_LIST vert_edges;
+ api_get_edges(tmp_ent, vert_edges);
+ vert_edges.init();
+ while((tmp_ent = vert_edges.next()))
+ {
+ EDGE *cur_edge = (EDGE*)tmp_ent;
+ if(cur_edge != edge)
+ {
+ if(cur_edge->length() < small_edge_length)
+ {
+ if(!small_edges.is_in_list(cur_edge))
+ {
+ small_edges.append(cur_edge);
+ propagate_from_small_edge(cur_edge, small_edges, processed_faces, small_edge_length);
+ }
+ }
+ }
+ }
+ }
+ // Now look at adjacent narrow faces and recursively process them.
+ ENTITY_LIST edge_faces;
+ api_get_faces((ENTITY*)edge, edge_faces);
+ edge_faces.init();
+ while((tmp_ent = edge_faces.next()))
+ {
+ FACE *cur_face = (FACE*)tmp_ent;
+ if(!processed_faces.is_in_list(cur_face))
+ {
+ if(narrow_region_exists(cur_face, small_edge_length))
+ {
+ propagate_over_narrow_face(cur_face, edge, processed_faces,
+ small_edges, small_edge_length);
+ }
+ }
+ }
+}
+*/
+CubitStatus AcisTopologyTool::setup_clump_map(DLIList<EDGE*> &edges_to_remove,
+ DLIList<FACE*> &faces_to_remove,
+ double small_edge_size,
+ DLIList<VERTEXClump*> &clumps,
+ std::map <VERTEX*, VERTEXClump*, mapltid> &old_vertex_to_clump_map)
+{
+ int i;
+ DLIList<EDGE*> small_edges;
+
+ // Look at the passed-in curves and surfaces and determine if any of the curves
+ // are small enough to be swallowed up by a clump. Otherwise put a clump at every
+ // vertex.
+ for(i=edges_to_remove.size(); i--;)
+ {
+ EDGE *edge = edges_to_remove.get_and_step();
+ if(edge->length() < small_edge_size)
+ small_edges.append_unique(edge);
+ }
+ for(i=faces_to_remove.size(); i--;)
+ {
+ FACE *face = faces_to_remove.get_and_step();
+ ENTITY_LIST edges;
+ api_get_edges((ENTITY*)face, edges);
+ edges.init();
+ ENTITY *tmp_ent = NULL;
+ while( (tmp_ent = edges.next()) != NULL )
+ {
+ EDGE *tmp_edge = (EDGE*)tmp_ent;
+ if(tmp_edge->length() < small_edge_size)
+ small_edges.append_unique(tmp_edge);
+ }
+ }
+ /*
+ // If told to do so propagate the topology to be removed to include
+ // other narrow surfaces and small edges.
+ if(propagate)
+ {
+ DLIList<FACE*> processed_faces;
+ // First look at all of the edges connected to small edges
+ // to see if there are other small edges.
+ DLIList<EDGE*> copy_of_small_edges = small_edges;
+ while(copy_of_small_edges.size())
+ {
+ EDGE *edge = copy_of_small_edges.extract();
+ propagate_from_small_edge(edge, small_edges,
+ processed_faces, small_edge_size);
+ }
+ }
+*/
+ while(small_edges.size())
+ {
+ VERTEXClump *new_clump = new VERTEXClump;
+ new_clump->new_vert = NULL;
+ EDGE *edge = small_edges.extract();
+ ENTITY_LIST verts;
+ api_get_vertices(edge, verts);
+ verts.init();
+ ENTITY *tmp_ent;
+ while((tmp_ent=verts.next()))
+ {
+ VERTEX *tmp_vert = (VERTEX*)tmp_ent;
+ new_clump->verts.append_unique(tmp_vert);
+ get_neighbor_small_edges(edge, tmp_vert, new_clump, small_edges);
+ }
+ clumps.append(new_clump);
+ }
+ // Fill out the pt to clump map for the clumps we have created.
+ build_old_vertex_to_clump_map(clumps, old_vertex_to_clump_map);
+ // Now create a clump for any remaining pts that were
+ // not put in other clumps.
+ for(i=edges_to_remove.size(); i--;)
+ {
+ EDGE *edge = edges_to_remove.get_and_step();
+ ENTITY_LIST verts;
+ api_get_vertices(edge, verts);
+ verts.init();
+ ENTITY *tmp_ent;
+ while((tmp_ent = verts.next()))
+ {
+ VERTEX *tmp_vert = (VERTEX*)tmp_ent;
+ if(!old_vertex_to_clump_map.count(tmp_vert))
+ {
+ VERTEXClump *new_clump = new VERTEXClump;
+ new_clump->new_vert = NULL;
+ new_clump->verts.append(tmp_vert);
+ old_vertex_to_clump_map[tmp_vert] = new_clump;
+ clumps.append(new_clump);
+ }
+ }
+ }
+ for(i=faces_to_remove.size(); i--;)
+ {
+ FACE *face = faces_to_remove.get_and_step();
+ ENTITY_LIST edges;
+ api_get_edges((ENTITY*)face, edges);
+ edges.init();
+ ENTITY *tmp_ent;
+ while((tmp_ent = edges.next()))
+ {
+ EDGE *tmp_edge = (EDGE*)tmp_ent;
+ ENTITY_LIST verts;
+ api_get_vertices(tmp_edge, verts);
+ verts.init();
+ ENTITY *tmp_ent2;
+ while((tmp_ent2 = verts.next()))
+ {
+ VERTEX *tmp_vert = (VERTEX*)tmp_ent2;
+ if(!old_vertex_to_clump_map.count(tmp_vert))
+ {
+ VERTEXClump *new_clump = new VERTEXClump;
+ new_clump->new_vert = NULL;
+ new_clump->verts.append(tmp_vert);
+ old_vertex_to_clump_map[tmp_vert] = new_clump;
+ clumps.append(new_clump);
+ }
+ }
+ }
+ }
+
+ return CUBIT_SUCCESS;
+}
+/*
+void AcisTopologyTool::propagate_to_find_other_small_edges(EDGE *edge,
+ VERTEX *cur_vert,
+ DLIList<EDGE*> &small_edges,
+ double small_edge_length)
+{
+ ENTITY_LIST vert_edges;
+ api_get_edges((ENTITY*)cur_vert, vert_edges);
+ ENTITY *tmp_ent;
+ vert_edges.init();
+ while((tmp_ent = vert_edges.next()))
+ {
+ EDGE *cur_edge = (EDGE*)tmp_ent;
+ if(cur_edge != edge && cur_edge->length() < small_edge_length &&
+ !small_edges.is_in_list(cur_edge))
+ {
+ small_edges.append(cur_edge);
+ ENTITY_LIST edge_verts;
+ api_get_vertices((ENTITY*)cur_edge, edge_verts);
+ edge_verts.init();
+ while((tmp_ent = edge_verts.next()))
+ {
+ VERTEX *vert = (VERTEX*)tmp_ent;
+ if(vert != cur_vert)
+ propagate_to_find_other_small_edges(cur_edge, vert, small_edges, small_edge_length);
+ }
+ }
+ }
+}
+*/
+void AcisTopologyTool::build_old_vertex_to_clump_map(DLIList<VERTEXClump*> &clumps,
+ std::map <VERTEX*, VERTEXClump*, mapltid> &old_vertex_to_clump_map)
+{
+ int i, j;
+
+ for(i=clumps.size(); i--;)
+ {
+ VERTEXClump *cur_clump = clumps.get_and_step();
+ for(j=cur_clump->verts.size(); j--;)
+ {
+ VERTEX *cur_vert = cur_clump->verts.get_and_step();
+ old_vertex_to_clump_map[cur_vert] = cur_clump;
+ }
+ }
+}
+
+void AcisTopologyTool::get_neighbor_small_edges(EDGE *edge,
+ VERTEX *vert,
+ VERTEXClump *&clump,
+ DLIList<EDGE*> &small_edges)
+{
+ ENTITY_LIST edges;
+ api_get_edges(vert, edges);
+ edges.remove(edge);
+ ENTITY *tmp_ent;
+ edges.init();
+ while((tmp_ent = edges.next()))
+ {
+ EDGE *tmp_edge = (EDGE*)tmp_ent;
+ if(small_edges.is_in_list(tmp_edge))
+ {
+ small_edges.move_to(tmp_edge);
+ small_edges.extract();
+ ENTITY_LIST verts;
+ api_get_vertices(tmp_edge, verts);
+ ENTITY *tmp_ent2;
+ verts.init();
+ while((tmp_ent2 = verts.next()))
+ {
+ VERTEX *tmp_vert = (VERTEX*)tmp_ent2;
+ if(tmp_vert != vert)
+ {
+ clump->verts.append_unique(tmp_vert);
+ get_neighbor_small_edges(tmp_edge, tmp_vert, clump, small_edges);
+ }
+ }
+ }
+ }
+}
+
+CubitStatus AcisTopologyTool::find_faces_surrounding_clumps(DLIList<VERTEXClump*> &clumps,
+ std::map <VERTEXClump*, DLIList<FACE*>*, mapltclump> &surrounding_faces_map,
+ DLIList<VERTEX*> &all_verts_in_clumps,
+ std::map <VERTEX*, VERTEXClump*, mapltid> &old_vertex_to_clump_map,
+ DLIList<FACE*> &faces_to_remove)
+{
+ int i, j, k;
+
+ for(i=clumps.size(); i--;)
+ {
+ DLIList<FACE*> *faces_surrounding_clump = new DLIList<FACE*>;
+ VERTEXClump *cur_clump = clumps.get_and_step();
+ for(j=cur_clump->verts.size(); j--;)
+ {
+ VERTEX *cur_vert = cur_clump->verts.get_and_step();
+ ENTITY_LIST vert_faces;
+ api_get_faces(cur_vert, vert_faces);
+ ENTITY *tmp_ent;
+ /*
+ DLIList<FACE*> faces_to_remove_from_local_list;
+ vert_faces.init();
+ while((tmp_ent = vert_faces.next()))
+ {
+ FACE *cur_face = (FACE*)tmp_ent;
+ ENTITY_LIST face_verts;
+ api_get_vertices((ENTITY*)cur_face, face_verts);
+ for(k=all_verts_in_clumps.size(); k--;)
+ face_verts.remove(all_verts_in_clumps.get_and_step());
+ if(face_verts.iteration_count() == 0)
+ {
+ ENTITY_LIST face_edges;
+ api_get_edges((ENTITY*)cur_face, face_edges);
+ ENTITY *tmp_ent2;
+ EDGE *short_edge = NULL;
+ face_edges.init();
+ while((tmp_ent2 = face_edges.next()) && !short_edge)
+ {
+ EDGE *cur_edge = (EDGE*)tmp_ent2;
+ if(edge_within_clump(cur_edge, old_vertex_to_clump_map))
+ short_edge = cur_edge;
+ }
+ if(short_edge)
+ {
+ faces_to_remove.append_unique(cur_face);
+ faces_to_remove_from_local_list.append(cur_face);
+ }
+ }
+ }
+ */
+ for(k=faces_to_remove.size(); k--;)
+ vert_faces.remove((ENTITY*)faces_to_remove.get_and_step());
+ vert_faces.init();
+ while((tmp_ent = vert_faces.next()))
+ faces_surrounding_clump->append((FACE*)tmp_ent);
+ }
+ faces_surrounding_clump->uniquify_ordered();
+ surrounding_faces_map[cur_clump] = faces_surrounding_clump;
+ }
+
+ return CUBIT_SUCCESS;
+ /*
+ int i, j, k;
+
+ for(i=clumps.size(); i--;)
+ {
+ DLIList<FACE*> *faces_surrounding_clump = new DLIList<FACE*>;
+ VERTEXClump *cur_clump = clumps.get_and_step();
+ for(j=cur_clump->verts.size(); j--;)
+ {
+ VERTEX *cur_vert = cur_clump->verts.get_and_step();
+ ENTITY_LIST vert_faces;
+ api_get_faces(cur_vert, vert_faces);
+ DLIList<FACE*> faces_to_remove_from_local_list;
+ ENTITY *tmp_ent;
+ vert_faces.init();
+ while((tmp_ent = vert_faces.next()))
+ {
+ FACE *cur_face = (FACE*)tmp_ent;
+ ENTITY_LIST face_verts;
+ api_get_vertices((ENTITY*)cur_face, face_verts);
+ for(k=all_verts_in_clumps.size(); k--;)
+ face_verts.remove(all_verts_in_clumps.get_and_step());
+ if(face_verts.iteration_count() == 0)
+ {
+ ENTITY_LIST face_edges;
+ api_get_edges((ENTITY*)cur_face, face_edges);
+ ENTITY *tmp_ent2;
+ EDGE *short_edge = NULL;
+ face_edges.init();
+ while((tmp_ent2 = face_edges.next()) && !short_edge)
+ {
+ EDGE *cur_edge = (EDGE*)tmp_ent2;
+ if(edge_within_clump(cur_edge, old_vertex_to_clump_map))
+ short_edge = cur_edge;
+ }
+ if(short_edge)
+ {
+ faces_to_remove.append_unique(cur_face);
+ faces_to_remove_from_local_list.append(cur_face);
+ }
+ }
+ }
+ for(k=faces_to_remove_from_local_list.size(); k--;)
+ vert_faces.remove((ENTITY*)faces_to_remove_from_local_list.get_and_step());
+ vert_faces.init();
+ while((tmp_ent = vert_faces.next()))
+ faces_surrounding_clump->append((FACE*)tmp_ent);
+ }
+ faces_surrounding_clump->uniquify_ordered();
+ surrounding_faces_map[cur_clump] = faces_surrounding_clump;
+ }
+
+ return CUBIT_SUCCESS;
+ */
+}
+
+int AcisTopologyTool::edge_within_clump(EDGE *edge,
+ std::map <VERTEX*,VERTEXClump*, mapltid> &old_vertex_to_clump_map)
+{
+ int ret = 0;
+ VERTEX *v1 = edge->start();
+ VERTEX *v2 = edge->end();
+ if(old_vertex_to_clump_map.count(v1) > 0)
+ {
+ VERTEXClump *c1 = old_vertex_to_clump_map[v1];
+ if(old_vertex_to_clump_map.count(v2) > 0)
+ {
+ VERTEXClump *c2 = old_vertex_to_clump_map[v2];
+ if(c1 == c2)
+ ret = 1;
+ }
+ }
+ return ret;
+}
+
+void f(RefFace* face, int color)
+{
+ GfxDebug::draw_ref_face(face, color);
+ GfxDebug::flush();
+}
+
+void e(RefEdge* edge, int color)
+{
+ GfxDebug::draw_ref_edge(edge, color);
+ GfxDebug::flush();
+}
+
+void v(RefVertex* vert, int color)
+{
+ GfxDebug::draw_ref_vertex(vert, color);
+ GfxDebug::flush();
+}
+
+void p(CubitVector* v, int color)
+{
+ GfxDebug::draw_point(v, color);
+ GfxDebug::flush();
+}
+
+void pos(SPAposition* p, int color)
+{
+ GfxDebug::draw_point(p->x(), p->y(), p->z(), color);
+ GfxDebug::flush();
+}
+
+void en(ENTITY* ent, int color)
+{
+ AcisDrawTool::instance()->draw_ENTITY(ent, color, 0, 1);
+}
Copied: cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisTopologyTool.hpp (from rev 3491, cgm/branches/cubit/geom/ACIS_SRC/AcisTopologyTool.hpp)
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisTopologyTool.hpp (rev 0)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisTopologyTool.hpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -0,0 +1,218 @@
+//- Class: AcisTopologyTool
+//- File: AcisTopologyTool.hpp
+//- Type: class definition
+//- Description: Tool for removing topology
+//- from a model.
+//- Owner: Brett Clark
+//
+
+#ifndef ACISTOPOLOGYTOOL_HPP
+#define ACISTOPOLOGYTOOL_HPP
+
+#include "DLIList.hpp"
+#include "kernapi.hxx"
+#include "position.hxx"
+#include <map>
+
+class ENTITY;
+class VERTEX;
+class EDGE;
+class FACE;
+class ATTRIB_SNL_SIMPLE;
+
+typedef struct {
+ DLIList<VERTEX*> verts;
+ SPAposition ave_pos;
+ VERTEX *new_vert;
+} VERTEXClump;
+
+typedef struct {
+ VERTEXClump *c1, *c2;
+ EDGE *new_edge;
+} Link;
+
+struct mapltid
+{
+ bool operator()(const ENTITY *e1, const ENTITY *e2) const
+ {
+ tag_id_type id1, id2;
+ api_get_entity_id((ENTITY*)e1, id1);
+ api_get_entity_id((ENTITY*)e2, id2);
+ return (id1 < id2);
+ }
+};
+
+struct mapltclump
+{
+ bool operator()(const VERTEXClump *c1, const VERTEXClump *c2) const
+ {
+ tag_id_type id1, id2;
+ api_get_entity_id((ENTITY*)(c1->verts[0]), id1);
+ api_get_entity_id((ENTITY*)(c2->verts[0]), id2);
+ return (id1 < id2);
+ }
+};
+
+class AcisTopologyTool
+{
+ public:
+
+ //Constructor
+ AcisTopologyTool(){};
+
+ //Destructor
+ virtual ~AcisTopologyTool(){};
+
+
+ CubitStatus remove_topology(BODY *&body,
+ DLIList<EDGE*> &edges_to_remove,
+ DLIList<FACE*> &faces_to_remove,
+ double backoff_distance,
+ double small_edge_size);
+
+private:
+
+ ATTRIB_SNL_SIMPLE* find_named_att(ENTITY* ent, const char *name);
+ void add_named_att(ENTITY* ent, const char *name_in);
+ void remove_att(ENTITY* ent, ATTRIB_SNL_SIMPLE *att);
+ CubitStatus combine_old_body_and_new_faces(BODY *&b, DLIList<FACE*> &new_faces);
+ VERTEX* new_vert_from_pos(const SPAposition &pos);
+ CubitStatus build_clump_topology(DLIList<VERTEXClump*> &clumps);
+ void tangent_indir( FACE *FACE_ptr, EDGE *EDGE_ptr,
+ const SPAposition &acis_pos, SPAunit_vector &in_dir );
+ int is_roughly_straight_curve_wrt_surf(EDGE *cur_edge, FACE *cur_face);
+ FACE* find_keep_face(EDGE *edge, VERTEX *vert, DLIList<FACE*> &dead_faces);
+ EDGE* imprint_new_edge_on_face(FACE *face, VERTEX *v1, VERTEX *v2);
+ double angle_between(FACE *face, EDGE *e1, VERTEX *v1, EDGE *e2, VERTEX *v2);
+ EDGE* get_other_edge(EDGE *edge, VERTEX *vert, FACE *face);
+ VERTEX* other_vertex(EDGE *edge, VERTEX *vert);
+ void get_next_edge_around_clump(EDGE *cur_edge, VERTEX *cur_vert,
+ FACE *cur_face,
+ std::map <VERTEX*, VERTEXClump*, mapltid> &old_vertex_to_clump_map,
+ EDGE *&next_edge, VERTEX *&next_vert);
+ CubitStatus generate_faces_for_non_lateral_edge(FACE *&face, EDGE *edge,
+ double &backoff_distance,
+ std::map <VERTEX*, VERTEXClump*, mapltid> &old_vertex_to_clump_map,
+ std::map <EDGE*, EDGE*, mapltid> &old_edge_to_new_edge_map,
+ DLIList<VERTEX*> &processed_verts,
+ DLIList<EDGE*> &processed_edges,
+ DLIList<EDGE*> &edges_to_imprint,
+ DLIList<FACE*> &new_vol_faces,
+ DLIList<FACE*> &dead_faces,
+ DLIList<SPAposition> &projected_positions);
+ CubitStatus generate_faces_for_lateral_edge(FACE *&face, EDGE *edge,
+ double &backoff_distance,
+ std::map <VERTEX*, VERTEXClump*, mapltid> &old_vertex_to_clump_map,
+ std::map <EDGE*, EDGE*, mapltid> &old_edge_to_new_edge_map,
+ DLIList<VERTEX*> &processed_verts,
+ DLIList<EDGE*> &processed_edges,
+ DLIList<EDGE*> &edges_to_imprint,
+ DLIList<FACE*> &new_vol_faces,
+ DLIList<FACE*> &dead_faces,
+ DLIList<SPAposition> &projected_positions);
+ int is_lateral_edge(EDGE *edge, std::map <EDGE*, EDGE*, mapltid> &old_edge_to_new_edge_map);
+ CubitStatus generate_faces_for_surrounding_faces(std::map <VERTEXClump*, DLIList<FACE*>*, mapltclump> &surrounding_faces_map,
+ std::map <EDGE*, EDGE*, mapltid> &old_edge_to_new_edge_map,
+ std::map <VERTEX*,VERTEXClump*, mapltid> &old_vertex_to_clump_map,
+ DLIList<FACE*> &new_vol_faces,
+ DLIList<FACE*> &modified_faces,
+ double &backoff_distance,
+ DLIList<FACE*> &dead_faces,
+ DLIList<SPAposition> &projected_positions);
+ /*
+ void propagate_from_small_edge(EDGE *edge,
+ DLIList<EDGE*> &small_edges,
+ DLIList<FACE*> &processed_faces,
+ double small_edge_length);
+ */
+ CubitStatus generate_faces_for_surrounding_face(FACE *face,
+ double &backoff_distance,
+ std::map <VERTEX*, VERTEXClump*, mapltid> &old_vertex_to_clump_map,
+ std::map <EDGE*, EDGE*, mapltid> &old_edge_to_new_edge_map,
+ DLIList<FACE*> &processed_faces,
+ DLIList<FACE*> &modified_faces,
+ DLIList<FACE*> &new_vol_faces,
+ DLIList<FACE*> &dead_faces,
+ DLIList<SPAposition> &projected_positions);
+ CubitStatus split_all_curves_coming_into_clumps(DLIList<VERTEXClump*> &clumps,
+ std::map <VERTEX*,VERTEXClump*, mapltid> &old_vertex_to_clump_map,
+ std::map <EDGE*, EDGE*, mapltid> &old_edge_to_new_edge_map,
+ double &backoff_distance, DLIList<SPAposition> &split_positions);
+ CubitStatus adjust_backoff_distance(DLIList<VERTEXClump*> &clumps,
+ std::map <VERTEX*,VERTEXClump*, mapltid> &old_vertex_to_clump_map,
+ std::map <EDGE*, EDGE*, mapltid> &old_edge_to_new_edge_map,
+ double &backoff_distance);
+ CubitStatus find_new_edges_between_clumps(DLIList<VERTEXClump*> &clumps,
+ std::map <EDGE*, EDGE*, mapltid> &old_edge_to_new_edge_map,
+ std::map <VERTEXClump*, DLIList<FACE*>*, mapltclump> &surrounding_faces_map);
+ CubitStatus find_new_pos_for_clump(std::map <VERTEXClump*, DLIList<FACE*>*, mapltclump> &surrounding_faces_map,
+ DLIList<FACE*> &faces_to_move,
+ double &size);
+ EDGE* find_common_edge (FACE *f1, FACE *f2);
+ EDGE* find_common_edge (VERTEX *v1, VERTEX *v2);
+ CubitStatus choose_best_face_to_move(DLIList<FACE*> &faces_that_might_move,
+ std::map <FACE*, int, mapltid> &face_clump_count_map,
+ DLIList<VERTEX*> &all_verts_in_clumps);
+ CubitStatus ensure_possible_solution(std::map <VERTEXClump*, DLIList<FACE*>*, mapltclump> &faces_that_dont_intersect_map,
+ DLIList<FACE*> &faces_that_might_move);
+ CubitStatus find_faces_that_dont_intersect(std::map <VERTEXClump*, DLIList<FACE*>*, mapltclump> &surrounding_faces_map,
+ std::map <VERTEXClump*, DLIList<FACE*>*, mapltclump> &faces_that_dont_intersect_map,
+ double &small_dist);
+ CubitStatus find_face_clump_counts(std::map <VERTEXClump*, DLIList<FACE*>*, mapltclump> &surrounding_faces_map,
+ std::map <FACE*, int, mapltid> &face_clump_count_map);
+ int edge_within_clump(EDGE *edge,
+ std::map <VERTEX*,VERTEXClump*, mapltid> &old_vertex_to_clump_map);
+ void point_perp_trimmed(EDGE *edge,
+ SPAposition &pos_in,
+ SPAposition &pos_out,
+ double *param);
+ /*
+ int narrow_region_exists(EDGE *e1,
+ EDGE *e2,
+ FACE *face,
+ const double &tol,
+ DLIList<SPAposition*> &e1_pos_list,
+ DLIList<SPAposition*> &e2_pos_list,
+ DLIList<VERTEX*> &e1_vert_list,
+ DLIList<VERTEX*> &e2_vert_list);
+ int narrow_region_exists(FACE *face, const double &tol);
+ int is_narrow_region_at_point(EDGE *e1,
+ SPAposition &pt_on_e1,
+ EDGE *e2,
+ const double &tol_sq,
+ SPAposition &closest);
+ */
+ CubitStatus find_faces_surrounding_clumps(DLIList<VERTEXClump*> &clumps,
+ std::map <VERTEXClump*, DLIList<FACE*>*, mapltclump> &surrounding_faces_map,
+ DLIList<VERTEX*> &all_verts_in_clumps,
+ std::map <VERTEX*, VERTEXClump*, mapltid> &old_vertex_to_clump_map,
+ DLIList<FACE*> &faces_to_remove);
+ void find_ave_clump_pos(VERTEXClump *&clump);
+ CubitStatus get_all_verts_in_clumps(DLIList<VERTEXClump*> &clumps,
+ DLIList<VERTEX*> &all_verts_in_clumps);
+ void build_old_vertex_to_clump_map(DLIList<VERTEXClump*> &clumps,
+ std::map <VERTEX*, VERTEXClump*, mapltid> &old_vertex_to_clump_map);
+ void get_neighbor_small_edges(EDGE *edge,
+ VERTEX *vert,
+ VERTEXClump *&clump,
+ DLIList<EDGE*> &small_edges);
+ /*
+ void propagate_to_find_other_small_edges(EDGE *edge,
+ VERTEX *cur_vert,
+ DLIList<EDGE*> &small_edges,
+ double small_edge_length);
+ void propagate_over_narrow_face(FACE *narrow_face,
+ EDGE *edge,
+ DLIList<FACE*> &processed_faces,
+ DLIList<EDGE*> &small_edges,
+ double small_edge_length);
+ */
+ CubitStatus setup_clump_map(DLIList<EDGE*> &edges_to_remove,
+ DLIList<FACE*> &faces_to_remove,
+ double small_edge_size,
+ DLIList<VERTEXClump*> &clumps,
+ std::map <VERTEX*, VERTEXClump*, mapltid> &old_vertex_to_clump_map);
+
+};
+
+#endif
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisTweakTool.cpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisTweakTool.cpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisTweakTool.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -9,40 +9,7 @@
#ifdef UNIX_PORT
#include "undefwin_.h"
#endif
-#if CUBIT_ACIS_VERSION < 1100
-#include "kernel/acis.hxx"
-#include "kernel/kernapi/api/api.hxx"
-#include "kernel/kernapi/api/kernapi.hxx"
-#include "kernel/kerndata/geom/point.hxx"
-#include "kernel/kerndata/geom/transfrm.hxx"
-#include "kernel/kerndata/top/edge.hxx"
-#include "kernel/kerndata/top/body.hxx"
-#include "kernel/kerndata/top/face.hxx"
-#include "kernel/kerndata/top/loop.hxx"
-#include "kernel/kerndata/top/wire.hxx"
-#include "kernel/kernutil/law/law.hxx"
-#include "kernel/kerndata/lists/lists.hxx"
-#include "kernel/spline/api/spl_api.hxx"
-#include "cover/kernapi/api/coverapi.hxx"
-#include "blend/kernapi/api/blendapi.hxx"
-#include "intersct/kernapi/api/intrapi.hxx"
-#include "constrct/kernapi/api/cstrapi.hxx"
-#include "skin/kernapi/api/skinapi.hxx"
-#include "offset/kernapi/api/ofstapi.hxx"
-#include "boolean/kernapi/api/boolapi.hxx"
-#include "baseutil/vector/position.hxx"
-#include "baseutil/vector/unitvec.hxx"
-#include "baseutil/logical.h"
-#ifdef ACIS_LOCAL_OPS
- #include "lop_husk/api/lop_api.hxx"
- #include "lopt_husk/api/loptapi.hxx"
- #include "rem_husk/api/rem_api.hxx"
-#endif
-
-#include "kernel/geomhusk/copyent.hxx" // copy single entity
-
-#else
#include "acis.hxx"
#include "api.hxx"
#include "kernapi.hxx"
@@ -52,6 +19,8 @@
#include "coedge.hxx"
#include "loop.hxx"
#include "face.hxx"
+#include "shell.hxx"
+#include "lump.hxx"
#include "body.hxx"
#include "wire.hxx"
#include "law.hxx"
@@ -77,10 +46,12 @@
#include "utils.hxx" // sg_body_to_1d
#include "heal_api.hxx"
#include "rbi_api.hxx"
+#include "at_real.hxx"
+//#include "insanity_list.hxx" // api_check_entity
+#include "warp_api.hxx"
+#include "posarray.hxx"
-#if CUBIT_ACIS_VERSION >= 1600
#include "lop_opts.hxx"
-#endif
#ifdef ACIS_LOCAL_OPS
#include "lop_api.hxx"
@@ -90,7 +61,6 @@
#include "copyent.hxx" // copy_single_entity
#include "acistype.hxx" // is_closed_solid_body
-#endif
#ifdef UNIX_PORT
#include "defwin_.h"
@@ -99,7 +69,7 @@
// ********** BEGIN CUBIT INCLUDES **********
#include "AcisTweakTool.hpp"
-
+#include "AcisTopologyTool.hpp"
#include "AcisQueryEngine.hpp"
#include "AcisModifyEngine.hpp"
#include "GeometryQueryTool.hpp"
@@ -112,17 +82,24 @@
#include "PointACIS.hpp"
#include "DLIList.hpp"
+#include "GfxDebug.hpp"
#include "attrib_cubit_owner.hpp"
#include "CubitUtil.hpp"
-#include "GfxDebug.hpp"
#include "GfxPreview.hpp"
+//#include "GfxDebug.hpp"
#include "AcisDrawTool.hpp"
#include "CubitPlane.hpp"
#include "GMem.hpp"
+#include "RandomMersenne.hpp"
+#include <time.h>
+
+#define MSG if(silent==CUBIT_FALSE)
+//#define GfxPreview GfxDebug
+
// ********** END CUBIT INCLUDES **********
AcisTweakTool* AcisTweakTool::instance_ = 0;
@@ -149,6 +126,8 @@
// For convenience, setup pointers to AcisQueryEngine and AcisModifyEngine
AQE = AcisQueryEngine::instance();
AME = AcisModifyEngine::instance();
+
+ silent = CUBIT_FALSE;
}
AcisTweakTool::~AcisTweakTool()
@@ -160,8248 +139,325 @@
api_terminate_blending();
}
-//=============================================================================
-// Function : tweak_chamfer
-// Member Type: PUBLIC
-// Description: Chamfer curves on solid bodies. The left and right offsets are
-// with respect to the curve direction. If the given right offset
-// is negative, the left offset is used. Users can preview to
-// clarify the meaning of left and right.
-// Author : Eric Nielsen
-// Date :
-//=============================================================================
-CubitStatus
-AcisTweakTool::tweak_chamfer( DLIList<Curve*> &curve_list,
- double left_offset,
- DLIList<BodySM*> &new_bodysm_list,
- double right_offset,
- CubitBoolean keep_old_body,
- CubitBoolean preview )
+CubitStatus AcisTweakTool::tweak_bend( DLIList<BodySM*> &bend_bodies,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitVector& neutral_root,
+ CubitVector& bend_axis,
+ CubitVector& bend_direction,
+ double radius,
+ double angle,
+ DLIList<CubitVector*> bend_regions,
+ double width /*= -1*/,
+ CubitBoolean center_bend /*= CUBIT_FALSE*/,
+ int num_points /*= 0*/,
+ CubitBoolean keep_old_body /*= CUBIT_FALSE*/,
+ CubitBoolean preview /*= CUBIT_FALSE*/)
{
- int i;
- outcome result;
+ /*
+ http://doc.spatial.com/r19/index.php/Entity_Bending
+ outcome api_bend_entity ( ENTITY * in_entity,
+ SPAposition & neutral_root,
+ SPAunit_vector & bend_axis,
+ SPAunit_vector & bend_direction,
+ double radius,
+ double angle,
+ double width = -1,
+ logical f_center_bend = FALSE,
+ int n_points = 0,
+ SPAposition * bend_regions = NULL,
+ AcisOptions * opts = NULL
+ )
+ */
+ int i = 0;
+ int delete_attribs =
+ (GeometryModifyTool::instance()->get_new_ids() || keep_old_body);
- BodySM *body_ptr;
-
- BODY *BODY_ptr;
- BODY *copied_BODY_ptr;
-
- int delete_attribs =
- (GeometryModifyTool::instance()->get_new_ids() || keep_old_body);
-
- if( right_offset <= 0.0 )
- right_offset = left_offset;
-
- // Copy the incoming ref_edge_list since we will be pulling
- // edges out of it.
- DLIList<CurveACIS*> copied_ref_edge_list(curve_list.size());
- CAST_LIST( curve_list, copied_ref_edge_list, CurveACIS );
- if (curve_list.size() != copied_ref_edge_list.size())
- {
- PRINT_ERROR("Non-ACIS Curve found\n");
- return CUBIT_FAILURE;
- }
-
- copied_ref_edge_list.reset();
- while( copied_ref_edge_list.size() )
- {
- DLIList<EDGE*> EDGE_list;
- if( AME->get_copied_EDGES_of_body( copied_ref_edge_list, EDGE_list,
- copied_BODY_ptr ) == CUBIT_FAILURE )
- {
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- // Get original Body and BODY
- body_ptr = AQE->get_body_sm_of_ENTITY( copied_BODY_ptr );
- BODY_ptr = dynamic_cast<BodyACIS*>(body_ptr)->get_BODY_ptr();
-
- // Now, blend the edges on this body
- if( chamfer_edges( EDGE_list, left_offset, right_offset ) == CUBIT_FAILURE )
- {
- api_delent(copied_BODY_ptr);
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- if( !preview )
- {
- // If we've made it this far, the copied_BODY has been
- // modified and we can update it in CUBIT
-
- // Now cleanout the owner attributes from the copied BODY, if required
- if( delete_attribs )
- AQE->remove_cubit_owner_attrib_in_BODY( copied_BODY_ptr );
-
- BodySM* new_body_ptr = AME->get_new_Body( body_ptr, BODY_ptr,
- copied_BODY_ptr, keep_old_body );
-
- if( new_body_ptr )
- new_bodysm_list.append( new_body_ptr );
- }
- else
- {
- GfxPreview::clear(); // should previews always be cleared?
-
- ENTITY_LIST face_list;
- api_get_faces( copied_BODY_ptr, face_list);
- AcisBridge *ab_face_ptr = NULL;
- for( i=0; i<face_list.count(); i++ )
- {
- ab_face_ptr = ATTRIB_CUBIT_OWNER::cubit_owner( face_list[i] );
- if( !ab_face_ptr )
- {
- // Draw this face
- AcisDrawTool::instance()->draw_FACE( (FACE*)face_list[i], CUBIT_BLUE );
- }
- }
-
- api_delent(copied_BODY_ptr);
- }
- }
-
- if( preview )
- GfxPreview::flush();
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : tweak_chamfer
-// Member Type: PUBLIC
-// Description: Chamfer vertices on solid or sheet bodies. On a solid body
-// there can be up to 3 offsets; on a sheet body up to 2 offsets.
-// The offsets are in the direction of the supplied edges. If
-// multiple vertices are supplied, only one offset value is
-// allowed and the edges are not used.
-// Author : Steve Storm
-// Date : 03/28/05
-//=============================================================================
-CubitStatus
-AcisTweakTool::tweak_chamfer( DLIList<Point*> &point_list,
- double offset1,
- DLIList<BodySM*> &new_bodysm_list,
- Curve *edge1,
- double offset2,
- Curve *edge2,
- double offset3,
- Curve *edge3,
- CubitBoolean keep_old_body,
- CubitBoolean preview )
-{
- // Sort out vertices between sheet and solid bodies
- DLIList<Point*> solid_points, sheet_points;
- if( sort_points_by_body_type( point_list, solid_points, sheet_points ) ==
- CUBIT_FAILURE )
- return CUBIT_FAILURE;
-
- // Do simple forms
- if( edge1 == NULL || offset2 <= 0.0 )
- {
- if( tweak_chamfer_solid( solid_points, offset1, new_bodysm_list,
- keep_old_body, preview )== CUBIT_FAILURE )
- return CUBIT_FAILURE;
- return tweak_chamfer_fillet_sheet( sheet_points, offset1, 1,
- new_bodysm_list, keep_old_body, preview );
- }
-
- if( solid_points.size() > 1 || sheet_points.size() > 1 )
- {
- PRINT_ERROR( "cannot chamfer multiple vertices with a variable radius.\n" );
- return CUBIT_FAILURE;
- }
-
- if( solid_points.size() )
- {
- Point *point_ptr = solid_points.get();
- BodySM *bodysm_ptr = NULL;
-
- if( tweak_chamfer_solid( point_ptr, offset1, edge1, offset2, edge2,
- offset3, edge3, bodysm_ptr, keep_old_body, preview ) == CUBIT_FAILURE )
- return CUBIT_FAILURE;
-
- new_bodysm_list.append( bodysm_ptr );
- return CUBIT_SUCCESS;
- }
-
- if( sheet_points.size() )
- {
- Point *point_ptr = sheet_points.get();
- BodySM *bodysm_ptr = NULL;
-
- if( tweak_chamfer_sheet( point_ptr, offset1, edge1, offset2, edge2,
- bodysm_ptr, keep_old_body, preview ) == CUBIT_FAILURE )
- return CUBIT_FAILURE;
-
- new_bodysm_list.append( bodysm_ptr );
- return CUBIT_SUCCESS;
- }
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : tweak_fillet
-// Member Type: PUBLIC
-// Description: Create a round fillet (or blend) at the given curves on solid
-// bodies.
-// Author : Eric Nielsen
-// Date :
-//=============================================================================
-CubitStatus
-AcisTweakTool::tweak_fillet( DLIList<Curve*> &curve_list,
- double radius,
- DLIList<BodySM*> &new_bodysm_list,
- bool keep_old_body,
- CubitBoolean preview )
-{
- int i;
- outcome result;
-
- BodySM *body_ptr;
-
- BODY *BODY_ptr;
- BODY *copied_BODY_ptr;
-
- int delete_attribs =
- (GeometryModifyTool::instance()->get_new_ids() || keep_old_body);
-
- // Copy the incoming ref_edge_list since we will be pulling
- // edges out of it.
- DLIList<CurveACIS*> copied_ref_edge_list(curve_list.size());
- CAST_LIST( curve_list, copied_ref_edge_list, CurveACIS );
- if (curve_list.size() != copied_ref_edge_list.size())
- {
- PRINT_ERROR("Non-ACIS Curve encountered\n");
- return CUBIT_FAILURE;
- }
-
- copied_ref_edge_list.reset();
- while( copied_ref_edge_list.size() )
- {
- DLIList<EDGE*> EDGE_list;
- if( AME->get_copied_EDGES_of_body( copied_ref_edge_list, EDGE_list,
- copied_BODY_ptr ) == CUBIT_FAILURE )
- {
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- // Get original Body and BODY
- body_ptr = AQE->get_body_sm_of_ENTITY( copied_BODY_ptr );
- BODY_ptr = dynamic_cast<BodyACIS*>(body_ptr)->get_BODY_ptr();
-
- if( blend_edges( EDGE_list, radius ) == CUBIT_FAILURE )
- {
- AQE->ACIS_API_error(result);
- api_delent(copied_BODY_ptr);
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- if( !preview )
- {
- // If we've made it this far, the copied_BODY has been
- // modified and we can update it in CUBIT
-
- // Now cleanout the owner attributes from the copied BODY, if required
- if( delete_attribs )
- AQE->remove_cubit_owner_attrib_in_BODY(copied_BODY_ptr);
-
- BodySM* new_body_ptr = AME->get_new_Body( body_ptr, BODY_ptr, copied_BODY_ptr,
- keep_old_body );
-
- if (new_body_ptr)
- new_bodysm_list.append( new_body_ptr );
- }
- else
- {
- GfxPreview::clear();
-
- ENTITY_LIST face_list;
- api_get_faces( copied_BODY_ptr, face_list);
- AcisBridge *ab_face_ptr = NULL;
- for( i=0; i<face_list.count(); i++ )
- {
- ab_face_ptr = ATTRIB_CUBIT_OWNER::cubit_owner( face_list[i] );
- if( !ab_face_ptr )
- {
- // Draw this face
- AcisDrawTool::instance()->draw_FACE( (FACE*)face_list[i], CUBIT_BLUE );
- }
- }
-
- api_delent(copied_BODY_ptr);
- }
- }
-
- if( preview )
- GfxPreview::flush();
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : tweak_fillet
-// Member Type: PUBLIC
-// Description: Create a round fillet (or blend) at the given curves on a solid
-// body. The fillet has a variable radius from the start to the
-// end of the curve.
-// Author : Steve Storm
-// Date : 03/28/05
-//=============================================================================
-CubitStatus AcisTweakTool::tweak_fillet( Curve *curve_ptr,
- double start_radius,
- double end_radius,
- BodySM *&new_bodysm_ptr,
- CubitBoolean keep_old_body,
- CubitBoolean preview )
-{
- outcome result;
-
- BodySM *body_ptr;
-
- BODY *BODY_ptr;
- BODY *copied_BODY_ptr;
-
- int delete_attribs =
- (GeometryModifyTool::instance()->get_new_ids() || keep_old_body);
-
- DLIList<CurveACIS*> copied_curve_list(1);
- CurveACIS *curve_acis_ptr = CAST_TO( curve_ptr, CurveACIS );
- if( curve_acis_ptr == NULL )
- {
- PRINT_ERROR("Non-ACIS Curve encountered\n");
- return CUBIT_FAILURE;
- }
- copied_curve_list.append( curve_acis_ptr );
-
- DLIList<EDGE*> EDGE_list;
- if( AME->get_copied_EDGES_of_body( copied_curve_list, EDGE_list,
- copied_BODY_ptr ) == CUBIT_FAILURE )
- {
- return CUBIT_FAILURE;
- }
-
- // Get original Body and BODY
- body_ptr = AQE->get_body_sm_of_ENTITY( copied_BODY_ptr );
- BODY_ptr = dynamic_cast<BodyACIS*>(body_ptr)->get_BODY_ptr();
-
- EDGE *EDGE_ptr = EDGE_list.get();
- ENTITY_LIST ENTITY_list;
- ENTITY_list.add( EDGE_ptr );
-
- int num_fixes = 2;
- SPAposition pos_array[2];
- pos_array[0] = EDGE_ptr->start_pos();
- pos_array[1] = EDGE_ptr->end_pos();
-
- double fix_radii[2] = { start_radius, end_radius };
-
- // Setup tweak attributes so we can preserve Cubit owners
- DLIList<FACE*> pre_FACE_list;
- DLIList<EDGE*> pre_EDGE_list;
- DLIList<VERTEX*> pre_VERTEX_list;
- DLIList<AcisBridge*> ab_FACE_list, ab_EDGE_list, ab_VERTEX_list;
- assign_tweak_attribs( copied_BODY_ptr, "tweak", pre_FACE_list, ab_FACE_list,
- pre_EDGE_list, ab_EDGE_list, pre_VERTEX_list, ab_VERTEX_list );
-
- // Now, blend the edges on this body
- result = api_blend_edges_pos_rad( ENTITY_list, num_fixes, pos_array, fix_radii );
-
- if( !result.ok() )
- {
- AQE->ACIS_API_error(result);
- api_delent(copied_BODY_ptr);
- return CUBIT_FAILURE;
- }
-
- // Replace Cubit owners
- reassign_cubit_owners_from_tweak_attribs( copied_BODY_ptr, "tweak",
- pre_FACE_list, ab_FACE_list, pre_EDGE_list, ab_EDGE_list, pre_VERTEX_list,
- ab_VERTEX_list );
-
- // Remove tweak attributes
- remove_named_attribs( copied_BODY_ptr, "tweak" );
-
- if( !preview )
- {
- // If we've made it this far, the copied_BODY has been
- // modified and we can update it in CUBIT
-
- // Now cleanout the owner attributes from the copied BODY, if required
- if( delete_attribs )
- AQE->remove_cubit_owner_attrib_in_BODY(copied_BODY_ptr);
-
- new_bodysm_ptr = AME->get_new_Body( body_ptr, BODY_ptr, copied_BODY_ptr,
- keep_old_body );
- }
- else
- {
+ // Clear any previous previews
GfxPreview::clear();
- ENTITY_LIST face_list;
- api_get_faces( copied_BODY_ptr, face_list);
- AcisBridge *ab_face_ptr = NULL;
- int i;
- for( i=0; i<face_list.count(); i++ )
+ position_array regions;
+ for (i = 0; i < num_points; i++)
{
- ab_face_ptr = ATTRIB_CUBIT_OWNER::cubit_owner( face_list[i] );
- if( !ab_face_ptr )
- {
- // Draw this face
- AcisDrawTool::instance()->draw_FACE( (FACE*)face_list[i], CUBIT_BLUE );
- }
+ CubitVector* vector = bend_regions.get_and_step();
+ SPAposition pos(vector->x(), vector->y(), vector->z());
+ regions.Add(pos);
}
- api_delent(copied_BODY_ptr);
+ outcome result;
- GfxPreview::flush();
- }
+ BODY* BODY_ptr;
+ BODY* copied_BODY_ptr;
+ BodySM* body_ptr;
- return CUBIT_SUCCESS;
-}
+ SPAposition acis_neutral_root(neutral_root.x(), neutral_root.y(), neutral_root.z());
+ SPAunit_vector acis_bend_axis(bend_axis.x(), bend_axis.y(), bend_axis.z());
+ SPAunit_vector acis_bend_direction(bend_direction.x(), bend_direction.y(), bend_direction.z());
-//=============================================================================
-// Function : tweak_fillet
-// Member Type: PUBLIC
-// Description: Create a round fillet (or blend) at the given vertices on sheet
-// bodies.
-// Author : Steve Storm
-// Date : 03/28/05
-//=============================================================================
-CubitStatus AcisTweakTool::tweak_fillet( DLIList<Point*> &point_list,
- double radius,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean keep_old_body,
- CubitBoolean preview )
-{
- return tweak_chamfer_fillet_sheet( point_list, radius, 2, new_bodysm_list,
- keep_old_body, preview );
-}
-
-//=============================================================================
-// Function : tweak_move
-// Member Type: PUBLIC
-// Description: Tweak specified faces of a volume or volumes along a vector.
-// Author : Steve Storm
-// Date :
-//=============================================================================
-CubitStatus AcisTweakTool::tweak_move( DLIList<Surface*> &surface_list,
- const CubitVector &delta,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean keep_old_body,
- CubitBoolean preview )
-{
-#ifndef ACIS_LOCAL_OPS
- PRINT_ERROR( "The ACIS Local Operations Husk is required for moving\n"
- " surfaces. It has not been licensed for this installation.\n" );
- return CUBIT_FAILURE;
-#endif
-
- int i;
- int num_faces = 0;
-
- BodySM* body_ptr;
-
- BODY* BODY_ptr;
- BODY* copied_BODY_ptr;
- outcome result;
-
- // Setup translation transform
- SPAtransf tr;
- SPAvector vec(delta.x(), delta.y(), delta.z() );
- tr = translate_transf( vec );
-
- bool delete_attribs =
- (GeometryModifyTool::instance()->get_new_ids() || keep_old_body);
-
- // Copy the incoming surface_list since we will be pulling
- // surfaces out of it.
- DLIList<SurfaceACIS*> copied_surface_list( surface_list.size() );
- if (!get_ACIS_surfaces( surface_list, copied_surface_list ))
- return CUBIT_FAILURE;
-
- copied_surface_list.reset();
- while( copied_surface_list.size() )
- {
- DLIList<FACE*> FACE_list;
- if( AME->get_copied_FACES_of_body( copied_surface_list, FACE_list,
- copied_BODY_ptr ) == CUBIT_FAILURE )
- {
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- // Get original Body and BODY
- body_ptr = AQE->get_body_sm_of_ENTITY( copied_BODY_ptr );
- BODY_ptr = dynamic_cast<BodyACIS*>(body_ptr)->get_BODY_ptr();
-
- // Store moved FACEs for preview
- DLIList<AcisBridge*> preview_ab_list;
- if( preview ) get_owner_list( FACE_list, preview_ab_list );
-
- // Now, move the surfaces on this body
- num_faces = FACE_list.size();
- FACE** move_FACES = new FACE*[num_faces];
- for( i=0; i<num_faces; i++ )
- move_FACES[i] = FACE_list.get_and_step();
-
- SPAposition box_l(0,0,0);
- SPAposition box_h(0,0,0);
-
- // Setup tweak attributes so we can preserve Cubit owners
- DLIList<FACE*> pre_FACE_list;
- DLIList<EDGE*> pre_EDGE_list;
- DLIList<VERTEX*> pre_VERTEX_list;
- DLIList<AcisBridge*> ab_FACE_list, ab_EDGE_list, ab_VERTEX_list;
- // This operation sometimes destroys owner attributes
- AcisBridge *ab_body_ptr;
- AcisBridge *ab_lump_ptr;
- AcisBridge *ab_shell_ptr;
- if( !delete_attribs )
- {
- assign_tweak_attribs( copied_BODY_ptr, "tweak", pre_FACE_list, ab_FACE_list,
- pre_EDGE_list, ab_EDGE_list, pre_VERTEX_list, ab_VERTEX_list );
- get_owner_attribs( copied_BODY_ptr, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
- }
-
- result = api_move_faces( num_faces, move_FACES, tr, box_l, box_h );
-
- delete [] move_FACES;
-
- // Replace Cubit owners
- if( !delete_attribs )
- {
- reassign_cubit_owners_from_tweak_attribs( copied_BODY_ptr, "tweak",
- pre_FACE_list, ab_FACE_list, pre_EDGE_list, ab_EDGE_list, pre_VERTEX_list,
- ab_VERTEX_list );
- reset_owner_attribs( copied_BODY_ptr, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
- // Remove tweak attributes
- remove_named_attribs( copied_BODY_ptr, "tweak" );
- }
-
- if( !result.ok() )
+ for (i = 0; i < bend_bodies.size(); i++)
{
- AQE->ACIS_API_error(result);
- api_delent(copied_BODY_ptr);
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
+ body_ptr = bend_bodies.get_and_step();
+ BODY_ptr = dynamic_cast<BodyACIS*>(body_ptr)->get_BODY_ptr();
- if( !preview )
- {
- // Now cleanout the owner attributes from the copied BODY, if required
- if( delete_attribs )
- AQE->remove_cubit_owner_attrib_in_BODY(copied_BODY_ptr);
-
- // If we've made it this far, the copied_BODY has been
- // modified and we can update it in CUBIT
- BodySM* new_body_ptr =
- AME->get_new_Body( body_ptr, BODY_ptr, copied_BODY_ptr, keep_old_body );
-
- if( new_body_ptr )
- new_bodysm_list.append( new_body_ptr );
- }
- else
- {
- GfxPreview::clear();
-
- // Draw preview EDGEs
- draw_tweak_preview_omt( copied_BODY_ptr, CUBIT_TRUE, &preview_ab_list );
- api_delent( copied_BODY_ptr );
- }
- }
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : tweak_move
-// Member Type: PUBLIC
-// Description: Tweak specified curves of a sheet body along a vector.
-// Author : Steve Storm
-// Date : 03/28/05
-//=============================================================================
-CubitStatus AcisTweakTool::tweak_move( DLIList<Curve*> &input_curve_list,
- const CubitVector &delta,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean keep_old_bodies,
- CubitBoolean preview )
-{
-#ifndef ACIS_LOCAL_OPS
- PRINT_ERROR( "The ACIS Local Operations Husk is required for tweaking\n"
- " curves. It has not been licensed for this installation.\n" );
- return CUBIT_FAILURE;
-#endif
-
- int i, j;
- outcome result;
-
- // Setup translation transform
- SPAtransf tr;
- SPAvector vec(delta.x(), delta.y(), delta.z() );
- tr = translate_transf( vec );
-
- bool delete_attribs =
- (GeometryModifyTool::instance()->get_new_ids() || keep_old_bodies);
-
- // Get ACIS EDGEs
- DLIList<EDGE*> input_EDGE_list;
- if( get_EDGEs( input_curve_list, input_EDGE_list )== CUBIT_FAILURE )
- return CUBIT_FAILURE;
-
- input_EDGE_list.reset();
- while( input_EDGE_list.size() )
- {
- BODY *BODY_ptr;
- DLIList<EDGE*> removed_EDGE_list;
- DLIList<BODY*> thickened_BODY_list;
- DLIList<DLIList<EDGE*>*> output_EDGE_lists;
- DLIList<DLIList<FACE*>*> output_FACE_lists;
- DLIList<DLIList<FACE*>*> conjugate_FACE_lists;
- if( get_thickened_BODIES_of_EDGES( "tweak", input_EDGE_list,
- removed_EDGE_list, BODY_ptr, thickened_BODY_list, output_EDGE_lists,
- output_FACE_lists, conjugate_FACE_lists ) == CUBIT_FAILURE )
- {
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- BodySM *bodysm_ptr = AQE->get_body_sm_of_ENTITY( BODY_ptr );
-
- // Remove the surfaces on the output BODIEs
- // First copy the BODY
- BODY *copied_BODY_ptr = AME->copy_BODY(BODY_ptr, CUBIT_FALSE);
-
- // Store moved EDGEs for preview
- DLIList<AcisBridge*> preview_ab_list;
- if( preview ) get_owner_list( removed_EDGE_list, preview_ab_list );
-
- int num_faces;
- BODY *thickened_BODY_ptr;
- DLIList<FACE*> *output_FACE_list_ptr;
- DLIList<FACE*> *conjugate_FACE_list_ptr;
- thickened_BODY_list.reset();
- output_EDGE_lists.reset();
- output_FACE_lists.reset();
- conjugate_FACE_lists.reset();
- for( i=thickened_BODY_list.size(); i--; )
- {
- thickened_BODY_ptr = thickened_BODY_list.get_and_step();
- output_FACE_list_ptr = output_FACE_lists.get_and_step();
- conjugate_FACE_list_ptr = conjugate_FACE_lists.get_and_step();
-
- // Note - the conjugate FACE list can have duplicate entries in
- // it, as thicken doesn't always create a separate surface for
- // each curve.
- DLIList<FACE*> tweak_FACE_list;
- conjugate_FACE_list_ptr->reset();
- for( j=conjugate_FACE_list_ptr->size(); j--; )
- tweak_FACE_list.append_unique( conjugate_FACE_list_ptr->get_and_step() );
-
- // Keep track of the FACEs of interest, via their Cubit owners, which
- // will survive throughout the operation
- DLIList<AcisBridge*> owner_list;
- get_owner_list( *output_FACE_list_ptr, owner_list );
-
- num_faces = tweak_FACE_list.size();
-
- FACE** FACES = new FACE*[num_faces];
- output_FACE_list_ptr->reset();
- for( j=0; j<num_faces; j++ )
- FACES[j] = tweak_FACE_list.get_and_step();
-
- SPAposition box_l(0,0,0);
- SPAposition box_h(0,0,0);
-
- result = api_move_faces( num_faces, FACES, tr, box_l, box_h );
-
- delete [] FACES;
-
- if( !result.ok() )
- {
- AQE->ACIS_API_error(result);
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( conjugate_FACE_lists.size() ) delete conjugate_FACE_lists.pop();
- while( thickened_BODY_list.size() )
- api_delent( thickened_BODY_list.pop() );
- api_delent( copied_BODY_ptr );
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- // Get bodies ready to swap new surfaces for old
- if( prep_for_surface_swap( thickened_BODY_ptr, copied_BODY_ptr,
- owner_list ) == CUBIT_FAILURE )
- {
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( conjugate_FACE_lists.size() ) delete conjugate_FACE_lists.pop();
- while( thickened_BODY_list.size() )
- api_delent( thickened_BODY_list.pop() );
- api_delent( copied_BODY_ptr );
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
- } // End loop on thickened (separated) BODIES
-
- // Free memory
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( conjugate_FACE_lists.size() ) delete conjugate_FACE_lists.pop();
-
- // Unite the thickened BODIEs back into the copied_BODY_ptr
- BODY *master;
- if( unite_BODIES( copied_BODY_ptr, thickened_BODY_list, master ) == CUBIT_FAILURE )
- {
- // If failure, the unite_BODIES function cleaned up the memory
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- // This BODY is done (whew!)
-
- if( !preview )
- {
- // Now cleanout the owner attributes from the copied BODY, if required
- if( delete_attribs )
- AQE->remove_cubit_owner_attrib_in_BODY( master );
-
- BodySM *new_body = AME->get_new_Body( bodysm_ptr, BODY_ptr, master,
- keep_old_bodies );
-
- if( new_body )
- new_bodysm_list.append( new_body );
- }
- else
- {
- GfxPreview::clear();
-
- // Draw preview EDGEs
- draw_tweak_preview_omt( copied_BODY_ptr, CUBIT_TRUE, &preview_ab_list );
- api_delent( master );
- }
- }
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : tweak_offset
-// Member Type: PUBLIC
-// Description: Tweak specified faces of a volume or volumes by offsetting
-// those faces by the offset distance.
-// Author : Steve Storm
-// Date :
-//=============================================================================
-CubitStatus
-AcisTweakTool::tweak_offset( DLIList<Surface*> &surface_list,
- double offset_distance,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean keep_old_body,
- CubitBoolean preview )
-{
-#ifndef ACIS_LOCAL_OPS
- PRINT_ERROR( "The ACIS Local Operations Husk is required for offsetting\n"
- " surfaces. It has not been licensed for this installation.\n" );
- return CUBIT_FAILURE;
-#endif
-
- int i;
- outcome result;
-
- // Copy the incoming surface_list since we will be pulling surfaces out of
- // it.
-
- BodySM *body_ptr;
-
- BODY *BODY_ptr;
- BODY *copied_BODY_ptr;
-
- bool delete_attribs =
- (GeometryModifyTool::instance()->get_new_ids() || keep_old_body);
-
- // Copy the incoming surface_list since we will be pulling surfaces out of
- // it.
- DLIList<SurfaceACIS*> copied_surface_list( surface_list.size() );
- if (!get_ACIS_surfaces( surface_list, copied_surface_list ))
- return CUBIT_FAILURE;
-
- copied_surface_list.reset();
- while( copied_surface_list.size() )
- {
- DLIList<FACE*> FACE_list;
- if( AME->get_copied_FACES_of_body( copied_surface_list, FACE_list,
- copied_BODY_ptr ) == CUBIT_FAILURE )
- {
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- // Get original Body and BODY
- body_ptr = AQE->get_body_sm_of_ENTITY( copied_BODY_ptr );
- BODY_ptr = dynamic_cast<BodyACIS*>(body_ptr)->get_BODY_ptr();
-
- // Store offset FACEs for preview
- DLIList<AcisBridge*> preview_ab_list;
- if( preview ) get_owner_list( FACE_list, preview_ab_list );
-
- // Now, offset the surfaces on this body
- int num_offsets = FACE_list.size();
- FACE** offset_FACES = new FACE*[num_offsets];
- for( i=0; i<num_offsets; i++ )
- offset_FACES[i] = FACE_list.get_and_step();
-
- SPAposition box_l(0,0,0);
- SPAposition box_h(0,0,0);
-
- //This has been added as a temporary fix for bug #5559.
- //Lump attrib should persist across offset operation, but does not
- //ENTITY_LIST lump_list;
- //api_get_lumps(copied_BODY_ptr, lump_list);
- //AcisBridge *lump_owner_before = ATTRIB_CUBIT_OWNER::cubit_owner(lump_list[0]);
-
- // Setup tweak attributes so we can preserve Cubit owners
- DLIList<FACE*> pre_FACE_list;
- DLIList<EDGE*> pre_EDGE_list;
- DLIList<VERTEX*> pre_VERTEX_list;
- DLIList<AcisBridge*> ab_FACE_list, ab_EDGE_list, ab_VERTEX_list;
- // This operation sometimes destroys owner attributes
- AcisBridge *ab_body_ptr;
- AcisBridge *ab_lump_ptr;
- AcisBridge *ab_shell_ptr;
- if( !delete_attribs )
- {
- assign_tweak_attribs( copied_BODY_ptr, "tweak", pre_FACE_list, ab_FACE_list,
- pre_EDGE_list, ab_EDGE_list, pre_VERTEX_list, ab_VERTEX_list );
- get_owner_attribs( copied_BODY_ptr, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
- }
-
- result = api_offset_faces( num_offsets, offset_FACES, offset_distance,
- box_l, box_h );
- delete [] offset_FACES;
-
- if( !result.ok() )
- {
- AQE->ACIS_API_error(result);
- api_delent(copied_BODY_ptr);
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- if( !preview )
- {
- // Now cleanout the owner attributes from the copied BODY, if required
- if( delete_attribs )
- AQE->remove_cubit_owner_attrib_in_BODY( copied_BODY_ptr );
- else
- {
- /*
- //continued temporary fix for bug #5559
- lump_list.clear();
- api_get_lumps(copied_BODY_ptr, lump_list);
- AcisBridge *lump_owner_after = ATTRIB_CUBIT_OWNER::cubit_owner(lump_list[0]);
- if( lump_owner_after == NULL )
- ATTRIB_CUBIT_OWNER::set_cubit_owner( lump_list[0], lump_owner_before );
- */
-
- // Replace Cubit owners
- if( !delete_attribs )
- {
- reassign_cubit_owners_from_tweak_attribs( copied_BODY_ptr, "tweak",
- pre_FACE_list, ab_FACE_list, pre_EDGE_list, ab_EDGE_list, pre_VERTEX_list,
- ab_VERTEX_list );
- reset_owner_attribs( copied_BODY_ptr, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
-
- // Remove tweak attributes
- remove_named_attribs( copied_BODY_ptr, "tweak" );
- }
- }
-
- BodySM *new_body_ptr = AME->get_new_Body( body_ptr, BODY_ptr,
- copied_BODY_ptr, keep_old_body );
-
- if( new_body_ptr )
- new_bodysm_list.append( new_body_ptr );
- }
- else
- {
- GfxPreview::clear();
-
- // Draw preview EDGEs
- draw_tweak_preview_omt( copied_BODY_ptr, CUBIT_TRUE, &preview_ab_list );
- api_delent( copied_BODY_ptr );
- }
- }
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : tweak_offset
-// Member Type: PUBLIC
-// Description: Tweak specified curves of a sheet body or bodies by offsetting
-// those curves by the offset distance.
-// Author :
-// Date :
-//=============================================================================
-CubitStatus AcisTweakTool::tweak_offset( DLIList<Curve*> &input_curve_list,
- double offset_distance,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean keep_old_bodies,
- CubitBoolean preview )
-{
-#ifndef ACIS_LOCAL_OPS
- PRINT_ERROR( "The ACIS Local Operations Husk is required for tweaking\n"
- " curves. It has not been licensed for this installation.\n" );
- return CUBIT_FAILURE;
-#endif
-
- int i, j;
- outcome result;
-
- bool delete_attribs =
- (GeometryModifyTool::instance()->get_new_ids() || keep_old_bodies);
-
- // Get ACIS EDGEs
- DLIList<EDGE*> input_EDGE_list;
- if( get_EDGEs( input_curve_list, input_EDGE_list ) == CUBIT_FAILURE )
- return CUBIT_FAILURE;
-
- input_EDGE_list.reset();
- while( input_EDGE_list.size() )
- {
- BODY *BODY_ptr;
- DLIList<EDGE*> removed_EDGE_list;
- DLIList<BODY*> thickened_BODY_list;
- DLIList<DLIList<EDGE*>*> output_EDGE_lists;
- DLIList<DLIList<FACE*>*> output_FACE_lists;
- DLIList<DLIList<FACE*>*> conjugate_FACE_lists;
- if( get_thickened_BODIES_of_EDGES( "tweak", input_EDGE_list,
- removed_EDGE_list, BODY_ptr, thickened_BODY_list, output_EDGE_lists,
- output_FACE_lists, conjugate_FACE_lists ) == CUBIT_FAILURE )
- {
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- // Get the BodySM from the BODY
- BodySM *bodysm_ptr = AQE->get_body_sm_of_ENTITY( BODY_ptr );
-
- // Remove the surfaces on the output BODIEs
-
- // Copy the BODY with all owner attributes intact
- BODY *copied_BODY_ptr = AME->copy_BODY( BODY_ptr, CUBIT_FALSE );
-
- // Store offset EdGEs for preview
- DLIList<AcisBridge*> preview_ab_list;
- if( preview ) get_owner_list( removed_EDGE_list, preview_ab_list );
-
- int num_faces;
- BODY *thickened_BODY_ptr;
- DLIList<FACE*> *output_FACE_list_ptr;
- DLIList<FACE*> *conjugate_FACE_list_ptr;
- thickened_BODY_list.reset();
- output_EDGE_lists.reset();
- output_FACE_lists.reset();
- conjugate_FACE_lists.reset();
- for( i=thickened_BODY_list.size(); i--; )
- {
- thickened_BODY_ptr = thickened_BODY_list.get_and_step();
- output_FACE_list_ptr = output_FACE_lists.get_and_step();
- conjugate_FACE_list_ptr = conjugate_FACE_lists.get_and_step();
-
- // Note - the conjugate FACE list can have duplicate entries in
- // it, as thicken doesn't always create a separate surface for
- // each curve.
- DLIList<FACE*> tweak_FACE_list;
- conjugate_FACE_list_ptr->reset();
- for( j=conjugate_FACE_list_ptr->size(); j--; )
- tweak_FACE_list.append_unique( conjugate_FACE_list_ptr->get_and_step() );
-
- // Keep track of the FACEs of interest, via their Cubit owners, which
- // will survive throughout the operation
- DLIList<AcisBridge*> owner_list;
- get_owner_list( *output_FACE_list_ptr, owner_list );
-
- num_faces = tweak_FACE_list.size();
-
- FACE** FACES = new FACE*[num_faces];
- output_FACE_list_ptr->reset();
- for( j=0; j<num_faces; j++ )
- FACES[j] = tweak_FACE_list.get_and_step();
-
- SPAposition box_l(0,0,0);
- SPAposition box_h(0,0,0);
-
-#ifdef ACIS_LOCAL_OPS
- result = api_offset_faces( num_faces, FACES, offset_distance,
- box_l, box_h );
-#endif
-
- delete [] FACES;
-
- if( !result.ok() )
- {
- AQE->ACIS_API_error(result);
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( conjugate_FACE_lists.size() ) delete conjugate_FACE_lists.pop();
- while( thickened_BODY_list.size() )
- api_delent( thickened_BODY_list.pop() );
- api_delent( copied_BODY_ptr );
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- // Get bodies ready to swap new surfaces for old
- if( prep_for_surface_swap( thickened_BODY_ptr, copied_BODY_ptr,
- owner_list ) == CUBIT_FAILURE )
- {
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( conjugate_FACE_lists.size() ) delete conjugate_FACE_lists.pop();
- while( thickened_BODY_list.size() )
- api_delent( thickened_BODY_list.pop() );
- api_delent( copied_BODY_ptr );
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
- } // End loop on thickened (separated) BODIES
-
- // Free memory
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( conjugate_FACE_lists.size() ) delete conjugate_FACE_lists.pop();
-
- // Unite the thickened BODIEs back into the copied_input_BODY_ptr
- BODY *master;
- if( unite_BODIES( copied_BODY_ptr, thickened_BODY_list, master )
- == CUBIT_FAILURE )
- {
- // If failure, the unite_BODIES function cleaned up the memory
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- // This BODY is done (whew!)
-
- if( !preview )
- {
- // Now cleanout the owner attributes from the copied BODY, if required
- if( delete_attribs )
- AQE->remove_cubit_owner_attrib_in_BODY( master );
-
- BodySM *new_body = AME->get_new_Body( bodysm_ptr, BODY_ptr, master,
- keep_old_bodies );
-
- if( new_body )
- new_bodysm_list.append( new_body );
- }
- else
- {
- GfxPreview::clear();
-
- // Draw preview EDGEs
- draw_tweak_preview_omt( master, CUBIT_TRUE, &preview_ab_list );
- api_delent( master );
- }
- }
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : tweak_remove
-// Member Type: PUBLIC
-// Description: Function to remove surfaces from a body and then extend the
-// remaining surfaces to fill the gap or hole.
-// Author : Steve Storm
-// Date : 03/28/05
-//=============================================================================
-CubitStatus AcisTweakTool::tweak_remove( DLIList<Surface*> &surface_list,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean extend_adjoining,
- CubitBoolean keep_surface,
- CubitBoolean keep_old_body,
- CubitBoolean preview )
-{
-#ifndef ACIS_LOCAL_OPS
- if( extend_adjoining )
- {
- PRINT_ERROR( "The ACIS Local Operations Husk is required for extending\n"
- " adjoining surfaces. It has not been licensed for this\n"
- " installation.\n" );
- return CUBIT_FAILURE;
- }
-#endif
-
- int i;
- outcome result;
-
- // Copy the incoming surface_list since we will be pulling
- // surfaces out of it.
- DLIList<SurfaceACIS*> copied_surface_list(surface_list.size());
- if (!get_ACIS_surfaces( surface_list, copied_surface_list ))
- return CUBIT_FAILURE;
-
- BodySM *body_ptr;
-
- BODY *BODY_ptr;
- BODY *copied_BODY_ptr;
- FACE *FACE_ptr;
- ENTITY *copied_entity_ptr;
- DLIList<FACE*> kept_FACE_list, remove_FACE_list;
- DLIList<SurfaceACIS*> body_remove_face_list;
-
- bool delete_attribs =
- (GeometryModifyTool::instance()->get_new_ids() || keep_old_body);
-
- // Remove sometimes destroys the owner attributes, so we keep track of them
- AcisBridge *ab_body_ptr;
- AcisBridge *ab_lump_ptr;
- AcisBridge *ab_shell_ptr;
-
- copied_surface_list.reset();
- while( copied_surface_list.size() )
- {
- remove_FACE_list.clean_out();
- body_remove_face_list.clean_out();
- if( AME->get_copied_FACES_of_body( copied_surface_list, remove_FACE_list,
- body_remove_face_list, copied_BODY_ptr ) == CUBIT_FAILURE )
- {
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- // Get original Body and BODY
- body_ptr = AQE->get_body_sm_of_ENTITY( copied_BODY_ptr );
- BODY_ptr = dynamic_cast<BodyACIS*>(body_ptr)->get_BODY_ptr();
-
- // Now cleanout the owner attributes from the copied BODY, if required
- if( delete_attribs )
- AQE->remove_cubit_owner_attrib_in_BODY(copied_BODY_ptr);
-
- // Keep a copy of the surfaces if required
- if( keep_surface && !preview )
- {
- // Make a copy of the FACES to hold onto
- for( i=0; i<remove_FACE_list.size(); i++ )
- {
- FACE_ptr = remove_FACE_list.get_and_step();
- copy_single_entity((ENTITY*)FACE_ptr, copied_entity_ptr);
- kept_FACE_list.append( (FACE*)copied_entity_ptr );
- }
- }
-
- // Finally, remove the faces from this body
- if( extend_adjoining )
- {
- FACE** FACES = new FACE*[remove_FACE_list.size()];
- for( i=0; i<remove_FACE_list.size(); i++ )
- FACES[i] = remove_FACE_list.get_and_step();
-
- // Remove sometimes destroys owner attributes
- // Setup tweak attributes so we can preserve Cubit owners
- DLIList<FACE*> pre_FACE_list;
- DLIList<EDGE*> pre_EDGE_list;
- DLIList<VERTEX*> pre_VERTEX_list;
- DLIList<AcisBridge*> ab_FACE_list, ab_EDGE_list, ab_VERTEX_list;
- if( !delete_attribs )
- {
- get_owner_attribs( copied_BODY_ptr, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
- assign_tweak_attribs( copied_BODY_ptr, "tweak", pre_FACE_list, ab_FACE_list,
- pre_EDGE_list, ab_EDGE_list, pre_VERTEX_list, ab_VERTEX_list );
- }
-
- SPAposition box_l(0,0,0);
- SPAposition box_h(0,0,0);
-
-#ifdef ACIS_LOCAL_OPS
-
- // Add tweak_preview attributes to adjoining FACEs to remove if needed
- if( preview )
- tag_tweak_remove_FACEs_for_preview( copied_BODY_ptr, remove_FACE_list );
-
-#if CUBIT_ACIS_VERSION < 1600
- // When removing FACEs, we don't want ACIS to regularize the volume.
- // Here we set the EDGEs not owned by the FACEs being removed as not
- // mergeable so they persist through the removal operation.
-
- // Get all the EDGEs on the BODY
- ENTITY_LIST body_edges;
- api_get_edges( copied_BODY_ptr, body_edges );
-
- // Get all the EDGEs on the FACE to remove
- ENTITY_LIST surf_edges;
- for( i=0; i<remove_FACE_list.size(); i++ )
- api_get_edges( remove_FACE_list.get_and_step(), surf_edges );
-
- // Remove all EDGEs of the FACE to remove
- body_edges.remove( surf_edges );
-
- // Set the EDGEs as not mergeable
- api_set_no_merge_attrib( body_edges );
-#endif
-
- if( !preview )
- PRINT_INFO( "Removing %d surface(s) from volume...\n", remove_FACE_list.size() );
- else
- PRINT_INFO( "Previewing removal of %d surface(s) from volume...\n", remove_FACE_list.size() );
-
- result = api_remove_faces( remove_FACE_list.size(), FACES, box_l, box_h );
-
-#if CUBIT_ACIS_VERSION < 1600
- // Remove the merge attributes
- body_edges.clear();
- api_get_edges( copied_BODY_ptr, body_edges );
- api_remove_no_merge_attrib( body_edges );
-#endif
-
- delete [] FACES;
-
- if( !result.ok() )
- {
- PRINT_INFO("result was bad....\n");
- AQE->ACIS_API_error(result);
- api_delent(copied_BODY_ptr);
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
- else if( !preview )
- PRINT_INFO( "Successfully removed surfaces from volume\n" );
- else
- PRINT_INFO( "Successfully previewed removal of surfaces from volume\n" );
-
-
- if( !delete_attribs )
- {
- reset_owner_attribs( copied_BODY_ptr, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
-
- // Replace Cubit owners
- reassign_cubit_owners_from_tweak_attribs( copied_BODY_ptr, "tweak",
- pre_FACE_list, ab_FACE_list, pre_EDGE_list, ab_EDGE_list, pre_VERTEX_list,
- ab_VERTEX_list );
-
- // Remove tweak attributes
- remove_named_attribs( copied_BODY_ptr, "tweak" );
- }
-#endif
- }
- else
- {
- // Just unhook the faces (if previewing do this anyway to check for
- // errors)
- for( i=0; i<remove_FACE_list.size(); i++ )
- {
+ // Copy the BODY
+ copied_BODY_ptr = AME->copy_BODY(BODY_ptr, CUBIT_FALSE);
- //make sure we're not trying to unhook the last face
- ENTITY_LIST tmp_face_list;
- api_get_faces( copied_BODY_ptr, tmp_face_list);
+ result = api_bend_entity(copied_BODY_ptr,
+ acis_neutral_root,
+ acis_bend_axis,
+ acis_bend_direction,
+ radius,
+ angle,
+ width,
+ center_bend,
+ num_points,
+ regions //acis_bend_regions
+ );
- if( tmp_face_list.count() == 1 )
- {
- AcisBridge *tmp_bridge = ATTRIB_CUBIT_OWNER::cubit_owner( copied_BODY_ptr );
- if( tmp_bridge )
- {
- BodyACIS *tmp_acis_body = CAST_TO( tmp_bridge, BodyACIS );
- Body *tmp_body = CAST_TO(tmp_acis_body->topology_entity(), Body );
- PRINT_WARNING("Will not remove ALL faces from body %d\n", tmp_body->id() );
- }
- continue;
- }
-
- BODY *new_BODY;
- FACE_ptr = remove_FACE_list.get_and_step();
-
- result = api_unhook_face( FACE_ptr, new_BODY );
-
- if( !result.ok() )
- {
- AQE->ACIS_API_error(result);
- api_delent(copied_BODY_ptr);
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- if( preview )
- {
- GfxPreview::clear();
-
- AcisDrawTool::instance()->draw_ENTITY( new_BODY, CUBIT_BLUE,
- CUBIT_FALSE, CUBIT_TRUE );
- }
-
- // This function puts the pulled-off FACE into a sheet
- // body. No need to keep this - we copied the surfaces
- // before if the keep_surface flag is on.
- api_delent( new_BODY );
- }
- }
-
- // If we are keeping the pulled-off surfaces, just make free RefFaces from
- // them.
- if( keep_surface && !preview )
- {
- for( i=0; i<kept_FACE_list.size(); i++ )
- {
- FACE* kept_FACE = kept_FACE_list.get_and_step();
- FACE *face_list[1];
- face_list[0] = kept_FACE;
- BODY *sheet_BODY_ptr = NULL;
- result = api_sheet_from_ff( 1, face_list, sheet_BODY_ptr );
- api_body_to_2d( sheet_BODY_ptr );
-
- if( !result.ok() )
- {
- PRINT_ERROR("Problem with 'keepsurface' option\n" );
- }
- else
- {
- BodySM *body_ptr = AQE->populate_topology_bridges( sheet_BODY_ptr );
- DLIList<Surface*> tmp_surfs;
- body_ptr->surfaces( tmp_surfs );
- Surface *surface_ptr = tmp_surfs.get();
- GeometryModifyTool::instance()->make_Body( surface_ptr );
- }
- }
- }
-
- // If we've made it this far, the copied_BODY has been modified and we can
- // update it in CUBIT
- if( !preview )
- {
- BodySM *new_body = AME->get_new_Body( body_ptr, BODY_ptr,
- copied_BODY_ptr, keep_old_body );
-
- if( new_body )
- new_bodysm_list.append( new_body );
- }
- else if( extend_adjoining ) // Only case we need to preview
- {
- GfxPreview::clear();
-
- draw_tweak_preview_tagged_FACEs( copied_BODY_ptr, CUBIT_TRUE );
- api_delent( copied_BODY_ptr );
- }
- }
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : tweak_remove
-// Member Type: PUBLIC
-// Description: Function to remove curves from a sheet body and then extend the
-// remaining curves or fill the gap or hole.
-// Author : Steve Storm
-// Date : 03/28/05
-//=============================================================================
-CubitStatus
-AcisTweakTool::tweak_remove( DLIList<Curve*> &input_curve_list,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean keep_old_bodies,
- CubitBoolean preview )
-{
- int i, j, k;
- outcome result;
-
- bool delete_attribs =
- (GeometryModifyTool::instance()->get_new_ids() || keep_old_bodies);
-
- // We have a very efficient way to remove internal loops, so if all curves
- // being removed on a given body are internal loops, we do that with a
- // special case first. We will loop on each set of EDGEs from a common
- // BODY.
- DLIList<BODY*> BODY_list;
- DLIList<DLIList<EDGE*>*> BODY_EDGE_lists;
- if( get_EDGES_by_BODY( input_curve_list, BODY_list, BODY_EDGE_lists )
- == CUBIT_FAILURE )
- return CUBIT_FAILURE;
-
- BODY *BODY_ptr;
- BodySM *bodysm_ptr;
- DLIList<EDGE*> *BODY_EDGE_list_ptr;
- BODY_list.reset();
- BODY_EDGE_lists.reset();
- for( i=BODY_EDGE_lists.size(); i--; )
- {
- BODY_ptr = BODY_list.get_and_step();
- BODY_EDGE_list_ptr = BODY_EDGE_lists.get_and_step();
-
- // Get the BodySM from the BODY
- bodysm_ptr = AQE->get_body_sm_of_ENTITY( BODY_ptr );
-
- // Copy the BODY with all owner attributes intact
- BODY *copied_BODY_ptr = AME->copy_BODY( BODY_ptr, CUBIT_FALSE );
-
- DLIList<LOOP*> LOOP_list;
- if( all_complete_internal_loops( *BODY_EDGE_list_ptr, LOOP_list )
- == CUBIT_SUCCESS )
- {
- // Efficiently remove these LOOPS
-
- // Get the LOOPs to remove on the copied BODY
- DLIList<AcisBridge*> owner_list;
- get_owner_list( LOOP_list, owner_list );
- DLIList<LOOP*> copied_LOOP_list;
- get_corresponding_LOOP_list( owner_list, copied_BODY_ptr, copied_LOOP_list );
-
- // Tag EDGEs for preview
- if( preview )
- {
- LOOP *LOOP_ptr;
- for( j=copied_LOOP_list.size(); j--; )
+ if (!result.ok())
{
- LOOP_ptr = copied_LOOP_list.get_and_step();
- DLIList<EDGE*> LOOP_EDGE_list;
- AQE->get_EDGEs( LOOP_ptr, LOOP_EDGE_list );
- tag_tweak_remove_FACEs_for_preview( copied_BODY_ptr, LOOP_EDGE_list );
+ AQE->ACIS_API_error(result);
+ api_delent(copied_BODY_ptr);
+ return CUBIT_FAILURE;
}
- }
- if( remove_LOOPs( copied_LOOP_list ) == CUBIT_SUCCESS )
- {
- if( !preview )
+ if (!preview)
{
- // Now cleanout the owner attributes from the copied BODY, if required
- if( delete_attribs )
- AQE->remove_cubit_owner_attrib_in_BODY(copied_BODY_ptr);
+ // Now cleanout the owner attributes from the copied BODY, if required
+ if (delete_attribs)
+ AQE->remove_cubit_owner_attrib_in_BODY(copied_BODY_ptr);
- BodySM *new_body = AME->get_new_Body( bodysm_ptr, BODY_ptr,
- copied_BODY_ptr, keep_old_bodies );
+ BodySM* new_body_ptr = AME->get_new_Body(body_ptr, BODY_ptr,
+ copied_BODY_ptr, keep_old_body);
- if( new_body )
- new_bodysm_list.append( new_body );
+ /*BODY* temp_BODY_ptr = dynamic_cast<BodyACIS*>(new_body_ptr)->get_BODY_ptr();
+ AcisDrawTool::instance()->draw_ENTITY( temp_BODY_ptr, CUBIT_BLUE,
+ CUBIT_TRUE, CUBIT_TRUE );
+ AcisDrawTool::instance()->draw_ENTITY( temp_BODY_ptr, CUBIT_BLUE,
+ CUBIT_FALSE, CUBIT_TRUE );
+ GfxPreview::flush();//*/
+
+ if (new_body_ptr)
+ new_bodysm_list.append(new_body_ptr);
}
else
{
- GfxPreview::clear();
+ // draw preview
+ AcisDrawTool::instance()->draw_ENTITY( copied_BODY_ptr, CUBIT_BLUE,
+ CUBIT_FALSE, CUBIT_TRUE );
- draw_tweak_preview_tagged_FACEs( copied_BODY_ptr, CUBIT_TRUE );
- api_delent( copied_BODY_ptr );
+ api_delent(copied_BODY_ptr);
}
- }
- else
- {
- // Cleanup memory
- while( BODY_EDGE_lists.size() ) delete BODY_EDGE_lists.pop();
- api_delent( copied_BODY_ptr );
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
+
}
- // For this BODY, all curves to remove are not complete loops
- else
- {
- // Remove sometimes destroys the owner attributes
- AcisBridge *ab_body_ptr;
- AcisBridge *ab_lump_ptr;
- AcisBridge *ab_shell_ptr;
- BODY *BODY_ptr2;
- DLIList<EDGE*> removed_EDGE_list;
- DLIList<BODY*> thickened_BODY_list;
- DLIList<DLIList<EDGE*>*> output_EDGE_lists;
- DLIList<DLIList<FACE*>*> output_FACE_lists;
- DLIList<DLIList<FACE*>*> conjugate_FACE_lists;
- if( get_thickened_BODIES_of_EDGES( "tweak", *BODY_EDGE_list_ptr,
- removed_EDGE_list, BODY_ptr2, thickened_BODY_list, output_EDGE_lists,
- output_FACE_lists, conjugate_FACE_lists ) == CUBIT_FAILURE )
- {
- // Cleanup memory
- while( BODY_EDGE_lists.size() ) delete BODY_EDGE_lists.pop();
- api_delent( copied_BODY_ptr );
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- if( BODY_ptr != BODY_ptr2 )
- {
- PRINT_ERROR( "Internal error - please report\n" );
- // Cleanup memory
- while( BODY_EDGE_lists.size() ) delete BODY_EDGE_lists.pop();
- api_delent( copied_BODY_ptr );
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- // Tag EDGEs for preview
- if( preview )
- {
- thickened_BODY_list.reset();
- output_EDGE_lists.reset();
- for( j=output_EDGE_lists.size(); j--; )
- {
- DLIList<EDGE*> *EDGE_list_ptr = output_EDGE_lists.get_and_step();
- BODY *tmp_BODY_ptr = thickened_BODY_list.get_and_step();
- tag_tweak_remove_FACEs_for_preview( tmp_BODY_ptr, *EDGE_list_ptr );
- }
- }
-
- // Remove the surfaces on the output BODIEs
-
- int num_faces;
- BODY *thickened_BODY_ptr;
- DLIList<FACE*> *output_FACE_list_ptr;
- DLIList<FACE*> *conjugate_FACE_list_ptr;
- thickened_BODY_list.reset();
- output_EDGE_lists.reset();
- output_FACE_lists.reset();
- conjugate_FACE_lists.reset();
- for( j=thickened_BODY_list.size(); j--; )
- {
- thickened_BODY_ptr = thickened_BODY_list.get_and_step();
- output_FACE_list_ptr = output_FACE_lists.get_and_step();
- conjugate_FACE_list_ptr = conjugate_FACE_lists.get_and_step();
-
- // Note - the conjugate FACE list can have duplicate entries in
- // it, as thicken doesn't always create a separate surface for
- // each curve.
- DLIList<FACE*> tweak_FACE_list;
- conjugate_FACE_list_ptr->reset();
- for( k=conjugate_FACE_list_ptr->size(); k--; )
- tweak_FACE_list.append_unique( conjugate_FACE_list_ptr->get_and_step() );
-
- // Keep track of the FACEs of interest, via their Cubit owners, which
- // will survive throughout the operation
- DLIList<AcisBridge*> owner_list;
- get_owner_list( *output_FACE_list_ptr, owner_list );
-
- num_faces = tweak_FACE_list.size();
-
- FACE** FACES = new FACE*[num_faces];
- output_FACE_list_ptr->reset();
- for( k=0; k<num_faces; k++ )
- FACES[k] = tweak_FACE_list.get_and_step();
-
- // Remove sometimes destroys owner attributes
- get_owner_attribs( thickened_BODY_ptr, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
-
- SPAposition box_l(0,0,0);
- SPAposition box_h(0,0,0);
-
-#ifdef ACIS_LOCAL_OPS
- result = api_remove_faces( num_faces, FACES, box_l, box_h );
-#endif
-
- delete [] FACES;
-
- if( !result.ok() )
- {
- AQE->ACIS_API_error(result);
- while( BODY_EDGE_lists.size() ) delete BODY_EDGE_lists.pop();
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( conjugate_FACE_lists.size() ) delete conjugate_FACE_lists.pop();
- while( thickened_BODY_list.size() )
- api_delent( thickened_BODY_list.pop() );
- api_delent( copied_BODY_ptr );
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- // Reset the owner attributes
- reset_owner_attribs( thickened_BODY_ptr, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
-
- // Get bodies ready to swap new surfaces for old
- if( prep_for_surface_swap( thickened_BODY_ptr, copied_BODY_ptr,
- owner_list ) == CUBIT_FAILURE )
- {
- while( BODY_EDGE_lists.size() ) delete BODY_EDGE_lists.pop();
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( conjugate_FACE_lists.size() ) delete conjugate_FACE_lists.pop();
- while( thickened_BODY_list.size() )
- api_delent( thickened_BODY_list.pop() );
- api_delent( copied_BODY_ptr );
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
- } // End loop on thickened (separated) BODIES
-
- // Free memory
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( conjugate_FACE_lists.size() ) delete conjugate_FACE_lists.pop();
-
- // Unite the thickened BODIEs back into the copied_BODY_ptr
- BODY *master;
- if( unite_BODIES( copied_BODY_ptr, thickened_BODY_list, master ) == CUBIT_FAILURE )
- {
- // If failure, the unite_BODIES function cleaned up the
- // thickened_BODY_list memory
- while( BODY_EDGE_lists.size() ) delete BODY_EDGE_lists.pop();
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- // This BODY is done (whew!)
-
- if( !preview )
- {
- // Now cleanout the owner attributes from the copied BODY, if required
- if( delete_attribs )
- AQE->remove_cubit_owner_attrib_in_BODY( master );
-
- BodySM *new_body = AME->get_new_Body( bodysm_ptr, BODY_ptr, master,
- keep_old_bodies );
-
- if( new_body )
- new_bodysm_list.append( new_body );
- }
- else
- {
- GfxPreview::clear();
-
- draw_tweak_preview_tagged_FACEs( master, CUBIT_TRUE );
- api_delent( master );
- }
- }
- }
-
- // Free memory
- while( BODY_EDGE_lists.size() ) delete BODY_EDGE_lists.pop();
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : tweak_target
-// Member Type: PUBLIC
-// Description: Tweak specified faces of a volume or volumes up to a set of
-// target surfaces.
-// Author : Steve Storm
-// Date : 10/27/05
-//=============================================================================
-CubitStatus AcisTweakTool::tweak_target( DLIList<Surface*> &input_surface_list,
- DLIList<Surface*> &target_surf_list,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean reverse_flg,
- CubitBoolean keep_old_body,
- CubitBoolean preview )
-{
-#ifndef ACIS_LOCAL_OPS
- PRINT_ERROR( "The ACIS Local Operations Husk is required for tweaking\n"
- " surfaces to a target. It has not been licensed for this installation.\n" );
- return CUBIT_FAILURE;
-#endif
-
- if( target_surf_list.size() == 1 )
- {
- return tweak_target_single( input_surface_list, target_surf_list.get(),
- new_bodysm_list, reverse_flg, keep_old_body, preview );
- }
- else
- {
- return tweak_target_multiple( input_surface_list, target_surf_list,
- new_bodysm_list, reverse_flg, keep_old_body, preview );
- }
-}
-
-//=============================================================================
-// Function : tweak_target_single
-// Member Type: PRIVATE
-// Description: Tweak specified faces of a volume or volumes up to a single
-// target surface.
-// Author : Steve Storm
-// Date :
-//=============================================================================
-CubitStatus AcisTweakTool::tweak_target_single(
- DLIList<Surface*> &input_surface_list,
- Surface *target_surf_ptr,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean reverse_flg,
- CubitBoolean keep_old_body,
- CubitBoolean preview )
-{
- int i;
- BODY* copied_BODY_ptr;
- BODY* BODY_ptr;
- BodySM* body_ptr;
-
- bool delete_attribs =
- (GeometryModifyTool::instance()->get_new_ids() || keep_old_body);
-
- // Copy the incoming input_surface_list since we will be pulling
- // surfaces out of it.
- DLIList<SurfaceACIS*> surface_list( input_surface_list.size() );
- if (!get_ACIS_surfaces( input_surface_list, surface_list ))
- return CUBIT_FAILURE;
-
- // Make sure that the none of the surfaces are sheet bodies (2-sided)
- for( i=surface_list.size(); i--; )
- {
- if( surface_list.get_and_step()->get_FACE_ptr()->sides() == DOUBLE_SIDED )
- {
- PRINT_ERROR("Cannot tweak surfaces that do not belong to a closed volume\n");
- return CUBIT_FAILURE;
- }
- }
-
- // Get target FACE
- Surface *target_surface_ptr = target_surf_ptr;
- SurfaceACIS *target_surf_acis = dynamic_cast<SurfaceACIS*>( target_surf_ptr );
- if (!target_surf_acis)
- {
- PRINT_ERROR("Target cannot be a non-ACIS Surface.\n");
- return CUBIT_FAILURE;
- }
-
- // Copy the target face (in some cases, the target face can be modified -
- // if for example it is tweaked to itself, which is sometimes done to
- // remove unwanted topology or to fix an error). This preserves the target
- // in that case.
- ENTITY *copied_entity_ptr;
- outcome result = api_copy_entity_contents( target_surf_acis->get_FACE_ptr(),
- copied_entity_ptr );
- if( !result.ok() )
- {
- AQE->ACIS_API_error(result);
- return CUBIT_FAILURE;
- }
- FACE *target_FACE_ptr = (FACE *)copied_entity_ptr;
-
- // This acis api doesn't work exactly as I'd like. The
- // only thing that makes sense using it, it seems, is to
- // tweak multiple surfaces to one surface.
- DLIList<FACE*> tweak_FACE_list;
- DLIList<SurfaceACIS*> tweak_surface_list;
- surface_list.reset();
- while( surface_list.size() )
- {
- // Remove a group of surfaces from surface_list that belong to the same
- // BODY. Copy the BODY and put the copied surfaces in tweak_FACE_list.
- tweak_FACE_list.clean_out();
- tweak_surface_list.clean_out();
- if( AME->get_copied_FACES_of_body( surface_list, tweak_FACE_list,
- tweak_surface_list, copied_BODY_ptr ) == CUBIT_FAILURE )
- {
- api_delent( target_FACE_ptr );
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- // Store source FACEs for preview
- DLIList<AcisBridge*> preview_ab_list;
- if( preview )
- {
- get_owner_list( tweak_FACE_list, preview_ab_list );
- preview_ab_list.append_unique(
- ATTRIB_CUBIT_OWNER::cubit_owner( target_surf_acis->get_FACE_ptr() ) );
- }
-
- // Do the tweak
- if( tweak_FACEs_to_target( tweak_FACE_list, target_FACE_ptr, reverse_flg )
- == CUBIT_FAILURE )
- {
- api_delent( copied_BODY_ptr );
- api_delent( target_FACE_ptr );
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- // Get original Body and BODY
- body_ptr = AQE->get_body_sm_of_ENTITY( copied_BODY_ptr );
- BODY_ptr = dynamic_cast<BodyACIS*>(body_ptr)->get_BODY_ptr();
-
- if( !preview )
- {
- // Now cleanout the owner attributes from the copied BODY, if required
- if( delete_attribs )
- AQE->remove_cubit_owner_attrib_in_BODY( copied_BODY_ptr );
-
- BodySM *new_body = AME->get_new_Body( body_ptr, BODY_ptr,
- copied_BODY_ptr, keep_old_body );
-
- if( new_body )
- new_bodysm_list.append( new_body );
- }
- else
- {
- GfxPreview::clear();
-
- // Note the preview_ab_list is used for a special case in the preview -
- // when the target is a FACE in the BODY itself.
- draw_tweak_preview_omt( copied_BODY_ptr, CUBIT_TRUE, &preview_ab_list );
-
- api_delent( copied_BODY_ptr );
- }
- }
-
- api_delent( target_FACE_ptr );
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : tweak_target_multiple
-// Member Type: PRIVATE
-// Description: Tweak specified faces of a volume or volumes up to a set of
-// target surfaces.
-// Author : Steve Storm
-// Date : 10/27/05
-//=============================================================================
-CubitStatus AcisTweakTool::tweak_target_multiple(
- DLIList<Surface*> &input_surface_list,
- DLIList<Surface*> &target_surf_list,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean reverse_flg,
- CubitBoolean keep_old_body,
- CubitBoolean preview )
-{
- bool delete_attribs =
- (GeometryModifyTool::instance()->get_new_ids() || keep_old_body);
-
- // Copy the incoming input_surface_list since we will be pulling surfaces out
- // of it.
- DLIList<SurfaceACIS*> surface_list( input_surface_list.size() );
- if (!get_ACIS_surfaces( input_surface_list, surface_list ))
- return CUBIT_FAILURE;
-
- // Make sure that the none of the surfaces are sheet bodies (2-sided)
- int i;
- for( i=surface_list.size(); i--; )
- {
- if( surface_list.get_and_step()->get_FACE_ptr()->sides() == DOUBLE_SIDED )
- {
- PRINT_ERROR("Cannot tweak surfaces that do not belong to a solid volume\n");
- return CUBIT_FAILURE;
- }
- }
-
- // Note: target surfaces don't necessarily have to be from same BODY
-
- // Get target FACEs
- DLIList<FACE*> target_FACE_list;
- if( get_FACEs( target_surf_list, target_FACE_list ) == CUBIT_FAILURE )
- {
- PRINT_ERROR( "Targets must be ACIS surfaces\n" );
- return CUBIT_FAILURE;
- }
-
- // Get extended target surfaces (in a single sheet BODY)
- BODY *ext_target_BODY_ptr;
- if( create_extended_sheet( target_FACE_list, ext_target_BODY_ptr )
- == CUBIT_FAILURE )
- return CUBIT_FAILURE;
-
- if( DEBUG_FLAG(168) )
- {
- BODY *tmp_BODY = AME->copy_BODY( ext_target_BODY_ptr, CUBIT_TRUE );
- BodySM *this_bodysm = AcisQueryEngine::instance()->
- populate_topology_bridges( tmp_BODY );
- new_bodysm_list.append( this_bodysm );
- }
-
- // Tweak the sources to the targets on a per body basis
- DLIList<FACE*> source_FACE_list;
- BODY *copied_BODY_ptr;
- BODY *BODY_ptr;
- BodySM *body_ptr;
- surface_list.reset();
- while( surface_list.size() )
- {
- // Remove a group of surfaces from surface_list that belong to the same
- // BODY. Copy the BODY and put the copied sources in source_FACE_list.
- source_FACE_list.clean_out();
- if( AME->get_copied_FACES_of_body( surface_list, source_FACE_list,
- copied_BODY_ptr ) == CUBIT_FAILURE )
- break;
-
- // Get original Body and BODY
- body_ptr = AQE->get_body_sm_of_ENTITY( copied_BODY_ptr );
- BODY_ptr = dynamic_cast<BodyACIS*>(body_ptr)->get_BODY_ptr();
-
- // Store source and target FACEs for preview (necessary especially if
- // tweaking surfaces on a body to surfaces on the same body)
- DLIList<AcisBridge*> preview_ab_list;
- if( preview )
- {
- get_owner_list( source_FACE_list, preview_ab_list );
- get_owner_list( target_FACE_list, preview_ab_list );
- }
-
- // Tweak the source FACEs up to the target sheet body
- if( tweak_target_multiple( source_FACE_list, target_FACE_list,
- ext_target_BODY_ptr, new_bodysm_list, reverse_flg ) == CUBIT_FAILURE )
- {
- api_delent( ext_target_BODY_ptr );
- api_delent( copied_BODY_ptr );
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- if( !preview )
- {
- // Now cleanout the owner attributes from the copied BODY, if required
- if( delete_attribs )
- AQE->remove_cubit_owner_attrib_in_BODY( copied_BODY_ptr );
-
- BodySM *new_body = AME->get_new_Body( body_ptr, BODY_ptr,
- copied_BODY_ptr, keep_old_body );
-
- if( new_body )
- new_bodysm_list.append( new_body );
- }
- else
- {
- GfxPreview::clear();
-
- // Draw preview EDGEs
- draw_tweak_preview_omt( copied_BODY_ptr, CUBIT_TRUE, &preview_ab_list );
- api_delent(copied_BODY_ptr);
- }
- }
-
- api_delent( ext_target_BODY_ptr );
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : custom_att_merge_method
-// Member Type: Global
-// Description: Used to mark EDGEs that are merged for tweak_target_multiple
-// method. This is a custom merge_owner method for ACIS
-// generic attributes.
-// Author : Steve Storm
-// Date : 3/18/06
-//=============================================================================
-void
-custom_att_merge_method(
- ATTRIB_GEN_NAME *att, // attribute whose owner is being merged
- ENTITY *ENTITY_ptr2, // other entity involved in merge
- logical merge_method ) // attribute's owner will be lost?
-{
- ENTITY *ENTITY_ptr1 = att->entity();
-
- if( IS_ENTITY_TYPE( ENTITY_ptr1, EDGE ) )
- {
- api_add_generic_named_attribute( ENTITY_ptr1, "tweak_merged", 1, SplitCopy );
- api_add_generic_named_attribute( ENTITY_ptr2, "tweak_merged", 1, SplitCopy );
- }
-
- return;
-}
-
-//=============================================================================
-// Function : tweak_target_multiple
-// Member Type: PRIVATE
-// Description: Tweak specified faces of a volume up to a sheet body
-// Author : Steve Storm
-// Date : 10/27/05
-//=============================================================================
-CubitStatus AcisTweakTool::tweak_target_multiple( DLIList<FACE*> &source_FACE_list,
- DLIList<FACE*> &target_FACE_list,
- BODY *ext_target_BODY_ptr,
- DLIList<BodySM*> &debug_BodySM_list,
- CubitBoolean reverse_flg )
-{
- // Summary of method:
- // 1. Check for special case - extended target could contain only one
- // surface - if so, use single tweak method.
- // 2. Assign attributes to side FACEs (FACEs alongside the sources) so that
- // we can get back to these FACEs after the tweak. Since we are cutting
- // the body with an extended target, the cutting sheet could cross parts
- // of the body we don't want to cut - if it crosses any FACEs without
- // these attributes we throw away that portion of the cutting sheet.
- // 3. Copy the targets into a single sheet BODY. We will make the surface
- // normals consistent in this sheet BODY. Our method relies on having
- // consistent normals on the cutting sheet. Since when extending the
- // target surfaces, cylinders may become full cylinders (i.e., extend
- // a planar FACE with one filleted surface adjoining - you will get a
- // plane connected to a cylinder), we will ultimately have to remove the
- // portions of the cylinder we don't want (remove the "back side" of the
- // cylinder). By computing the average normal of the original target
- // surfaces, we will have a good idea as to which side of the extended
- // cylinders to keep.
- // 4. Get weighted average FACE normal of source and target surfaces.
- // 5. Create a plane just past the targets aligned with the target normal.
- // Tweak the source surfaces to this plane (the body is now tweaked past
- // the targets). This is the tweaked BODY.
- // 6. Make normals in the extended target sheet consistent with the normals
- // in #3, since we will need to compare to the extended target sheet
- // normals.
- // 7. Intersect the tweaked BODY (#5) and the extended target sheet - this
- // makes a cutting sheet. Note this cutting sheet may cross parts of the
- // BODY where we don't want it to cut.
- // 8. Imprint so as to score the cutting sheet.
- // 9. Throw away individual cutting sheet surfaces that don't cross the
- // FACEs we want to cut (the side FACEs tracked in #2).
- // 10. Since the extended target could contain complete cylinders, torii and
- // spheres, AND it could cut through other portions of our body, we need
- // to do some special handling before just cutting the body with it. Our
- // approach is to trim the extended target body to the desired cutting
- // sheet.
- // a) Remove periodic surfaces near nonmanifold edges.
- // b) Align the normals of the cutting sheet with the extended target
- // sheet - again, we need to keep the normals consistent to the
- // original targets.
- // c) Remove unwanted periodic FACEs on the back of the cutting sheet.
- // Since we diligently kept the normals consistent, we can simply
- // remove periodic surfaces with normals aligned with the negative
- // of the target normal (from #4).
- // 11. Make sure cutting sheet normal is pointing in opposite direction of
- // the source normal. Note we can tweak forwards or backwards - no
- // special handling is needed.
- // 12. Chopoff the body.
-
- // Check for special case - if ext_target_BODY_ptr only contains one
- // FACE, tweak to it and exit.
- DLIList<FACE*> ext_FACE_list;
- AQE->get_FACEs( ext_target_BODY_ptr, ext_FACE_list );
- if( ext_FACE_list.size() == 1 )
- {
- FACE *target_FACE_ptr = ext_FACE_list.get();
- if( tweak_FACEs_to_target( source_FACE_list, target_FACE_ptr, reverse_flg )
- == CUBIT_FAILURE )
- return CUBIT_FAILURE;
-
- return CUBIT_SUCCESS;
- }
-
- // Get the BODY the sources are in
- FACE *FACE_ptr = source_FACE_list.get();
- BODY *copied_BODY_ptr = AQE->get_BODY_of_ENTITY( FACE_ptr );
-
- // This operation sometimes destroys owner attributes
- AcisBridge *ab_body_ptr;
- AcisBridge *ab_lump_ptr;
- AcisBridge *ab_shell_ptr;
- get_owner_attribs( copied_BODY_ptr, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
-
- // Assign attributes to side FACEs for later use
- int i, j, k;
- outcome result;
- ATTRIB_GEN_NAME *ret_att;
- for( i=source_FACE_list.size(); i--; )
- {
- FACE_ptr = source_FACE_list.get_and_step();
-
- DLIList<EDGE*> EDGE_list;
- AQE->get_EDGEs( FACE_ptr, EDGE_list );
-
- for( j=EDGE_list.size(); j--; )
- {
- EDGE *EDGE_ptr = EDGE_list.get_and_step();
- DLIList<FACE*> attached_FACEs;
- AQE->get_FACEs( EDGE_ptr, attached_FACEs );
-
- for( k=attached_FACEs.size(); k--; )
- {
- FACE_ptr = attached_FACEs.get_and_step();
- result = api_find_named_attribute( FACE_ptr, "tweak", ret_att );
- if( !ret_att )
- {
- result = api_add_generic_named_attribute( FACE_ptr, "tweak", 1, SplitCopy );
- if( !result.ok() )
- {
- AQE->ACIS_API_error(result);
- return CUBIT_FAILURE;
- }
- }
- }
- }
- }
-
- // Remove named attributes from the sources
- for( i=source_FACE_list.size(); i--; )
- {
- FACE_ptr = source_FACE_list.get_and_step();
- api_remove_generic_named_attribute(FACE_ptr, "tweak");
- }
-
- // Store the sources in a sheet - needed for distance calculation and may be
- // needed later for self-intersecting BODY issue.
- BODY *source_sheet;
- if( copy_FACEs_into_sheet( source_FACE_list, source_sheet ) == CUBIT_FAILURE )
- {
- PRINT_ERROR( "Unable to tweak to targets\n" );
- remove_named_attribs( copied_BODY_ptr, "tweak" );
- return CUBIT_FAILURE;
- }
-
- // Make a target sheet with copies of original target FACEs in it. We will
- // extract the target normal from this BODY.
- BODY *target_sheet;
- if( copy_FACEs_into_sheet( target_FACE_list, target_sheet ) == CUBIT_FAILURE )
- {
- api_delent( source_sheet );
- remove_named_attribs( copied_BODY_ptr, "tweak" );
- return CUBIT_FAILURE;
- }
-
- // Make the surface normals consistent. Note user could pick a variety of
- // target surfaces from different bodies, without consistent surface normals.
- if( make_surf_normals_consistent( target_sheet )== CUBIT_FAILURE )
- {
- PRINT_ERROR( "Unable to make target surface normals consistent - invalid target\n" );
- api_delent( source_sheet );
- api_delent( target_sheet );
- remove_named_attribs( copied_BODY_ptr, "tweak" );
- return CUBIT_FAILURE;
- }
-
- // FYI: Property of dot product:
- // * angle between vectors acute (<90) if dot product > 0
- // * angle between vectors obtuse (>90) if dot product < 0
- // * angle between vectors 90 deg if dot product = 0
-
- // Get average direction of source normals.
- CubitVector source_norm = weighted_average_FACE_normal( source_FACE_list );
- if( source_norm.length() < 1e-12 )
- {
- PRINT_ERROR( "Unable to tweak source surfaces that form a loop\n" );
- api_delent( source_sheet );
- api_delent( target_sheet );
- remove_named_attribs( copied_BODY_ptr, "tweak" );
- return CUBIT_FAILURE;
- }
-
- // Get average target normal
- DLIList<FACE*> target_sheet_FACE_list;
- AQE->get_FACEs( target_sheet, target_sheet_FACE_list );
- CubitVector target_norm = weighted_average_FACE_normal( target_sheet_FACE_list );
- if( target_norm.length() < 1e-12 )
- {
- PRINT_ERROR( "Unable to tweak to target surfaces that form a loop\n" );
- api_delent( source_sheet );
- api_delent( target_sheet );
- remove_named_attribs( copied_BODY_ptr, "tweak" );
- return CUBIT_FAILURE;
- }
-
- // Get a plane through one of the source's vertices (with normal aligned with
- // target normal (but pointing in direction of source normal)
- source_FACE_list.reset();
- DLIList<VERTEX*> temp_VERTEX_list;
- AQE->get_VERTICEs( source_FACE_list.get(), temp_VERTEX_list );
- VERTEX *VERTEX_ptr = temp_VERTEX_list.get();
- SPAposition acis_coords = (VERTEX_ptr->geometry())->coords();
- CubitVector coords( acis_coords.x(), acis_coords.y(), acis_coords.z() );
- CubitPlane source_plane( target_norm, coords );
-
- // Have plane's normal point in the general direction of source_norm
- if( source_norm % source_plane.normal() < 0.0 ) // Dot product
- {
- // Obtuse angle - reverse the plane
- CubitVector neg_norm = -source_plane.normal();
- source_plane.normal( neg_norm );
- source_plane.coefficient( -source_plane.coefficient() );
- }
-
- // Offset the plane past the targets. Do this in two steps - in some
- // cases, our plane is far from the sources and this can cause problems
- // (if there is a cylindrical surface, the API error "no solution for an
- // edge" has occurred).
-
- // Find offset distance for first tweak - just past the sources (this
- // will most likely make one planar source)
- double offset_dist;
- if( extrema_pln_BODY( source_plane, source_sheet, offset_dist )
- == CUBIT_FAILURE )
- {
- api_delent( source_sheet );
- api_delent( target_sheet );
- remove_named_attribs( copied_BODY_ptr, "tweak" );
- return CUBIT_FAILURE;
- }
-
- BODY *planar_target_BODY;
- if( create_offset_planar_body( source_plane, offset_dist,
- planar_target_BODY ) == CUBIT_FAILURE )
- {
- api_delent( source_sheet );
- api_delent( target_sheet );
- remove_named_attribs( copied_BODY_ptr, "tweak" );
- return CUBIT_FAILURE;
- }
-
- if( DEBUG_FLAG(168) )
- {
- BODY *tmp_BODY = AME->copy_BODY( planar_target_BODY, CUBIT_TRUE );
- BodySM *this_bodysm = AQE->populate_topology_bridges( tmp_BODY );
- debug_BodySM_list.append( this_bodysm );
- }
-
- DLIList<FACE*> planar_FACE_list;;
- AQE->get_FACEs( planar_target_BODY, planar_FACE_list );
- FACE *planar_target_FACE = planar_FACE_list.get();
-
- // Mark the sources and other FACEs
- for( i=source_FACE_list.size(); i--; )
- {
- FACE_ptr = source_FACE_list.get_and_step();
- api_add_generic_named_attribute( FACE_ptr, "tweak_source", 1, SplitCopy );
- }
- DLIList<FACE*> copied_BODY_FACE_list;
- AQE->get_FACEs( copied_BODY_ptr, copied_BODY_FACE_list );
- for( i=copied_BODY_FACE_list.size(); i--; )
- {
- FACE_ptr = copied_BODY_FACE_list.get_and_step();
- api_find_named_attribute( FACE_ptr, "tweak_source", ret_att );
- if( !ret_att )
- api_add_generic_named_attribute( FACE_ptr, "tweak_other", 1 );
- }
-
- // Tweak the sources to the first planar target
- CubitBoolean skip_self_int_check = CUBIT_TRUE;
-
- if( tweak_FACEs_to_target( source_FACE_list, planar_target_FACE,
- CUBIT_FALSE, skip_self_int_check ) == CUBIT_FAILURE )
- {
- api_delent( source_sheet );
- api_delent( target_sheet );
- api_delent( planar_target_BODY );
- remove_named_attribs( copied_BODY_ptr, "tweak" );
- return CUBIT_FAILURE;
- }
-
- // Delete the first planar target
- api_delent( planar_target_BODY );
-
- // Get new source list
- source_FACE_list.clean_out();
- copied_BODY_FACE_list.clean_out();
- AQE->get_FACEs( copied_BODY_ptr, copied_BODY_FACE_list );
- for( i=copied_BODY_FACE_list.size(); i--; )
- {
- FACE_ptr = copied_BODY_FACE_list.get_and_step();
- api_find_named_attribute( FACE_ptr, "tweak_source", ret_att );
- if( ret_att )
- {
- source_FACE_list.append( FACE_ptr );
- api_remove_generic_named_attribute(FACE_ptr, "tweak_source");
- }
- else
- {
- api_find_named_attribute( FACE_ptr, "tweak_other", ret_att );
- if( ret_att )
- api_remove_generic_named_attribute(FACE_ptr, "tweak_other");
- else
- {
- // No attribute - this must be the new source
- source_FACE_list.append( FACE_ptr );
- }
- }
- }
-
- // Get a plane for the second tweak
- target_FACE_list.reset();
- temp_VERTEX_list.clean_out();
- AQE->get_VERTICEs( target_FACE_list.get(), temp_VERTEX_list );
- VERTEX_ptr = temp_VERTEX_list.get();
- acis_coords = (VERTEX_ptr->geometry())->coords();
- coords.set( acis_coords.x(), acis_coords.y(), acis_coords.z() );
- CubitPlane target_plane( target_norm, coords );
-
- // Have plane's normal point in the general direction of source_norm
- if( source_norm % target_plane.normal() < 0.0 ) // Dot product
- {
- // Obtuse angle - reverse the plane
- CubitVector neg_norm = -target_plane.normal();
- target_plane.normal( neg_norm );
- target_plane.coefficient( -target_plane.coefficient() );
- }
-
- // Find offset distance for second tweak - past the targets. Calculate the
- // offset distance as the maximum distance from the plane to any point on the
- // extended target body, in the direction of the plane's normal.
- if( extrema_pln_BODY( target_plane, ext_target_BODY_ptr, offset_dist )
- == CUBIT_FAILURE )
- {
- api_delent( source_sheet );
- api_delent( target_sheet );
- remove_named_attribs( copied_BODY_ptr, "tweak" );
- return CUBIT_FAILURE;
- }
-
- // Create a target FACE offset from the plane (arbitrarily 10.0 X 10.0
- // in size)
- if( create_offset_planar_body( target_plane, offset_dist,
- planar_target_BODY ) == CUBIT_FAILURE )
- {
- api_delent( source_sheet );
- api_delent( target_sheet );
- remove_named_attribs( copied_BODY_ptr, "tweak" );
- return CUBIT_FAILURE;
- }
-
- if( DEBUG_FLAG(168) )
- {
- BODY *tmp_BODY = AME->copy_BODY( planar_target_BODY, CUBIT_TRUE );
- BodySM *this_bodysm = AQE->populate_topology_bridges( tmp_BODY );
- debug_BodySM_list.append( this_bodysm );
- }
-
- planar_FACE_list.clean_out();
- AQE->get_FACEs( planar_target_BODY, planar_FACE_list );
- planar_target_FACE = planar_FACE_list.get();
-
- // Tweak the sources to the planar target
- if( tweak_FACEs_to_target( source_FACE_list, planar_target_FACE,
- CUBIT_FALSE, skip_self_int_check ) == CUBIT_FAILURE )
- {
- api_delent( source_sheet );
- api_delent( target_sheet );
- api_delent( planar_target_BODY );
- remove_named_attribs( copied_BODY_ptr, "tweak" );
- return CUBIT_FAILURE;
- }
-
- // Free the plane since we are done with it
- api_delent( planar_target_BODY );
-
- // Copy the ext_target_BODY_ptr so as not to modify it
- BODY *ext_target_BODY_ptr2 = AME->copy_BODY( ext_target_BODY_ptr, CUBIT_TRUE );
-
- // Heal the body for good measure
- heal_BODY( ext_target_BODY_ptr2 );
-
- // Make the shell normals in the ext_target_BODY_ptr2 consistent with the
- // target sheet.
- FACE *seed_FACE_ptr = get_seed_FACE( target_sheet_FACE_list );
-
- DLIList<FACE*> ext_target_BODY_FACE_list;
- AQE->get_FACEs( ext_target_BODY_ptr2, ext_target_BODY_FACE_list );
-
- FACE *overlap_FACE_ptr = find_overlap_FACE( seed_FACE_ptr,
- ext_target_BODY_FACE_list );
- if( !overlap_FACE_ptr )
- {
- PRINT_ERROR( "Problem creating extended target to tweak to\n" );
- if( DEBUG_FLAG(168) )
- {
- BODY *tmp_BODY = AME->copy_BODY( ext_target_BODY_ptr2, CUBIT_TRUE );
- BodySM *this_bodysm = AQE->populate_topology_bridges( tmp_BODY );
- debug_BodySM_list.append( this_bodysm );
- }
- api_delent( source_sheet );
- api_delent( target_sheet );
- api_delent( ext_target_BODY_ptr2 );
- remove_named_attribs( copied_BODY_ptr, "tweak" );
- return CUBIT_FAILURE;
- }
-
- CubitVector norm_loc;
- CubitVector ext_norm = FACE_normal( overlap_FACE_ptr, norm_loc );
- CubitVector seed_norm = FACE_normal( seed_FACE_ptr, norm_loc, CUBIT_FALSE );
-
- if( ext_norm % seed_norm < 0.0 )
- api_reverse_face( overlap_FACE_ptr );
-
- if( make_surf_normals_consistent( ext_target_BODY_ptr2, overlap_FACE_ptr )
- == CUBIT_FAILURE )
- {
- PRINT_ERROR( "Unable to make extended target shell normals consistent - invalid target\n" );
- if( DEBUG_FLAG(168) )
- {
- BODY *tmp_BODY = AME->copy_BODY( ext_target_BODY_ptr2, CUBIT_TRUE );
- BodySM *this_bodysm = AQE->populate_topology_bridges( tmp_BODY );
- debug_BodySM_list.append( this_bodysm );
- }
- api_delent( source_sheet );
- api_delent( target_sheet );
- api_delent( ext_target_BODY_ptr2 );
- remove_named_attribs( copied_BODY_ptr, "tweak" );
- return CUBIT_FAILURE;
- }
-
- if( DEBUG_FLAG(168) )
- {
- BODY *tmp_BODY = AME->copy_BODY( ext_target_BODY_ptr2, CUBIT_TRUE );
- BodySM *this_bodysm = AQE->populate_topology_bridges( tmp_BODY );
- debug_BodySM_list.append( this_bodysm );
- }
-
- // We are done with the target_sheet
- api_delent( target_sheet );
-
- // Intersect the tweaked body and the ext_target_BODY_ptr2. We need to then
- // determine which loops on the resulting body to keep as the cutting
- // sheet. Note a NONREG_INTERSECTION sometimes corrupts the cutting_sheet,
- // so we do a regularized intersection then imprint afterwards.
- BODY *cutting_sheet = NULL;
- result = api_boolean( copied_BODY_ptr, ext_target_BODY_ptr2, INTERSECTION,
- NDBOOL_KEEP_BOTH, cutting_sheet );
- if( !result.ok() )
- {
- // A likely problem is that the BODY intersects with itself - we need to
- // handle this case. To fix we will chop off the tweaked part of the BODY
- // using the original sources; then our booleans will work. We then have
- // to reassemble the BODY.
+ if (preview)
+ GfxPreview::flush();
- BODY *copied_BODY_ptr2 = AME->copy_BODY( copied_BODY_ptr, CUBIT_FALSE );
-
- // Chopoff the copied_BODY_ptr with cutting_sheet
- if( chop_off_with_sheet( copied_BODY_ptr2, source_sheet ) == CUBIT_FAILURE )
- {
- AQE->ACIS_API_error(result);
- api_delent( source_sheet );
- api_delent( ext_target_BODY_ptr2 );
- api_delent( copied_BODY_ptr2 );
- remove_named_attribs( copied_BODY_ptr, "tweak" );
- return CUBIT_FAILURE;
- }
-
- // Chopoff the copied_BODY_ptr with cutting_sheet the other way
- api_reverse_body( source_sheet );
- if( chop_off_with_sheet( copied_BODY_ptr, source_sheet ) == CUBIT_FAILURE )
- {
- AQE->ACIS_API_error(result);
- api_delent( source_sheet );
- api_delent( ext_target_BODY_ptr2 );
- api_delent( copied_BODY_ptr2 );
- remove_named_attribs( copied_BODY_ptr, "tweak" );
- return CUBIT_FAILURE;
- }
-
- // We are done with the source_sheet
- api_delent( source_sheet );
-
- // Note copied_BODY_ptr2 is the cutoff tweaked piece - perform steps on
- // this piece. The good thing is we won't have to worry about looking for
- // FACEs crossed by the extended target that we don't want to affect.
-
- result = api_boolean( copied_BODY_ptr2, ext_target_BODY_ptr2, INTERSECTION,
- NDBOOL_KEEP_BOTH, cutting_sheet );
- if( !result.ok() )
- {
- api_delent( ext_target_BODY_ptr2 );
- api_delent( copied_BODY_ptr2 );
- remove_named_attribs( copied_BODY_ptr, "tweak" );
- return CUBIT_FAILURE;
- }
-
- // Prepare the cutting sheet
- if( prep_cutting_sheet( cutting_sheet, copied_BODY_ptr2, ext_target_BODY_ptr2,
- source_norm, target_norm, CUBIT_FALSE ) == CUBIT_FAILURE )
- {
- if( DEBUG_FLAG(168) )
- {
- BodySM *this_bodysm = AQE->populate_topology_bridges( cutting_sheet );
- debug_BodySM_list.append( this_bodysm );
- }
- else
- api_delent( cutting_sheet );
- api_delent( ext_target_BODY_ptr2 );
- api_delent( copied_BODY_ptr2 );
- remove_named_attribs( copied_BODY_ptr, "tweak" );
- return CUBIT_FAILURE;
- }
-
- // We are done with the "tweak" attributes (used in prep_cutting_sheet)
- remove_named_attribs( copied_BODY_ptr, "tweak" );
-
- // We are now done with the copied extended target sheet
- api_delent( ext_target_BODY_ptr2 );
-
- // Reverse if forced to
- if( reverse_flg )
- api_reverse_body( cutting_sheet );
-
- if( DEBUG_FLAG(168) )
- {
- BODY *tmp_BODY = AME->copy_BODY( cutting_sheet, CUBIT_TRUE );
- BodySM *this_bodysm = AQE->populate_topology_bridges( tmp_BODY );
- debug_BodySM_list.append( this_bodysm );
- }
-
- // Apply a "tweak2" named attribute as part of a multi-step process we use
- // to determine which EDGEs to regularize out when we reassemble the BODY.
- // The "tweak2" attribute will not exist on the EDGEs that result from the
- // chopoff operation with the cutting sheet. We will use a custom function
- // that gets called during boolean merge operations.
- DLIList<EDGE*> BODY2_EDGE_list;
- AQE->get_EDGEs( copied_BODY_ptr2, BODY2_EDGE_list );
- EDGE *EDGE_ptr;
- for( i=BODY2_EDGE_list.size(); i--; )
- {
- EDGE_ptr = BODY2_EDGE_list.get_and_step();
- api_add_generic_named_attribute( EDGE_ptr, "tweak2", 1, SplitLose,
- MergeCustom );
- }
-
- // Chopoff the copied_BODY_ptr2 with cutting_sheet
- if( chop_off_with_sheet( copied_BODY_ptr2, cutting_sheet ) == CUBIT_FAILURE )
- {
- api_delent( copied_BODY_ptr2 );
- api_delent( cutting_sheet );
- return CUBIT_FAILURE;
- }
-
- // We are done with the cutting sheet
- api_delent( cutting_sheet );
-
- // This will add a "tweak_merged" attribute to any EDGE containing a
- // "tweak2" attribute that is merged with another EDGE during the following
- // unite. We can then clean these EDGEs out. Note the EDGEs that were
- // sliced at the cutting sheet location won't have "tweak2" attributes on
- // them - thus this method allows us to efficiently find the EDGEs we need
- // to remove.
- set_merge_method( "tweak2", custom_att_merge_method );
-
- // Unite the copied_BODY_ptr2 with copied_BODY_ptr (this deletes
- // copied_BODY_ptr2)
- result = api_boolean( copied_BODY_ptr2, copied_BODY_ptr, NONREG_UNION );
- if( !result.ok() )
- {
- if( copied_BODY_ptr2 ) api_delent( copied_BODY_ptr2 );
- return CUBIT_FAILURE;
- }
-
- // The unite can leave double-sided FACEs within the BODY - we need to
- // to remove those.
- DLIList<FACE*> body_FACE_list;
- AQE->get_FACEs( copied_BODY_ptr, body_FACE_list );
- for( i=body_FACE_list.size(); i--; )
- {
- FACE_ptr = body_FACE_list.get_and_step();
-
- // If this is an internal FACE remove it
- if( FACE_ptr->sides() == DOUBLE_SIDED &&
- FACE_ptr->cont()==BOTH_INSIDE )
- {
- BODY *unhooked_BODY_ptr = NULL;
- api_unhook_face( FACE_ptr, unhooked_BODY_ptr );
- if( unhooked_BODY_ptr )
- api_delent( unhooked_BODY_ptr );
- }
- }
-
- // Remove the merged EDGEs
- DLIList<EDGE*> merged_EDGE_list;
- DLIList<EDGE*> body_EDGE_list;
- AQE->get_EDGEs( copied_BODY_ptr, body_EDGE_list );
- for( i=body_EDGE_list.size(); i--; )
- {
- EDGE_ptr = body_EDGE_list.get_and_step();
- api_find_named_attribute( EDGE_ptr, "tweak_merged", ret_att );
- if( ret_att )
- {
- merged_EDGE_list.append( EDGE_ptr );
- api_remove_generic_named_attribute(EDGE_ptr, "tweak_merged");
- }
- }
-
- for( i=merged_EDGE_list.size(); i--; )
- {
- EDGE_ptr = merged_EDGE_list.get_and_step();
-
- // Make sure EDGE was not already cleaned out
- DLIList<EDGE*> tmp_EDGE_list;
- AQE->get_EDGEs( copied_BODY_ptr, tmp_EDGE_list );
-
- if( tmp_EDGE_list.is_in_list( EDGE_ptr ) )
- api_clean_entity( EDGE_ptr );
- }
-
- // Cleanout any left-over named attributes
- remove_named_attribs( copied_BODY_ptr, "tweak2" );
-
- // Reset the owner attributes
- reset_owner_attribs( copied_BODY_ptr, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
-
return CUBIT_SUCCESS;
- } // End of workaround for self-intersecting case
-
- // Since the intersection was successful the source_sheet is not needed
- api_delent( source_sheet );
-
- // Prepare the cutting sheet
- if( prep_cutting_sheet( cutting_sheet, copied_BODY_ptr, ext_target_BODY_ptr2,
- source_norm, target_norm ) == CUBIT_FAILURE )
- {
- if( DEBUG_FLAG(168) )
- {
- BodySM *this_bodysm = AQE->populate_topology_bridges( cutting_sheet );
- debug_BodySM_list.append( this_bodysm );
- }
- else
- api_delent( cutting_sheet );
- api_delent( ext_target_BODY_ptr2 );
- remove_named_attribs( copied_BODY_ptr, "tweak" );
- return CUBIT_FAILURE;
- }
-
- // We are done with the "tweak" attributes (used in prep_cutting_sheet)
- remove_named_attribs( copied_BODY_ptr, "tweak" );
-
- // We are now done with the copied extended target sheet
- api_delent( ext_target_BODY_ptr2 );
-
- // Reverse if forced to
- if( reverse_flg )
- api_reverse_body( cutting_sheet );
-
- if( DEBUG_FLAG(168) )
- {
- BODY *tmp_BODY = AME->copy_BODY( cutting_sheet, CUBIT_TRUE );
- BodySM *this_bodysm = AQE->populate_topology_bridges( tmp_BODY );
- debug_BodySM_list.append( this_bodysm );
- }
-
- // Chopoff the copied_BODY_ptr with cutting_sheet
- if( chop_off_with_sheet( copied_BODY_ptr, cutting_sheet ) == CUBIT_FAILURE )
- {
- api_delent( cutting_sheet );
- return CUBIT_FAILURE;
- }
-
- // Delete the cutting sheet
- api_delent( cutting_sheet );
-
- // Reset the owner attributes
- reset_owner_attribs( copied_BODY_ptr, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
-
- return CUBIT_SUCCESS;
}
-//=============================================================================
-// Function : FACE_surrounded
-// Member Type: PRIVATE
-// Description: Determine if the given FACE is entirely surrounded by the
-// other FACEs. The given FACE can exist in FACE_list_in.
-// Author : Steve Storm
-// Date : 01/05/06
-//=============================================================================
-CubitBoolean
-AcisTweakTool::FACE_surrounded( FACE *ref_FACE_ptr,
- DLIList<FACE*> &FACE_list_in )
-{
- // Get outer loop curves in ref_FACE_ptr
- DLIList<EDGE*> ref_FACE_edges;
- get_outer_EDGEs( ref_FACE_ptr, ref_FACE_edges );
-
- // Loop through ref_FACE_edges, get all attached FACEs, check if any are in
- // FACE_list_in.
-
- int i, j;
- int num_found = 0;
- EDGE *ref_EDGE_ptr;
- for( i=ref_FACE_edges.size(); i--; )
- {
- ref_EDGE_ptr = ref_FACE_edges.get_and_step();
-
- DLIList<FACE *> attached_FACE_list;
- AQE->get_FACEs( ref_EDGE_ptr, attached_FACE_list );
-
- if( attached_FACE_list.move_to( ref_FACE_ptr ) == CUBIT_TRUE )
- attached_FACE_list.extract();
-
- FACE *FACE_ptr;
- for( j=attached_FACE_list.size(); j--; )
- {
- FACE_ptr = attached_FACE_list.get_and_step();
- if( FACE_list_in.is_in_list( FACE_ptr ) == CUBIT_TRUE )
- {
- num_found++;
- break;
- }
- }
- }
-
- if( num_found == ref_FACE_edges.size() )
- return CUBIT_TRUE;
-
- return CUBIT_FALSE;
-}
-
-//=============================================================================
-// Function : get_outer_EDGEs
-// Member Type: PRIVATE
-// Description: Get EDGEs from outer LOOP of FACE
-// Author : Steve Storm
-// Date : 01/03/06
-//=============================================================================
-CubitStatus
-AcisTweakTool::get_outer_EDGEs( FACE *FACE_ptr, DLIList<EDGE*> &EDGE_list )
-{
- // Loop through LOOPs
- outcome result;
- logical external;
-
- LOOP *LOOP_ptr = FACE_ptr->loop();
- while( LOOP_ptr != NULL )
- {
- result = api_loop_external( LOOP_ptr, &external );
- if( !result.ok() )
- {
- AQE->ACIS_API_error(result);
- return CUBIT_FAILURE;
- }
-
- if( external == TRUE )
- {
- AQE->get_EDGEs( LOOP_ptr, EDGE_list );
- return CUBIT_SUCCESS;
- }
-
- LOOP_ptr = LOOP_ptr->next();
- }
-
- return CUBIT_FAILURE;
-}
-
-//=============================================================================
-// Function : tweak_target
-// Member Type: PUBLIC
-// Description: Tweak specified edges of a surface or set of surfaces (in sheet
-// bodies) up to a single target surface or a set of target
-// surfaces.
-// Author : Steve Storm
-// Date : 03/28/05
-//=============================================================================
-CubitStatus
-AcisTweakTool::tweak_target( DLIList<Curve*> &input_curve_list,
- DLIList<Surface*> &target_surf_list,
+CubitStatus AcisTweakTool::tweak_chamfer( DLIList<Curve*> &curve_list,
+ double left_offset,
DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean reverse_flg,
- CubitBoolean keep_old_bodies,
- CubitBoolean preview )
+ double right_offset /*= -1.0*/,
+ CubitBoolean keep_old_body /*= CUBIT_FALSE*/,
+ CubitBoolean preview /*= CUBIT_FALSE*/ )
{
-#ifndef ACIS_LOCAL_OPS
- PRINT_ERROR( "The ACIS Local Operations Husk is required for tweaking\n"
- " surfaces to a target. It has not been licensed for this installation.\n" );
- return CUBIT_FAILURE;
-#endif
-
- if( target_surf_list.size() == 1 )
- {
- return tweak_target_single( input_curve_list, target_surf_list.get(),
- new_bodysm_list, reverse_flg, keep_old_bodies, preview );
- }
- else
- {
- return tweak_target_multiple( input_curve_list, target_surf_list,
- new_bodysm_list, reverse_flg, keep_old_bodies, preview );
- }
-}
-
-//=============================================================================
-// Function : tweak_target_single
-// Member Type: PRIVATE
-// Description: Tweak specified edges of a surface or set of surfaces (in sheet
-// bodies) up to a single target surface.
-// Author : Steve Storm
-// Date : 03/28/05
-//=============================================================================
-CubitStatus
-AcisTweakTool::tweak_target_single( DLIList<Curve*> &input_curve_list,
- Surface *target_surf_ptr,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean reverse_flg,
- CubitBoolean keep_old_bodies,
- CubitBoolean preview )
-{
-#ifndef ACIS_LOCAL_OPS
- PRINT_ERROR( "The ACIS Local Operations Husk is required for tweaking\n"
- " curves. It has not been licensed for this installation.\n" );
- return CUBIT_FAILURE;
-#endif
-
- // Get target FACE
- SurfaceACIS* target_surface = dynamic_cast<SurfaceACIS*>(target_surf_ptr);
- if( !target_surface )
- {
- PRINT_ERROR("Cannot tweak to non-ACIS target surface.\n");
+ PRINT_ERROR("This feature is not implemented.\n");
return CUBIT_FAILURE;
- }
-
- // Copy the target face (in some cases, the target face can be modified -
- // if for example it is tweaked to itself, which is sometimes done to
- // remove unwanted topology or to fix an error). This preserves the target
- // in that case.
- ENTITY *copied_entity_ptr;
- outcome result = api_copy_entity_contents( target_surface->get_FACE_ptr(),
- copied_entity_ptr );
- if( !result.ok() )
- {
- AcisQueryEngine::instance()->ACIS_API_error(result);
- return CUBIT_FAILURE;
- }
- FACE *target_FACE_ptr = (FACE *)copied_entity_ptr;
-
- // Get source EDGEs
- DLIList<EDGE*> input_EDGE_list( input_curve_list.size() );
- if( get_EDGEs( input_curve_list, input_EDGE_list ) == CUBIT_FAILURE )
- {
- api_delent( target_FACE_ptr );
- return CUBIT_FAILURE;
- }
-
- // Call private function to do the work
- if( tweak_target_single( input_EDGE_list, target_FACE_ptr, new_bodysm_list,
- reverse_flg, keep_old_bodies, preview ) == CUBIT_FAILURE )
- {
- api_delent( target_FACE_ptr );
- return CUBIT_FAILURE;
- }
-
- api_delent( target_FACE_ptr );
-
- return CUBIT_SUCCESS;
}
-//=============================================================================
-// Function : tweak_target_multiple
-// Member Type: PRIVATE
-// Description: Tweak specified edges of a surface or set of surfaces (in sheet
-// bodies) up to a set of target surfaces.
-// Author : Steve Storm
-// Date : 11/03/05
-//=============================================================================
-CubitStatus
-AcisTweakTool::tweak_target_multiple( DLIList<Curve*> &input_curve_list,
- DLIList<Surface*> &target_surf_list,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean reverse_flg,
- CubitBoolean keep_old_bodies,
- CubitBoolean preview )
-{
-#ifndef ACIS_LOCAL_OPS
- PRINT_ERROR( "The ACIS Local Operations Husk is required for extending\n"
- " surfaces. It has not been licensed for this installation.\n" );
- return CUBIT_FAILURE;
-#endif
-
- // Get source curves
- DLIList<EDGE*> input_EDGE_list( input_curve_list.size() );
- if( get_EDGEs( input_curve_list, input_EDGE_list ) == CUBIT_FAILURE )
- return CUBIT_FAILURE;
-
- // Get target FACES
- DLIList<FACE*> target_FACE_list( target_surf_list.size() );
- if( get_FACEs( target_surf_list, target_FACE_list ) == CUBIT_FAILURE )
- return CUBIT_FAILURE;
-
- // Call private function to do the work
- if( tweak_target_multiple( input_EDGE_list, target_FACE_list,
- new_bodysm_list, reverse_flg, keep_old_bodies, preview ) == CUBIT_FAILURE )
- return CUBIT_FAILURE;
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : tweak_target
-// Member Type: PUBLIC
-// Description: Tweak specified edges of a sheet body or bodies up to a set of
-// target curves that are part of a sheet body. The target is a
-// surface or surfaces created by thickening the owning surfaces
-// of the target curves.
-// Author : Steve Storm
-// Date : 03/28/05
-//=============================================================================
-CubitStatus
-AcisTweakTool::tweak_target( DLIList<Curve*> &input_curve_list,
- DLIList<Curve*> &target_curve_list,
+CubitStatus AcisTweakTool::tweak_chamfer( DLIList<Point*> &point_list,
+ double offset1,
DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean reverse_flg,
- CubitBoolean keep_old_bodies,
- CubitBoolean preview )
+ Curve *edge1 /*= NULL*/,
+ double offset2 /*= -1.0*/,
+ Curve *edge2 /*= NULL*/,
+ double offset3 /*= -1.0*/,
+ Curve *edge3 /*= NULL*/,
+ CubitBoolean keep_old_body /*= CUBIT_FALSE*/,
+ CubitBoolean preview /*= CUBIT_FALSE*/ )
{
-#ifndef ACIS_LOCAL_OPS
- PRINT_ERROR( "The ACIS Local Operations Husk is required for extending\n"
- " surfaces. It has not been licensed for this installation.\n" );
- return CUBIT_FAILURE;
-#endif
-
- if( target_curve_list.size() == 1 )
- {
- return tweak_target_single( input_curve_list, target_curve_list.get(),
- new_bodysm_list, reverse_flg, keep_old_bodies, preview );
- }
- else
- {
- return tweak_target_multiple( input_curve_list, target_curve_list,
- new_bodysm_list, reverse_flg, keep_old_bodies, preview );
- }
-}
-
-//=============================================================================
-// Function : tweak_target_single
-// Member Type: PRIVATE
-// Description: Tweak specified edges of a sheet body or bodies up to a single
-// target curve that is part of a sheet body. The target is a
-// surface created by thickening the owning surface of the target
-// curve.
-// Author : Steve Storm
-// Date : 03/28/05
-//=============================================================================
-CubitStatus
-AcisTweakTool::tweak_target_single( DLIList<Curve*> &curve_list,
- Curve *target_curve_ptr,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean reverse_flg,
- CubitBoolean keep_old_bodies,
- CubitBoolean preview )
-{
-#ifndef ACIS_LOCAL_OPS
- PRINT_ERROR( "The ACIS Local Operations Husk is required for extending\n"
- " surfaces. It has not been licensed for this installation.\n" );
- return CUBIT_FAILURE;
-#endif
-
- // We need to build the target FACE by grabbing the associated surfaces and
- // thickening them. For convenience, use the get_thickened_BODIES_of_EDGES
- // function to do this.
- EDGE *target_EDGE_ptr = AcisQueryEngine::instance()->
- get_EDGE( target_curve_ptr );
- if( target_EDGE_ptr == NULL )
- {
- PRINT_ERROR( "Target must be an ACIS curve.\n" );
+ PRINT_ERROR("This feature is not implemented.\n");
return CUBIT_FAILURE;
- }
- BODY *BODY_ptr;
- DLIList<EDGE*> removed_EDGE_list;
- DLIList<EDGE*> target_EDGE_list( 1 );
- target_EDGE_list.append( target_EDGE_ptr );
- DLIList<BODY*> thickened_BODY_list;
- DLIList<DLIList<EDGE*>*> output_EDGE_lists;
- DLIList<DLIList<FACE*>*> output_FACE_lists;
- DLIList<DLIList<FACE*>*> conjugate_FACE_lists;
- if( get_thickened_BODIES_of_EDGES( "tweak to", target_EDGE_list,
- removed_EDGE_list, BODY_ptr, thickened_BODY_list, output_EDGE_lists,
- output_FACE_lists, conjugate_FACE_lists ) == CUBIT_FAILURE )
- {
- PRINT_ERROR( "unable to setup target -- aborting\n" );
- return CUBIT_FAILURE;
- }
-
- FACE *target_FACE_ptr = conjugate_FACE_lists.get()->get();
-
- // Clean up memory allocated for the output lists
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( conjugate_FACE_lists.size() ) delete conjugate_FACE_lists.pop();
-
- if( target_FACE_ptr == NULL )
- {
- while( thickened_BODY_list.size() ) api_delent( thickened_BODY_list.pop() );
- PRINT_ERROR( "unable to setup target -- aborting\n" );
- return CUBIT_FAILURE;
- }
-
- // Needed for preview - target might be on BODY we are tweaking and we need
- // to check for that in the preview.
- DLIList<AcisBridge*> preview_ab_list;
- preview_ab_list.append( ATTRIB_CUBIT_OWNER::cubit_owner(target_EDGE_ptr) );
-
- // Call private function to do the work
- DLIList<EDGE*> EDGE_list( curve_list.size() );
- if( get_EDGEs( curve_list, EDGE_list ) == CUBIT_FAILURE )
- return CUBIT_FAILURE;
-
- CubitStatus status;
- status = tweak_target_single( EDGE_list, target_FACE_ptr, new_bodysm_list,
- reverse_flg, keep_old_bodies, preview, &preview_ab_list );
-
- // Delete thickened BODY
- while( thickened_BODY_list.size() ) api_delent( thickened_BODY_list.pop() );
-
- return status;
}
-//=============================================================================
-// Function : tweak_target_multiple
-// Member Type: PRIVATE
-// Description: Tweak specified edges of a sheet body or bodies up to a set
-// of target curves that are part of a sheet body or bodies. The
-// target is a set of surfaces created by thickening the owning
-// surfaces of the target curves.
-// Author : Steve Storm
-// Date : 02/13/06
-//=============================================================================
-CubitStatus
-AcisTweakTool::tweak_target_multiple( DLIList<Curve*> &input_curve_list,
- DLIList<Curve*> &target_curve_list,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean reverse_flg,
- CubitBoolean keep_old_bodies,
- CubitBoolean preview )
+CubitStatus AcisTweakTool::tweak_fillet( DLIList<Curve*> &curve_list,
+ double radius,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean keep_old_body /*= CUBIT_FALSE*/,
+ CubitBoolean preview /*= CUBIT_FALSE*/ )
{
-#ifndef ACIS_LOCAL_OPS
- PRINT_ERROR( "The ACIS Local Operations Husk is required for extending\n"
- " surfaces. It has not been licensed for this installation.\n" );
- return CUBIT_FAILURE;
-#endif
-
- // Get source curves
- DLIList<EDGE*> input_EDGE_list( input_curve_list.size() );
- if( get_EDGEs( input_curve_list, input_EDGE_list ) == CUBIT_FAILURE )
+ PRINT_ERROR("This feature is not implemented.\n");
return CUBIT_FAILURE;
-
- // Get target FACES
- DLIList<EDGE*> target_EDGE_list;
- if( get_EDGEs( target_curve_list, target_EDGE_list ) == CUBIT_FAILURE )
- return CUBIT_FAILURE;
-
- // Build list of FACEs which could be from multiple BODIES
- DLIList<FACE*> target_FACE_list;
- DLIList<BODY*> thickened_BODY_list;
- while( target_EDGE_list.size() )
- {
- BODY *BODY_ptr;
- DLIList<EDGE*> removed_EDGE_list;
- DLIList<BODY*> tmp_thickened_BODY_list;
- DLIList<DLIList<EDGE*>*> output_EDGE_lists;
- DLIList<DLIList<FACE*>*> output_FACE_lists;
- DLIList<DLIList<FACE*>*> conjugate_FACE_lists;
- if( get_thickened_BODIES_of_EDGES( "tweak to", target_EDGE_list,
- removed_EDGE_list, BODY_ptr, tmp_thickened_BODY_list, output_EDGE_lists,
- output_FACE_lists, conjugate_FACE_lists ) == CUBIT_FAILURE )
- {
- PRINT_ERROR( "unable to setup target -- aborting\n" );
- return CUBIT_FAILURE;
- }
-
- // The conjugate FACEs are what we are after
- int i, j;
- conjugate_FACE_lists.reset();
- for( i=conjugate_FACE_lists.size(); i--; )
- {
- DLIList<FACE*> *FACE_list_ptr = conjugate_FACE_lists.get_and_step();
-
- FACE *FACE_ptr;
- FACE_list_ptr->reset();
- for( j=FACE_list_ptr->size(); j--; )
- {
- FACE_ptr = FACE_list_ptr->get_and_step();
- target_FACE_list.append( FACE_ptr );
- }
- }
-
- // Clean up memory allocated for the output lists
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( conjugate_FACE_lists.size() ) delete conjugate_FACE_lists.pop();
-
- thickened_BODY_list += tmp_thickened_BODY_list;
- }
-
- // Needed for preview - targets might be on BODY we are tweaking and we need
- // to check for that in the preview.
- DLIList<AcisBridge*> preview_ab_list;
- if( preview ) get_owner_list( target_EDGE_list, preview_ab_list );
-
- // Call private function to do the work
- if( tweak_target_multiple( input_EDGE_list, target_FACE_list,
- new_bodysm_list, reverse_flg, keep_old_bodies, preview, &preview_ab_list )
- == CUBIT_FAILURE )
- {
- while( thickened_BODY_list.size() ) api_delent( thickened_BODY_list.pop() );
- return CUBIT_FAILURE;
- }
-
- // Delete the thickened target BODIES
- while( thickened_BODY_list.size() ) api_delent( thickened_BODY_list.pop() );
-
- return CUBIT_SUCCESS;
}
-CubitStatus AcisTweakTool::get_ACIS_surfaces( DLIList<Surface*>& surf_list,
- DLIList<SurfaceACIS*>& acis_list )
+CubitStatus AcisTweakTool::tweak_fillet( Curve *curve_ptr,
+ double start_radius,
+ double end_radius,
+ BodySM *&new_body_ptr,
+ CubitBoolean keep_old_body /*= CUBIT_FALSE*/,
+ CubitBoolean preview /*= CUBIT_FALSE */)
{
- int i;
- surf_list.reset();
- for( i=surf_list.size(); i--; )
- {
- Surface* surf = surf_list.get_and_step();
- if (SurfaceACIS* surf_acis = dynamic_cast<SurfaceACIS*>(surf))
- acis_list.append(surf_acis);
- }
-
- if (surf_list.size() != acis_list.size())
- {
- PRINT_ERROR("%d non-ACIS Surfaces.\n", surf_list.size() - acis_list.size());
+ PRINT_ERROR("This feature is not implemented.\n");
return CUBIT_FAILURE;
- }
-
- return CUBIT_SUCCESS;
}
-CubitStatus AcisTweakTool::get_FACEs( DLIList<Surface*> &surface_list,
- DLIList<FACE*> &FACE_list )
+CubitStatus AcisTweakTool::tweak_fillet( DLIList<Point*> &point_list,
+ double radius,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean keep_old_body /*= CUBIT_FALSE*/,
+ CubitBoolean preview /*= CUBIT_FALSE*/ )
{
- int i;
- FACE *FACE_ptr;
- surface_list.reset();
- for( i=surface_list.size(); i--; )
- {
- Surface* surface_ptr = surface_list.get_and_step();
- FACE_ptr = AcisQueryEngine::instance()->get_FACE( surface_ptr );
- if( FACE_ptr ) FACE_list.append( FACE_ptr );
- }
-
- if( surface_list.size() != FACE_list.size() )
- {
- PRINT_ERROR("%d non-ACIS surfaces.\n", surface_list.size() - FACE_list.size());
+ PRINT_ERROR("This feature is not implemented.\n");
return CUBIT_FAILURE;
- }
-
- return CUBIT_SUCCESS;
}
-CubitStatus AcisTweakTool::get_EDGEs( DLIList<Curve*> &curve_list,
- DLIList<EDGE*> &EDGE_list )
+CubitStatus AcisTweakTool::tweak_move( DLIList<Surface*> &surface_list,
+ const CubitVector &delta,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean keep_old_body /*= CUBIT_FALSE*/,
+ CubitBoolean preview /*= CUBIT_FALSE */)
{
- int i;
- EDGE *EDGE_ptr;
- curve_list.reset();
- for( i=curve_list.size(); i--; )
- {
- Curve* curve_ptr = curve_list.get_and_step();
- EDGE_ptr = AcisQueryEngine::instance()->get_EDGE( curve_ptr );
- if( EDGE_ptr ) EDGE_list.append( EDGE_ptr );
- }
-
- if( curve_list.size() != EDGE_list.size() )
- {
- PRINT_ERROR("%d non-ACIS curves.\n", curve_list.size() - EDGE_list.size());
+ PRINT_ERROR("This feature is not implemented.\n");
return CUBIT_FAILURE;
- }
-
- return CUBIT_SUCCESS;
}
-CubitStatus AcisTweakTool::get_VERTICEs( DLIList<Point*> &point_list,
- DLIList<VERTEX*> &VERTEX_list )
+CubitStatus AcisTweakTool::tweak_move( DLIList<Curve*> &curve_list,
+ const CubitVector &delta,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean keep_old_body /*= CUBIT_FALSE*/,
+ CubitBoolean preview /*= CUBIT_FALSE*/ )
{
- int i;
- VERTEX *VERTEX_ptr;
- point_list.reset();
- for( i=point_list.size(); i--; )
- {
- Point* point_ptr = point_list.get_and_step();
- VERTEX_ptr = AcisQueryEngine::instance()->get_VERTEX( point_ptr );
- if( VERTEX_ptr ) VERTEX_list.append( VERTEX_ptr );
- }
-
- if( point_list.size() != VERTEX_list.size() )
- {
- PRINT_ERROR("%d non-ACIS vertices.\n", point_list.size() - VERTEX_list.size());
+ PRINT_ERROR("This feature is not implemented.\n");
return CUBIT_FAILURE;
- }
-
- return CUBIT_SUCCESS;
}
-//=============================================================================
-// Function : tweak_target
-// Member Type: PRIVATE
-// Description: Tweak specified EDGES of a surface or set of surfaces (in
-// sheet bodies) up to a single target FACE.
-// Author : Steve Storm
-// Date : 03/28/05
-//=============================================================================
-CubitStatus
-AcisTweakTool::tweak_target_single( DLIList<EDGE*> &input_EDGE_list,
- FACE *target_FACE_ptr,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean reverse_flg,
- CubitBoolean keep_old_bodies,
- CubitBoolean preview,
- DLIList<AcisBridge*> *t_ab_list_ptr )
+CubitStatus AcisTweakTool::tweak_offset( DLIList<Surface*> &surface_list,
+ double offset_distance,
+ DLIList<Surface*> *add_surface_list_ptr,
+ DLIList<double> *add_offset_list_ptr,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean keep_old_body /*= CUBIT_FALSE*/,
+ CubitBoolean preview /*= CUBIT_FALSE*/ )
{
- assert( input_EDGE_list.size() );
-
- int i, j;
-
- bool delete_attribs =
- (GeometryModifyTool::instance()->get_new_ids() || keep_old_bodies);
-
- // Copy the input EDGE list, since we will be removing EDGEs from it
- DLIList<EDGE*> copied_EDGE_list = input_EDGE_list;
-
- copied_EDGE_list.reset();
- while( copied_EDGE_list.size() )
- {
- BODY *BODY_ptr;
- DLIList<EDGE*> removed_EDGE_list;
- DLIList<BODY*> thickened_BODY_list;
- DLIList<DLIList<EDGE*>*> output_EDGE_lists;
- DLIList<DLIList<FACE*>*> output_FACE_lists;
- DLIList<DLIList<FACE*>*> conjugate_FACE_lists;
- if( get_thickened_BODIES_of_EDGES( "tweak", copied_EDGE_list,
- removed_EDGE_list, BODY_ptr, thickened_BODY_list, output_EDGE_lists,
- output_FACE_lists, conjugate_FACE_lists ) == CUBIT_FAILURE )
- {
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- BodySM *bodysm_ptr = AQE->get_body_sm_of_ENTITY( BODY_ptr );
-
- // Store source and target EDGEs for preview
- DLIList<AcisBridge*> preview_ab_list;
- if( preview )
- {
- get_owner_list( removed_EDGE_list, preview_ab_list );
- if( t_ab_list_ptr ) preview_ab_list += *t_ab_list_ptr;
- }
-
- // Tweak the surfaces on the output BODIEs, pull the tweaked surfaces off,
- // and replace them in the original BODY
- // First copy the BODY
- BODY *copied_BODY_ptr = AME->copy_BODY(BODY_ptr, CUBIT_FALSE);
-
- BODY *thickened_BODY_ptr;
- DLIList<FACE*> *output_FACE_list_ptr;
- DLIList<FACE*> *conjugate_FACE_list_ptr;
- thickened_BODY_list.reset();
- output_EDGE_lists.reset();
- output_FACE_lists.reset();
- conjugate_FACE_lists.reset();
- for( i=thickened_BODY_list.size(); i--; )
- {
- thickened_BODY_ptr = thickened_BODY_list.get_and_step();
- output_FACE_list_ptr = output_FACE_lists.get_and_step();
- conjugate_FACE_list_ptr = conjugate_FACE_lists.get_and_step();
-
- // Note - the conjugate FACE list can have duplicate entries in
- // it, as thicken doesn't always create a separate surface for
- // each curve.
- DLIList<FACE*> tweak_FACE_list;
- conjugate_FACE_list_ptr->reset();
- for( j=conjugate_FACE_list_ptr->size(); j--; )
- tweak_FACE_list.append_unique( conjugate_FACE_list_ptr->get_and_step() );
-
- // Keep track of the FACEs of interest, via their Cubit owners, which
- // will survive throughout the operation
- DLIList<AcisBridge*> owner_list;
- get_owner_list( *output_FACE_list_ptr, owner_list );
-
- // Do the tweak
- if( tweak_FACEs_to_target( tweak_FACE_list, target_FACE_ptr, reverse_flg )
- == CUBIT_FAILURE )
- {
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( conjugate_FACE_lists.size() ) delete conjugate_FACE_lists.pop();
- while( thickened_BODY_list.size() )
- api_delent( thickened_BODY_list.pop() );
- api_delent( copied_BODY_ptr );
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- // Get bodies ready to swap new surfaces for old
- if( prep_for_surface_swap( thickened_BODY_ptr, copied_BODY_ptr,
- owner_list ) == CUBIT_FAILURE )
- {
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( conjugate_FACE_lists.size() ) delete conjugate_FACE_lists.pop();
- while( thickened_BODY_list.size() )
- api_delent( thickened_BODY_list.pop() );
- api_delent( copied_BODY_ptr );
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- } // End loop on thickened (separated) BODIES
-
- // Free memory
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( conjugate_FACE_lists.size() ) delete conjugate_FACE_lists.pop();
-
- // Unite the thickened BODIEs back into the copied_input_BODY_ptr
- BODY *master;
- if( unite_BODIES( copied_BODY_ptr, thickened_BODY_list, master ) == CUBIT_FAILURE )
- {
- // If failure, the unite_BODIES function cleaned up the memory
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- // This BODY is done (whew!)
-
- if( !preview )
- {
- // Now cleanout the owner attributes from the copied BODY, if required
- if( delete_attribs )
- AQE->remove_cubit_owner_attrib_in_BODY( master );
-
- BodySM *new_body = AME->get_new_Body( bodysm_ptr, BODY_ptr, master,
- keep_old_bodies );
-
- if( new_body )
- new_bodysm_list.append( new_body );
- }
- else
- {
- GfxPreview::clear();
-
- draw_tweak_preview_omt( master, CUBIT_TRUE, &preview_ab_list );
- api_delent( master );
- }
- }
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : tweak_target_multiple
-// Member Type: PRIVATE
-// Description: Tweak specified EDGES of a surface or set of surfaces (in
-// sheet bodies) up to a multiple target FACEs.
-// Author : Steve Storm
-// Date : 03/28/05
-//=============================================================================
-CubitStatus
-AcisTweakTool::tweak_target_multiple( DLIList<EDGE*> &input_EDGE_list,
- DLIList<FACE*> &target_FACE_list,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean reverse_flg,
- CubitBoolean keep_old_bodies,
- CubitBoolean preview,
- DLIList<AcisBridge*> *preview_ab_list_ptr )
-{
- assert( input_EDGE_list.size() );
-
- int i, j;
-
- bool delete_attribs =
- (GeometryModifyTool::instance()->get_new_ids() || keep_old_bodies);
-
- // Get extended target surfaces (in a single sheet BODY)
- BODY *ext_target_BODY_ptr;
- if( create_extended_sheet( target_FACE_list, ext_target_BODY_ptr )
- == CUBIT_FAILURE )
+ PRINT_ERROR("This feature is not implemented.\n");
return CUBIT_FAILURE;
-
- if( DEBUG_FLAG(168) )
- {
- BODY *tmp_BODY = AME->copy_BODY( ext_target_BODY_ptr, CUBIT_TRUE );
- BodySM *this_bodysm = AQE->populate_topology_bridges( tmp_BODY );
- new_bodysm_list.append( this_bodysm );
- }
-
- // Copy the input EDGE list, since we will be removing EDGEs from it
- DLIList<EDGE*> copied_EDGE_list = input_EDGE_list;
-
- copied_EDGE_list.reset();
- while( copied_EDGE_list.size() )
- {
- BODY *BODY_ptr;
- DLIList<EDGE*> removed_EDGE_list;
- DLIList<BODY*> thickened_BODY_list;
- DLIList<DLIList<EDGE*>*> output_EDGE_lists;
- DLIList<DLIList<FACE*>*> output_FACE_lists;
- DLIList<DLIList<FACE*>*> conjugate_FACE_lists;
- if( get_thickened_BODIES_of_EDGES( "tweak", copied_EDGE_list,
- removed_EDGE_list, BODY_ptr, thickened_BODY_list, output_EDGE_lists,
- output_FACE_lists, conjugate_FACE_lists ) == CUBIT_FAILURE )
- {
- api_delent( ext_target_BODY_ptr );
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- BodySM *bodysm_ptr = AQE->get_body_sm_of_ENTITY( BODY_ptr );
-
- // Tweak the surfaces on the output BODIEs, pull the tweaked surfaces off,
- // and replace them in the original BODY
- // First copy the BODY
- BODY *copied_BODY_ptr = AME->copy_BODY(BODY_ptr, CUBIT_FALSE);
-
- // Store source and target EDGEs for preview
- DLIList<AcisBridge*> preview_ab_list;
- if( preview )
- {
- get_owner_list( removed_EDGE_list, preview_ab_list );
- if( preview_ab_list_ptr ) preview_ab_list += *preview_ab_list_ptr;
- }
-
- BODY *thickened_BODY_ptr;
- DLIList<FACE*> *output_FACE_list_ptr;
- DLIList<FACE*> *conjugate_FACE_list_ptr;
- thickened_BODY_list.reset();
- output_EDGE_lists.reset();
- output_FACE_lists.reset();
- conjugate_FACE_lists.reset();
- for( i=thickened_BODY_list.size(); i--; )
- {
- thickened_BODY_ptr = thickened_BODY_list.get_and_step();
- output_FACE_list_ptr = output_FACE_lists.get_and_step();
- conjugate_FACE_list_ptr = conjugate_FACE_lists.get_and_step();
-
- // Note - the conjugate FACE list can have duplicate entries in
- // it, as thicken doesn't always create a separate surface for
- // each curve.
- DLIList<FACE*> tweak_FACE_list;
- conjugate_FACE_list_ptr->reset();
- for( j=conjugate_FACE_list_ptr->size(); j--; )
- tweak_FACE_list.append_unique( conjugate_FACE_list_ptr->get_and_step() );
-
- // Keep track of the FACEs of interest, via their Cubit owners, which
- // will survive throughout the operation
- DLIList<AcisBridge*> owner_list;
- get_owner_list( *output_FACE_list_ptr, owner_list );
-
- // Do the tweak
- if( tweak_target_multiple( tweak_FACE_list, target_FACE_list,
- ext_target_BODY_ptr, new_bodysm_list, reverse_flg )
- == CUBIT_FAILURE )
- {
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( conjugate_FACE_lists.size() ) delete conjugate_FACE_lists.pop();
- while( thickened_BODY_list.size() )
- api_delent( thickened_BODY_list.pop() );
- api_delent( ext_target_BODY_ptr );
- api_delent( copied_BODY_ptr );
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- // Get bodies ready to swap new surfaces for old
- if( prep_for_surface_swap( thickened_BODY_ptr, copied_BODY_ptr,
- owner_list ) == CUBIT_FAILURE )
- {
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( conjugate_FACE_lists.size() ) delete conjugate_FACE_lists.pop();
- while( thickened_BODY_list.size() )
- api_delent( thickened_BODY_list.pop() );
- api_delent( ext_target_BODY_ptr );
- api_delent( copied_BODY_ptr );
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- } // End loop on thickened (separated) BODIES
-
- // Free memory
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( conjugate_FACE_lists.size() ) delete conjugate_FACE_lists.pop();
-
- // Unite the thickened BODIEs back into the copied_input_BODY_ptr
- BODY *master;
- if( unite_BODIES( copied_BODY_ptr, thickened_BODY_list, master ) == CUBIT_FAILURE )
- {
- api_delent( ext_target_BODY_ptr );
- // If failure, the unite_BODIES function cleaned up the memory
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- // This BODY is done (whew!)
-
- if( !preview )
- {
- // Now cleanout the owner attributes from the copied BODY, if required
- if( delete_attribs )
- AQE->remove_cubit_owner_attrib_in_BODY( master );
-
- BodySM *new_body = AME->get_new_Body( bodysm_ptr, BODY_ptr, master,
- keep_old_bodies );
-
- if( new_body )
- new_bodysm_list.append( new_body );
- }
- else
- {
- GfxPreview::clear();
-
- // Preview EDGEs
- draw_tweak_preview_omt( master, CUBIT_TRUE, &preview_ab_list );
- api_delent( master );
- }
- }
-
- api_delent( ext_target_BODY_ptr );
-
- return CUBIT_SUCCESS;
}
-//=============================================================================
-// Function : copy_FACES_from_BODY
-// Member Type: PRIVATE
-// Description: Input FACE list must be in a single BODY. Copy these FACEs off
-// into a new BODY, while retaining all the Cubit attributes. The
-// input BODY (the parent BODY of the FACE_list) is NOT modified.
-// Author : Steve Storm
-// Date : 03/28/05
-//=============================================================================
-CubitStatus
-AcisTweakTool::copy_FACES_from_BODY( DLIList<FACE*> &input_FACE_list,
- BODY *&copied_BODY_ptr)
+CubitStatus AcisTweakTool::make_offset_sheet( DLIList<Surface*> &surface_list,
+ double def_offset,
+ DLIList<Surface*> *add_surface_list_ptr,
+ DLIList<double> *add_offset_list_ptr,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean preview /*= CUBIT_FALSE*/ )
{
- // Method - copy the body and remove the other faces from the body. We tried
- // copying the faces off into a new body using api_unhook_faces, or
- // copy_single_entity, etc., but the cubit attributes on the copied faces
- // always seem to disappear. This method, which may seem like an odd way
- // to approach the problem, is guaranteed to keep the cubit attributes on
- // the resultant body. It also guarantees a single body as a result (note
- // the resultant body may need to be separated, as it may have disconnected
- // faces).
- int i;
- FACE *FACE_ptr;
- BODY *input_BODY_ptr;
-
- // Get owning BODY of the FACE_list
- input_FACE_list.reset();
- FACE_ptr = input_FACE_list.get_and_step();
- input_BODY_ptr = AcisQueryEngine::instance()->get_BODY_of_ENTITY( FACE_ptr );
-
- // Error check - make sure remaining FACEs are from same BODY
- for( i=1; i<input_FACE_list.size(); i++ )
- {
- FACE_ptr = input_FACE_list.get_and_step();
- if( input_BODY_ptr != AcisQueryEngine::instance()->get_BODY_of_ENTITY( FACE_ptr ) )
- return CUBIT_FAILURE;
- }
-
- // Get a list of all the associated Surfaces to the input FACEs
- AcisBridge *ab_ptr;
- SurfaceACIS *asurf_ptr;
- DLIList<SurfaceACIS*> input_asurface_list( input_FACE_list.size() );
- input_FACE_list.reset();
- for( i=input_FACE_list.size(); i--; )
- {
- FACE_ptr = input_FACE_list.get_and_step();
- ab_ptr = ATTRIB_CUBIT_OWNER::cubit_owner(FACE_ptr);
- asurf_ptr = CAST_TO( ab_ptr, SurfaceACIS );
- if( asurf_ptr == NULL )
- {
- PRINT_ERROR( "Internal error -- please report.\n" );
- return CUBIT_FAILURE;
- }
- input_asurface_list.append( asurf_ptr );
- }
-
- // Copy the input BODY, keeping all the cubit attributes
- copied_BODY_ptr = AcisModifyEngine::instance()->copy_BODY(input_BODY_ptr,
- CUBIT_FALSE);
-
- DLIList<FACE*> remove_FACE_list;
-
- // Remove the "unused" FACEs from the copied BODY. Loop on FACEs in
- // copied_BODY_ptr
-
- DLIList<FACE*> FACE_list;
- AcisQueryEngine::instance()->get_FACEs( copied_BODY_ptr, FACE_list );
- for( i=FACE_list.size(); i--; )
- {
- FACE_ptr = FACE_list.get_and_step();
-
- ab_ptr = ATTRIB_CUBIT_OWNER::cubit_owner(FACE_ptr);
- asurf_ptr = CAST_TO( ab_ptr, SurfaceACIS );
-
- // If we don't find a matching asurf_ptr in input_asurface_list remove
- // this FACE
- if( !asurf_ptr || (asurf_ptr && !input_asurface_list.is_in_list( asurf_ptr )) )
- remove_FACE_list.append( FACE_ptr );
- }
-
- if( remove_FACES_from_BODY( copied_BODY_ptr, remove_FACE_list ) == CUBIT_FAILURE )
- {
- api_delent( copied_BODY_ptr );
- copied_BODY_ptr = NULL;
- }
-
- return CUBIT_SUCCESS;
-}
-
-CubitStatus
-AcisTweakTool::remove_FACES_from_BODY( BODY *BODY_ptr,
- DLIList<FACE*> &remove_FACE_list )
-{
- if( remove_FACE_list.size() == 0 )
- return CUBIT_SUCCESS;
-
- // I'm not sure why, but this operation can cause cubit owner attributes to
- // disappear from copied_BODY_ptr. We need to put them back.
- AcisBridge *ab_body_ptr;
- AcisBridge *ab_lump_ptr;
- AcisBridge *ab_shell_ptr;
- get_owner_attribs( BODY_ptr, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
-
- int i;
- outcome result;
- //ENTITY_LIST faces_to_remove;
- FACE *FACE_ptr;
- for( i=remove_FACE_list.size(); i--; )
- {
- FACE_ptr = remove_FACE_list.get_and_step();
- //faces_to_remove.add( FACE_ptr );
- result = api_remove_face( FACE_ptr );
- if( !result.ok() )
- {
- AcisQueryEngine::instance()->ACIS_API_error(result);
- return CUBIT_FAILURE;
- }
- }
-
- // This doesn't work, because all attributes are removed from the input body.
- // I think this would be faster than the method we are using.
- // This must be an acis bug...
- //ENTITY_LIST unhooked_bodies;
- //result = api_unhook_faces( faces_to_remove, false, unhooked_bodies );
- //unhooked_bodies.init();
- //ENTITY *ENTITY_ptr = NULL;
- //while( ENTITY_ptr = unhooked_bodies.next() )
- // api_delent( ENTITY_ptr );
- //if( !result.ok() )
- //{
- // AcisQueryEngine::instance()->ACIS_API_error(result);
- // return CUBIT_FAILURE;
- //}
-
- // Put cubit owner attributes back
- reset_owner_attribs( BODY_ptr, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
-
- // For some reason, removing faces causes the remaining faces to be single sided
- result = api_body_to_2d( BODY_ptr );
- if( !result.ok() )
- {
- AcisQueryEngine::instance()->ACIS_API_error(result);
+ PRINT_ERROR("This feature is not implemented.\n");
return CUBIT_FAILURE;
- }
-
- return CUBIT_SUCCESS;
}
-CubitStatus
-AcisTweakTool::remove_FACES_from_BODY_except( BODY *BODY_ptr,
- DLIList<FACE*> &keep_FACE_list )
+CubitStatus AcisTweakTool::tweak_offset( DLIList<Curve*> &curve_list,
+ double offset_distance,
+ DLIList<Curve*> *add_curve_list_ptr,
+ DLIList<double> *add_offset_list_ptr,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean keep_old_body /*= CUBIT_FALSE*/,
+ CubitBoolean preview /*= CUBIT_FALSE*/ )
{
- DLIList<FACE*> FACE_list;
- AcisQueryEngine::instance()->get_FACEs( BODY_ptr, FACE_list );
-
- DLIList<FACE*> remove_FACE_list;
- int i;
- FACE *FACE_ptr;
- for( i=FACE_list.size(); i--; )
- {
- FACE_ptr = FACE_list.get_and_step();
- if( !keep_FACE_list.is_in_list( FACE_ptr ) )
- remove_FACE_list.append( FACE_ptr );
- }
-
- return remove_FACES_from_BODY( BODY_ptr, remove_FACE_list );
-}
-
-CubitStatus
-AcisTweakTool::thicken_BODY( BODY *BODY_ptr, double thickness )
-{
-#if CUBIT_ACIS_VERSION >= 1600
- // ACIS v16 sometimes removes the Cubit owner attributes when thickening -
- // this workaround puts them back.
-
- // Setup tweak attributes so we can preserve Cubit owners on vertices,
- // edges and faces
- DLIList<FACE*> pre_FACE_list;
- DLIList<EDGE*> pre_EDGE_list;
- DLIList<VERTEX*> pre_VERTEX_list;
- DLIList<AcisBridge*> ab_FACE_list, ab_EDGE_list, ab_VERTEX_list;
- assign_tweak_attribs( BODY_ptr, "ttweak", pre_FACE_list, ab_FACE_list,
- pre_EDGE_list, ab_EDGE_list, pre_VERTEX_list, ab_VERTEX_list );
-
- // Also preserve on body, lump and shell
- AcisBridge *ab_body_ptr;
- AcisBridge *ab_lump_ptr;
- AcisBridge *ab_shell_ptr;
- get_owner_attribs( BODY_ptr, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
-#endif
-
- // Keep track of input VERTICEs, EDGEs and FACEs for later use
- DLIList<VERTEX*> input_VERTEX_list;
- AQE->get_VERTICEs( BODY_ptr, input_VERTEX_list );
-
- DLIList<EDGE*> input_EDGE_list;
- AQE->get_EDGEs( BODY_ptr, input_EDGE_list );
-
- DLIList<FACE*> input_FACE_list;
- AQE->get_FACEs( BODY_ptr, input_FACE_list );
-
- // Thicken the body
- SPAposition box_l(0,0,0);
- SPAposition box_h(0,0,0);
- outcome result;
- result = api_sheet_thicken( BODY_ptr, thickness, false, box_l, box_h);
- if (!result.ok())
- {
- AQE->ACIS_API_error(result);
- // Thicken doesn't give any sort of error. Sometimes it won't thicken
- // because of bad geometry, so just give a hint.
- PRINT_ERROR( "geometry problem encountered - try healing the body first\n" );
+ PRINT_ERROR("This feature is not implemented.\n");
return CUBIT_FAILURE;
- }
-
- // Thicken copies the cubit owner attributes from the original entities
- // to the other side. Remove those.
- int i;
-
- VERTEX *VERTEX_ptr;
- DLIList<VERTEX*> VERTEX_list;
- AQE->get_VERTICEs( BODY_ptr, VERTEX_list );
- for( i=VERTEX_list.size(); i--; )
- {
- VERTEX_ptr = VERTEX_list.get_and_step();
- if( !input_VERTEX_list.is_in_list( VERTEX_ptr ) )
- ATTRIB_CUBIT_OWNER::remove_cubit_owner(VERTEX_ptr);
- }
-
- EDGE *EDGE_ptr;
- DLIList<EDGE*> EDGE_list;
- AQE->get_EDGEs( BODY_ptr, EDGE_list );
- for( i=EDGE_list.size(); i--; )
- {
- EDGE_ptr = EDGE_list.get_and_step();
- if( !input_EDGE_list.is_in_list( EDGE_ptr ) )
- ATTRIB_CUBIT_OWNER::remove_cubit_owner(EDGE_ptr);
- }
-
- FACE *FACE_ptr;
- DLIList<FACE*> FACE_list;
- AQE->get_FACEs( BODY_ptr, FACE_list );
- for( i=FACE_list.size(); i--; )
- {
- FACE_ptr = FACE_list.get_and_step();
- if( !input_FACE_list.is_in_list( FACE_ptr ) )
- ATTRIB_CUBIT_OWNER::remove_cubit_owner(FACE_ptr);
- }
-
-#if CUBIT_ACIS_VERSION >= 1600
- // Put cubit owner attributes back on body, lump and shell
- reset_owner_attribs( BODY_ptr, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
-
- // Replace Cubit owners on vertices, edges, and faces
- reassign_cubit_owners_from_tweak_attribs( BODY_ptr, "ttweak",
- pre_FACE_list, ab_FACE_list, pre_EDGE_list, ab_EDGE_list, pre_VERTEX_list,
- ab_VERTEX_list );
-
- // Remove thicken tweak attributes
- remove_named_attribs( BODY_ptr, "ttweak" );
-#endif
-
- return CUBIT_SUCCESS;
}
-VERTEX *
-AcisTweakTool::find_corresponding_VERTEX( VERTEX *ref_VERTEX_ptr,
- DLIList<VERTEX*> &VERTEX_list )
+CubitStatus AcisTweakTool::tweak_remove( DLIList<Surface*> &surface_list,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean extend_adjoining /*= CUBIT_TRUE*/,
+ CubitBoolean keep_old_body /*= CUBIT_FALSE*/,
+ CubitBoolean preview /*= CUBIT_FALSE*/ )
{
- // Get the reference CUBIT owner attribute
- AcisBridge *ab_ptr = ATTRIB_CUBIT_OWNER::cubit_owner(ref_VERTEX_ptr);
- if( !ab_ptr )
- return NULL;
-
- PointACIS *ref_point_acis_ptr = CAST_TO( ab_ptr, PointACIS );
- if( !ref_point_acis_ptr )
- return NULL;
-
- // Find the point with the same CUBIT owner attribute in the input VERTEX list
- VERTEX *VERTEX_ptr;
- PointACIS *point_acis_ptr;
- int i;
- for( i=VERTEX_list.size(); i--; )
- {
- VERTEX_ptr = VERTEX_list.get_and_step();
-
- ab_ptr = ATTRIB_CUBIT_OWNER::cubit_owner(VERTEX_ptr);
- if( !ab_ptr )
- continue;
-
- point_acis_ptr = CAST_TO( ab_ptr, PointACIS );
- if( !point_acis_ptr )
- continue;
-
- if( point_acis_ptr == ref_point_acis_ptr )
- return VERTEX_ptr;
- }
-
- // No match found
- return NULL;
-}
-
-EDGE *
-AcisTweakTool::find_corresponding_EDGE( EDGE *ref_EDGE_ptr,
- DLIList<EDGE*> &EDGE_list )
-{
- // Get the reference CUBIT owner attribute
- AcisBridge *ab_ptr = ATTRIB_CUBIT_OWNER::cubit_owner(ref_EDGE_ptr);
- if( !ab_ptr )
- return NULL;
-
- CurveACIS *ref_curve_acis_ptr = CAST_TO( ab_ptr, CurveACIS );
- if( !ref_curve_acis_ptr )
- return NULL;
-
- // Find the curve with the same CUBIT owner attribute in the input EDGE list
- EDGE *EDGE_ptr;
- CurveACIS *curve_acis_ptr;
- int i;
- for( i=EDGE_list.size(); i--; )
- {
- EDGE_ptr = EDGE_list.get_and_step();
-
- ab_ptr = ATTRIB_CUBIT_OWNER::cubit_owner(EDGE_ptr);
- if( !ab_ptr )
- continue;
-
- curve_acis_ptr = CAST_TO( ab_ptr, CurveACIS );
- if( !curve_acis_ptr )
- continue;
-
- if( curve_acis_ptr == ref_curve_acis_ptr )
- return EDGE_ptr;
- }
-
- // No match found
- return NULL;
-}
-
-
-LOOP *
-AcisTweakTool::find_corresponding_LOOP( LOOP *ref_LOOP_ptr,
- DLIList<LOOP*> &LOOP_list )
-{
- // Get the reference CUBIT owner attribute
- AcisBridge *ab_ptr = ATTRIB_CUBIT_OWNER::cubit_owner(ref_LOOP_ptr);
- if( !ab_ptr )
- return NULL;
-
- LoopACIS *ref_loop_acis_ptr = CAST_TO( ab_ptr, LoopACIS );
- if( !ref_loop_acis_ptr )
- return NULL;
-
- // Find the loop with the same CUBIT owner attribute in the input LOOP list
- LOOP *LOOP_ptr;
- LoopACIS *loop_acis_ptr;
- int i;
- for( i=LOOP_list.size(); i--; )
- {
- LOOP_ptr = LOOP_list.get_and_step();
-
- ab_ptr = ATTRIB_CUBIT_OWNER::cubit_owner(LOOP_ptr);
- if( !ab_ptr )
- continue;
-
- loop_acis_ptr = CAST_TO( ab_ptr, LoopACIS );
- if( !loop_acis_ptr )
- continue;
-
- if( loop_acis_ptr == ref_loop_acis_ptr )
- return LOOP_ptr;
- }
-
- // No match found
- return NULL;
-}
-
-FACE *
-AcisTweakTool::find_corresponding_FACE( FACE *ref_FACE_ptr,
- DLIList<FACE*> &FACE_list )
-{
- // Get the reference CUBIT owner attribute
- AcisBridge *ab_ptr = ATTRIB_CUBIT_OWNER::cubit_owner(ref_FACE_ptr);
- if( !ab_ptr )
- return NULL;
-
- SurfaceACIS *ref_surf_acis_ptr = CAST_TO( ab_ptr, SurfaceACIS );
- if( !ref_surf_acis_ptr )
- return NULL;
-
- // Find the surface with the same CUBIT owner attribute in the input FACE list
- FACE *FACE_ptr;
- SurfaceACIS *surf_acis_ptr;
- int i;
- for( i=FACE_list.size(); i--; )
- {
- FACE_ptr = FACE_list.get_and_step();
-
- ab_ptr = ATTRIB_CUBIT_OWNER::cubit_owner(FACE_ptr);
- if( !ab_ptr )
- continue;
-
- surf_acis_ptr = CAST_TO( ab_ptr, SurfaceACIS );
- if( !surf_acis_ptr )
- continue;
-
- if( surf_acis_ptr == ref_surf_acis_ptr )
- return FACE_ptr;
- }
-
- // No match found
- return NULL;
-}
-
-FACE *
-AcisTweakTool::find_corresponding_FACE( AcisBridge *ab_ptr, BODY *BODY_ptr)
-{
- int i;
- FACE *FACE_ptr;
-
- DLIList<FACE*> FACE_list;
- AcisQueryEngine::instance()->get_FACEs( BODY_ptr, FACE_list );
-
- FACE_list.reset();
- for( i=FACE_list.size(); i--; )
- {
- FACE_ptr = FACE_list.get_and_step();
- if( ATTRIB_CUBIT_OWNER::cubit_owner( FACE_ptr ) == ab_ptr )
- return FACE_ptr;
- }
-
- return NULL;
-}
-
-LOOP *
-AcisTweakTool::find_corresponding_LOOP( AcisBridge *ab_ptr, BODY *BODY_ptr)
-{
- int i;
- LOOP *LOOP_ptr;
-
- DLIList<LOOP*> LOOP_list;
- AcisQueryEngine::instance()->get_LOOPs( BODY_ptr, LOOP_list );
-
- LOOP_list.reset();
- for( i=LOOP_list.size(); i--; )
- {
- LOOP_ptr = LOOP_list.get_and_step();
- if( ATTRIB_CUBIT_OWNER::cubit_owner( LOOP_ptr ) == ab_ptr )
- return LOOP_ptr;
- }
-
- return NULL;
-}
-
-CubitStatus
-AcisTweakTool::get_owner_list( DLIList<EDGE*> &EDGE_list,
- DLIList<AcisBridge*> &owner_list )
-{
- int i;
- EDGE *EDGE_ptr;
-
- EDGE_list.reset();
- for( i=EDGE_list.size(); i--; )
- {
- EDGE_ptr = EDGE_list.get_and_step();
- owner_list.append_unique( ATTRIB_CUBIT_OWNER::cubit_owner( EDGE_ptr ) );
- }
-
- return CUBIT_SUCCESS;
-}
-
-CubitStatus
-AcisTweakTool::get_owner_list( DLIList<FACE*> &FACE_list,
- DLIList<AcisBridge*> &owner_list )
-{
- int i;
- FACE *FACE_ptr;
-
- FACE_list.reset();
- for( i=FACE_list.size(); i--; )
- {
- FACE_ptr = FACE_list.get_and_step();
- owner_list.append_unique( ATTRIB_CUBIT_OWNER::cubit_owner( FACE_ptr ) );
- }
-
- return CUBIT_SUCCESS;
-}
-
-CubitStatus
-AcisTweakTool::get_owner_list( DLIList<LOOP*> &LOOP_list,
- DLIList<AcisBridge*> &owner_list )
-{
- int i;
- LOOP *LOOP_ptr;
-
- LOOP_list.reset();
- for( i=LOOP_list.size(); i--; )
- {
- LOOP_ptr = LOOP_list.get_and_step();
- owner_list.append_unique( ATTRIB_CUBIT_OWNER::cubit_owner( LOOP_ptr ) );
- }
-
- return CUBIT_SUCCESS;
-}
-
-CubitStatus
-AcisTweakTool::get_corresponding_FACE_list( DLIList<AcisBridge*> &owner_list,
- BODY *BODY_ptr,
- DLIList<FACE*> &corresponding_FACE_list )
-{
- int i;
- AcisBridge *ab_ptr;
-
- owner_list.reset();
- for( i=owner_list.size(); i--; )
- {
- ab_ptr = owner_list.get_and_step();
- corresponding_FACE_list.append( find_corresponding_FACE( ab_ptr, BODY_ptr ) );
- }
-
- return CUBIT_SUCCESS;
-}
-
-CubitStatus
-AcisTweakTool::get_corresponding_LOOP_list( DLIList<AcisBridge*> &owner_list,
- BODY *BODY_ptr,
- DLIList<LOOP*> &corresponding_LOOP_list )
-{
- int i;
- AcisBridge *ab_ptr;
-
- owner_list.reset();
- for( i=owner_list.size(); i--; )
- {
- ab_ptr = owner_list.get_and_step();
- corresponding_LOOP_list.append( find_corresponding_LOOP( ab_ptr, BODY_ptr ) );
- }
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : get_thickened_BODIES_of_EDGES
-// Member Type: PRIVATE
-// Description: Get thickened BODIES from an input list of EDGEs. This
-// function can be called multiple times on the same list of EDGEs
-// - each time, the EDGEs from the common body that is thickened
-// are removed from the input EDGE list. The thickened BODIES are
-// copied from the sheet the EDGEs are attached to (multiple
-// BODIES can be returned because the returned thickened BODIES
-// must be nonmanifold). For each BODY returned, also output a
-// list of EDGES (corresponding to the original input EDGEs), a
-// list of FACEs(corresponding to the original FACEs of the input
-// BODY) and a list of conjugate FACEs (the "side" FACEs of the
-// thickened BODY - these are the FACEs we can tweak).
-// Author : Steve Storm
-// Date : 03/01/05
-//=============================================================================
-CubitStatus
-AcisTweakTool::get_thickened_BODIES_of_EDGES( const char *command_name,
- DLIList<EDGE*> &input_EDGE_list,
- DLIList<EDGE*> &removed_EDGE_list,
- BODY *&common_BODY_ptr,
- DLIList<BODY*> &thickened_BODY_list,
- DLIList<DLIList<EDGE*>*> &output_EDGE_lists,
- DLIList<DLIList<FACE*>*> &output_FACE_lists,
- DLIList<DLIList<FACE*>*> &conjugate_FACE_lists,
- double thickness )
-{
- assert( thickened_BODY_list.size() == 0 );
-
- int i, j;
-
- EDGE *EDGE_ptr;
- FACE *FACE_ptr;
- BODY *BODY_ptr;
- outcome result;
-
- // Pull EDGEs out of the input EDGE list that are from a common BODY
- input_EDGE_list.reset();
- common_BODY_ptr = NULL;
- for( i=input_EDGE_list.size(); i--; )
- {
- EDGE_ptr = input_EDGE_list.get();
-
- BODY_ptr = AQE->get_BODY_of_ENTITY( EDGE_ptr );
-
- if( common_BODY_ptr == NULL )
- common_BODY_ptr = BODY_ptr;
-
- if( common_BODY_ptr == BODY_ptr )
- {
- removed_EDGE_list.append( EDGE_ptr );
- input_EDGE_list.change_to( NULL );
- }
-
- input_EDGE_list.step();
- }
- input_EDGE_list.remove_all_with_value( NULL );
-
- // Get all FACEs attached to the EDGEs
- DLIList<FACE*> attached_FACE_list;
- removed_EDGE_list.reset();
- for( i=removed_EDGE_list.size(); i--; )
- {
- EDGE_ptr = removed_EDGE_list.get_and_step();
- DLIList<FACE*> tmp_FACE_list;
- AQE->get_FACEs( EDGE_ptr, tmp_FACE_list );
-
- if( tmp_FACE_list.size() == 0 )
- {
- PRINT_ERROR( "Cannot %s curves that are free\n",
- command_name );
- return CUBIT_FAILURE;
- }
-
- if( tmp_FACE_list.size() != 1 )
- {
- PRINT_ERROR( "Can only %s curves attached to one surface\n",
- command_name );
- return CUBIT_FAILURE;
- }
-
- attached_FACE_list.append( tmp_FACE_list.get() );
- }
-
- // Make sure that all of the FACEs are on a sheet body
- for( i=attached_FACE_list.size(); i--; )
- {
- FACE_ptr = attached_FACE_list.get_and_step();
- if( FACE_ptr->sides() != DOUBLE_SIDED )
- {
- PRINT_ERROR("Cannot %s curves that are not on sheet bodies\n",
- command_name );
- return CUBIT_FAILURE;
- }
- }
-
- // Copy these FACEs off into a new body
- // Copy the BODY
- BODY *copied_BODY_ptr;
- if( copy_FACES_from_BODY( attached_FACE_list, copied_BODY_ptr ) == CUBIT_FAILURE )
+ PRINT_ERROR("This feature is not implemented.\n");
return CUBIT_FAILURE;
-
- // Make the BODY nonmanifold, as thicken can't handle manifold bodies. Note
- // the api_unstitch_nonmani api will remove the cubit owner from the resultant
- // BODY, LUMP and SHELL - we manually put them back on, for proper updating
- // of the Cubit entities (luckily it leaves them on the FACEs, CURVEs, etc..
- // Also note the api destroys the input BODY.
- AcisBridge *ab_body_ptr;
- AcisBridge *ab_lump_ptr;
- AcisBridge *ab_shell_ptr;
- get_owner_attribs( copied_BODY_ptr, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
-
- BODY* lumps = NULL;
- BODY* sheets = NULL;
- BODY* lamina = NULL;
- BODY* wires = NULL;
- result = api_unstitch_nonmani( copied_BODY_ptr, lumps, sheets, lamina, wires );
- if (!result.ok())
- {
- AQE->ACIS_API_error(result);
- AQE->delete_ACIS_BODY( copied_BODY_ptr,CUBIT_TRUE );
- return CUBIT_FAILURE;
- }
-
- // Make sure cubit owner attributes remain on resultant BODY, LUMP, SHELL
- reset_owner_attribs( sheets, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
-
- // Separate bodies (thicken won't work if more than one vol per body)
- BODY **separated_BODY_array = NULL;
- int n_body = 0;
-
- // Note first BODY will always be the input BODY
- result = api_separate_body( sheets, n_body, separated_BODY_array );
-
- if (!result.ok())
- {
- AQE->ACIS_API_error(result);
- AQE->delete_ACIS_BODY( sheets, CUBIT_TRUE );
- return CUBIT_FAILURE;
- }
-
- // These BODIES can now be thickened
- for( i=0; i<n_body; i++ )
- thickened_BODY_list.append(separated_BODY_array[i]);
-
- // Loop on separated BODIES
- thickened_BODY_list.reset();
- for( i=thickened_BODY_list.size(); i--; )
- {
- BODY_ptr = thickened_BODY_list.get_and_step();
-
- // Make sure cubit owner attributes remain on resultant BODY, LUMP, SHELL
- reset_owner_attribs( BODY_ptr, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
-
- // The FACEs in this BODY can efficiently be added to the output list here
- DLIList<FACE*> *FACE_list_ptr = new DLIList<FACE*>;
- output_FACE_lists.append( FACE_list_ptr );
- AQE->get_FACEs( BODY_ptr, *FACE_list_ptr );
-
- // Thicken the BODY
- if( thicken_BODY( BODY_ptr, thickness ) == CUBIT_FAILURE )
- {
- // Delete all BODIEs, since we failed
- while( thickened_BODY_list.size() )
- AQE->delete_ACIS_BODY(thickened_BODY_list.pop(),CUBIT_TRUE);
- // Clean up memory allocated for the output lists
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( conjugate_FACE_lists.size() ) delete conjugate_FACE_lists.pop();
- return CUBIT_FAILURE;
- }
-
- // Make sure cubit owner attributes remain on resultant BODY, LUMP, SHELL
- reset_owner_attribs( BODY_ptr, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
-
- // Now find EDGEs and conjugate FACEs for the thickened BODY
- DLIList<EDGE*> *EDGE_list_ptr = new DLIList<EDGE*>;
- output_EDGE_lists.append( EDGE_list_ptr );
-
- DLIList<EDGE*> tmp_EDGE_list;
- AQE->get_EDGEs( BODY_ptr, tmp_EDGE_list );
- EDGE *tmp_EDGE_ptr;
- for( j=removed_EDGE_list.size(); j--; )
- {
- EDGE_ptr = removed_EDGE_list.get_and_step();
-
- tmp_EDGE_ptr = find_corresponding_EDGE( EDGE_ptr, tmp_EDGE_list );
- if( tmp_EDGE_ptr )
- EDGE_list_ptr->append( tmp_EDGE_ptr );
- }
-
- if( !EDGE_list_ptr->size() )
- {
- PRINT_ERROR( "Internal error - please report.\n" );
- // Delete all BODIEs, since we failed
- while( thickened_BODY_list.size() )
- AQE->delete_ACIS_BODY(thickened_BODY_list.pop(),CUBIT_TRUE);
- // Clean up memory allocated for the output lists
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( conjugate_FACE_lists.size() ) delete conjugate_FACE_lists.pop();
- return CUBIT_FAILURE;
- }
-
- // Find the "conjugate" FACEs (the FACEs that will be tweaked or removed
- // by the calling function). These are the FACEs that adjoin the original
- // FACEs - they will be attached to the input EDGEs and won't exist in the
- // FACE_list_ptr.
-
- DLIList<FACE*> *conjugate_FACE_list_ptr = new DLIList<FACE*>;
- conjugate_FACE_lists.append( conjugate_FACE_list_ptr );
-
- EDGE_list_ptr->reset();
- for( j=EDGE_list_ptr->size(); j--; )
- {
- EDGE_ptr = EDGE_list_ptr->get_and_step();
-
- DLIList<FACE*> tmp_FACE_list;
- AQE->get_FACEs( EDGE_ptr, tmp_FACE_list );
-
- if( tmp_FACE_list.size() != 2 )
- {
- PRINT_ERROR( "Unexpected topology during %s curve function\n", command_name );
- // Delete all BODIEs, since we failed
- while( thickened_BODY_list.size() )
- AQE->delete_ACIS_BODY(thickened_BODY_list.pop(),CUBIT_TRUE);
- // Clean up memory allocated for the output lists
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( conjugate_FACE_lists.size() ) delete conjugate_FACE_lists.pop();
- return CUBIT_FAILURE;
- }
-
- FACE *FACE_ptr1 = tmp_FACE_list.get_and_step();
- FACE *FACE_ptr2 = tmp_FACE_list.get();
-
- if( FACE_list_ptr->is_in_list( FACE_ptr1 ) )
- conjugate_FACE_list_ptr->append( FACE_ptr2 );
- else
- conjugate_FACE_list_ptr->append( FACE_ptr1 );
- }
- }
-
- return CUBIT_SUCCESS;
}
-//=============================================================================
-// Function : get_thickened_BODIES_of_VERTICES
-// Member Type: PRIVATE
-// Description: Get thickened BODIES from an input list of VERTICEs. This
-// function can be called multiple times on the same list of
-// VERTICEs - each time, the VERTICEs from the common body that is
-// thickened are removed from the input EDGE list. These
-// thickened BODIES are copied from the sheets the VERTICEs are
-// attached to (multiple BODIES can be returned because the
-// thickened BODIES must be nonmanifold). For each BODY returned,
-// also output a list of the FACEs (corresponding to the original
-// FACEs of the sheet body), the VERTICEs (corresponding to the
-// original VERTICEs), and a list of EDGEs created by the
-// thickening process (from sweeping the original VERTEX - note it
-// is possible that no EDGE was created from a VERTEX, in which
-// case a NULL value will exist in the list).
-// Author : Steve Storm
-// Date : 02/10/06
-//=============================================================================
-CubitStatus
-AcisTweakTool::get_thickened_BODIES_of_VERTICES( const char *command_name,
- DLIList<VERTEX*> &input_VERTEX_list,
- BODY *&common_BODY_ptr,
- DLIList<BODY*> &thickened_BODY_list,
- DLIList<DLIList<FACE*>*> &output_FACE_lists,
- DLIList<DLIList<VERTEX*>*> &output_VERTEX_lists,
- DLIList<DLIList<EDGE*>*> &output_EDGE_lists,
- double thickness )
+CubitStatus AcisTweakTool::tweak_remove( DLIList<Curve*> &curve_list,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean keep_old_body /*= CUBIT_FALSE*/,
+ CubitBoolean preview /*= CUBIT_FALSE*/ )
{
- assert( thickened_BODY_list.size() == 0 );
-
- int i, j;
-
- VERTEX *VERTEX_ptr;
- FACE *FACE_ptr;
-
- outcome result;
-
- // Pull VERTICEs out of the input VERTEX list that are from a common BODY
- DLIList<VERTEX*> common_VERTEX_list;
- BODY *BODY_ptr;
- common_BODY_ptr = NULL;
- input_VERTEX_list.reset();
- for( i=input_VERTEX_list.size(); i--; )
- {
- VERTEX_ptr = input_VERTEX_list.get();
- BODY_ptr = AQE->get_BODY_of_ENTITY( VERTEX_ptr );
-
- if( common_BODY_ptr == NULL )
- common_BODY_ptr = BODY_ptr;
-
- if( common_BODY_ptr == BODY_ptr )
- {
- common_VERTEX_list.append( VERTEX_ptr );
- input_VERTEX_list.change_to( NULL );
- }
-
- input_VERTEX_list.step();
- }
- input_VERTEX_list.remove_all_with_value( NULL );
-
- // Get all FACEs attached to the VERTICEs
- DLIList<FACE*> attached_FACE_list;
- common_VERTEX_list.reset();
- for( i=common_VERTEX_list.size(); i--; )
- {
- VERTEX_ptr = common_VERTEX_list.get_and_step();
- DLIList<FACE*> tmp_FACE_list;
- AQE->get_FACEs( VERTEX_ptr, tmp_FACE_list );
-
- if( tmp_FACE_list.size() == 0 )
- {
- PRINT_ERROR( "Cannot %s vertices that are free\n",
- command_name );
- return CUBIT_FAILURE;
- }
-
- if( tmp_FACE_list.size() != 1 )
- {
- PRINT_ERROR( "Can only %s vertices attached to one surface for sheet bodies\n",
- command_name );
- return CUBIT_FAILURE;
- }
-
- attached_FACE_list.append_unique( tmp_FACE_list.get() );
- }
-
- // Make sure that all of the FACEs are on a sheet body
- for( i=attached_FACE_list.size(); i--; )
- {
- FACE_ptr = attached_FACE_list.get_and_step();
- if( FACE_ptr->sides() != DOUBLE_SIDED )
- {
- PRINT_ERROR("Cannot %s vertices that are not on sheet bodies\n",
- command_name );
- return CUBIT_FAILURE;
- }
- }
-
- // Copy these FACEs off into a new body
- // Copy the BODY
- BODY *copied_BODY_ptr;
- if( copy_FACES_from_BODY( attached_FACE_list, copied_BODY_ptr ) == CUBIT_FAILURE )
+ PRINT_ERROR("This feature is not implemented.\n");
return CUBIT_FAILURE;
-
- // Make the BODY nonmanifold, as thicken can't handle manifold bodies. Note
- // the api_unstitch_nonmani api will remove the cubit owner from the resultant
- // BODY, LUMP and SHELL - we manually put them back on, for proper updating
- // of the Cubit entities (luckily it leaves them on the FACEs, CURVEs, etc..
- // Also note the api destroys the input BODY.
- AcisBridge *ab_body_ptr;
- AcisBridge *ab_lump_ptr;
- AcisBridge *ab_shell_ptr;
- get_owner_attribs( copied_BODY_ptr, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
-
- BODY* lumps = NULL;
- BODY* sheets = NULL;
- BODY* lamina = NULL;
- BODY* wires = NULL;
- result = api_unstitch_nonmani( copied_BODY_ptr, lumps, sheets, lamina, wires );
- if (!result.ok())
- {
- AQE->ACIS_API_error(result);
- api_delent( copied_BODY_ptr );
- return CUBIT_FAILURE;
- }
-
- // Make sure cubit owner attributes remain on resultant BODY, LUMP, SHELL
- reset_owner_attribs( sheets, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
-
- // Separate bodies (thicken won't work if more than one vol per body)
- BODY **separated_BODY_array = NULL;
- int n_body = 0;
-
- // Note first BODY will always be the input BODY
- result = api_separate_body( sheets, n_body, separated_BODY_array );
- if (!result.ok())
- {
- AQE->ACIS_API_error(result);
- api_delent( sheets );
- return CUBIT_FAILURE;
- }
-
- // These BODIES can now be thickened
- for( i=0; i<n_body; i++ )
- thickened_BODY_list.append(separated_BODY_array[i]);
-
- // Loop on separated BODIES
- thickened_BODY_list.reset();
- for( i=thickened_BODY_list.size(); i--; )
- {
- BODY_ptr = thickened_BODY_list.get_and_step();
-
- // Make sure cubit owner attributes remain on resultant BODY, LUMP, SHELL
- reset_owner_attribs( BODY_ptr, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
-
- // Keep track of the original EDGEs in the sheet body
- DLIList<EDGE*> original_EDGE_list;
- AQE->get_EDGEs( BODY_ptr, original_EDGE_list );
-
- // The FACEs in this BODY can efficiently be added to the output list here
- DLIList<FACE*> *FACE_list_ptr = new DLIList<FACE*>;
- output_FACE_lists.append( FACE_list_ptr );
- AQE->get_FACEs( BODY_ptr, *FACE_list_ptr );
-
- // Thicken the BODY
- if( thicken_BODY( BODY_ptr, thickness ) == CUBIT_FAILURE )
- {
- // Delete all BODIEs, since we failed
- while( thickened_BODY_list.size() )
- api_delent( thickened_BODY_list.pop() );
- // Clean up memory allocated for the output lists
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( output_VERTEX_lists.size() ) delete output_VERTEX_lists.pop();
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- return CUBIT_FAILURE;
- }
-
- // Make sure cubit owner attributes remain on resultant BODY, LUMP, SHELL
- reset_owner_attribs( BODY_ptr, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
-
- // Now find VERTICEs and output EDGEs for the thickened BODY
- DLIList<VERTEX*> *VERTEX_list_ptr = new DLIList<VERTEX*>;
- output_VERTEX_lists.append( VERTEX_list_ptr );
-
- DLIList<VERTEX*> tmp_VERTEX_list;
- AQE->get_VERTICEs( BODY_ptr, tmp_VERTEX_list );
- VERTEX *tmp_VERTEX_ptr;
- for( j=common_VERTEX_list.size(); j--; )
- {
- VERTEX_ptr = common_VERTEX_list.get_and_step();
-
- tmp_VERTEX_ptr = find_corresponding_VERTEX( VERTEX_ptr, tmp_VERTEX_list );
- if( tmp_VERTEX_ptr )
- VERTEX_list_ptr->append( tmp_VERTEX_ptr );
- }
-
- if( !VERTEX_list_ptr->size() )
- {
- PRINT_ERROR( "Internal error - please report.\n" );
- // Delete all BODIEs, since we failed
- while( thickened_BODY_list.size() )
- api_delent( thickened_BODY_list.pop() );
- // Clean up memory allocated for the output lists
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( output_VERTEX_lists.size() ) delete output_VERTEX_lists.pop();
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- return CUBIT_FAILURE;
- }
-
- // Find the "conjugate" EDGEs (the EDGEs that can be chamfered or filleted
- // by the calling function). These are the EDGEs that were created by
- // the sweeping the VERTICEs during the thicken operation.
-
- DLIList<EDGE*> *EDGE_list_ptr = new DLIList<EDGE*>;
- output_EDGE_lists.append( EDGE_list_ptr );
-
- VERTEX_list_ptr->reset();
- for( j=VERTEX_list_ptr->size(); j--; )
- {
- VERTEX_ptr = VERTEX_list_ptr->get_and_step();
-
- DLIList<EDGE*> tmp_EDGE_list;
- AQE->get_EDGEs( VERTEX_ptr, tmp_EDGE_list );
-
- int k;
- EDGE *tmp_EDGE_ptr;
- int found = 0;
- for( k=tmp_EDGE_list.size(); k--; )
- {
- tmp_EDGE_ptr = tmp_EDGE_list.get_and_step();
- if( !original_EDGE_list.is_in_list( tmp_EDGE_ptr ) )
- {
- EDGE_list_ptr->append( tmp_EDGE_ptr );
- found = 1;
- break;
- }
- }
- if( !found )
- EDGE_list_ptr->append( NULL );
- }
- }
-
- return CUBIT_SUCCESS;
}
-CubitStatus
-AcisTweakTool::prep_for_surface_swap( BODY *thickened_BODY_ptr,
- BODY *copied_BODY_ptr,
- DLIList<AcisBridge*> &owner_FACE_list )
+CubitStatus AcisTweakTool::tweak_target( DLIList<Surface*> &surface_list,
+ DLIList<Surface*> &target_surf_list,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean extend_flg /*= CUBIT_TRUE*/,
+ CubitPlane *limit_plane /*= NULL*/,
+ CubitBoolean reverse_flg /*= CUBIT_FALSE*/,
+ CubitBoolean keep_old_body /*= CUBIT_FALSE*/,
+ CubitBoolean preview /*= CUBIT_FALSE*/ )
{
- // Pull original FACEs off and replace with extended FACEs
-
- // Remove all but the extended FACEs from thickened_BODY_ptr
- DLIList<FACE*> tweaked_FACE_list;
- get_corresponding_FACE_list( owner_FACE_list, thickened_BODY_ptr, tweaked_FACE_list );
- if( remove_FACES_from_BODY_except( thickened_BODY_ptr, tweaked_FACE_list )
- == CUBIT_FAILURE )
- {
+ PRINT_ERROR("This feature is not implemented.\n");
return CUBIT_FAILURE;
- }
-
- // Now remove the extended surfaces from the copied_input_BODY_ptr,
- // to be replaced by the output_FACE_list_ptr
- tweaked_FACE_list.clean_out();
- get_corresponding_FACE_list( owner_FACE_list, copied_BODY_ptr, tweaked_FACE_list );
- if( remove_FACES_from_BODY( copied_BODY_ptr, tweaked_FACE_list )
- == CUBIT_FAILURE )
- return CUBIT_FAILURE;
-
- return CUBIT_SUCCESS;
}
-CubitStatus
-AcisTweakTool::unite_BODIES( BODY *copied_input_BODY_ptr,
- DLIList<BODY*> &thickened_BODY_list,
- BODY *&master )
+CubitStatus AcisTweakTool::tweak_target( DLIList<Curve*> &curve_list,
+ DLIList<Surface*> &target_surf_list,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean extend_flg /*= CUBIT_TRUE*/,
+ CubitPlane *limit_plane /*= NULL*/,
+ CubitBoolean reverse_flg /*= CUBIT_FALSE*/,
+ CubitBoolean keep_old_body /*= CUBIT_FALSE*/,
+ CubitBoolean preview /*= CUBIT_FALSE*/,
+ double max_area_increase /*= 0*/ )
{
- int i;
-
- // Unite the thickened BODIEs back into the copied_input_BODY_ptr
- outcome result;
- thickened_BODY_list.reset();
- BODY *BODY_ptr;
- master = copied_input_BODY_ptr;
- for( i=thickened_BODY_list.size(); i--; )
- {
- BODY_ptr = thickened_BODY_list.get();
-
- // Do the union of the master and the BODY_ptr.
- // If this is successful, the result is master and
- // BODY_ptr will be deleted
- result = api_boolean( BODY_ptr, master, NONREG_UNION );
- if( !result.ok() || (!master) )
- {
- AQE->ACIS_API_error(result);
- while( thickened_BODY_list.size() )
- AQE->delete_ACIS_BODY(thickened_BODY_list.pop(),CUBIT_TRUE);
- if (master != NULL) AQE->delete_ACIS_BODY(master,CUBIT_TRUE);
- return CUBIT_FAILURE;
- }
-
- thickened_BODY_list.remove();
- }
-
- return CUBIT_SUCCESS;
-}
-
-CubitStatus
-AcisTweakTool::get_owner_attribs( BODY *BODY_ptr, AcisBridge *&ab_body_ptr,
- AcisBridge *&ab_lump_ptr, AcisBridge *&ab_shell_ptr)
-{
- ab_body_ptr = ATTRIB_CUBIT_OWNER::cubit_owner( BODY_ptr );
-
- ENTITY_LIST lump_list;
- api_get_lumps( BODY_ptr, lump_list);
- ab_lump_ptr = NULL;
- if( lump_list.count() == 1 )
- ab_lump_ptr = ATTRIB_CUBIT_OWNER::cubit_owner( lump_list[0] );
-
- ENTITY_LIST shell_list;
- api_get_shells( BODY_ptr, shell_list);
- ab_shell_ptr = NULL;
- if( shell_list.count() == 1 )
- ab_shell_ptr = ATTRIB_CUBIT_OWNER::cubit_owner( shell_list[0] );
-
- return CUBIT_SUCCESS;
-}
-
-CubitStatus
-AcisTweakTool::reset_owner_attribs( BODY *BODY_ptr,
- AcisBridge *ab_body_ptr,
- AcisBridge *ab_lump_ptr,
- AcisBridge *ab_shell_ptr)
-{
- // Check BODY
- if( !ATTRIB_CUBIT_OWNER::cubit_owner(BODY_ptr) )
- {
- if( ab_body_ptr )
- ATTRIB_CUBIT_OWNER::set_cubit_owner( BODY_ptr, ab_body_ptr );
- }
-
- // Check LUMP
- ENTITY_LIST lump_list;
- api_get_lumps( BODY_ptr, lump_list);
- if( lump_list.count() == 1 )
- {
- if( !ATTRIB_CUBIT_OWNER::cubit_owner(lump_list[0]) )
- {
- if( ab_lump_ptr )
- ATTRIB_CUBIT_OWNER::set_cubit_owner( lump_list[0], ab_lump_ptr );
- }
- }
-
- // Check SHELL
- ENTITY_LIST shell_list;
- api_get_shells( BODY_ptr, shell_list);
- if( shell_list.count() == 1 )
- {
- if( !ATTRIB_CUBIT_OWNER::cubit_owner(shell_list[0]) )
- {
- if( ab_shell_ptr )
- ATTRIB_CUBIT_OWNER::set_cubit_owner( shell_list[0], ab_shell_ptr );
- }
- }
-
- return CUBIT_SUCCESS;
-}
-
-CubitStatus
-AcisTweakTool::sort_points_by_body_type( DLIList<Point*> &point_list,
- DLIList<Point*> &solid_points,
- DLIList<Point*> &sheet_points )
-{
- int i, j;
- Point *point_ptr;
- PointACIS *point_acis_ptr;
- VERTEX *VERTEX_ptr;
- FACE *FACE_ptr;
- CubitBoolean sheet_face, solid_face;
- point_list.reset();
- for( i=point_list.size(); i--; )
- {
- point_ptr = point_list.get_and_step();
-
- point_acis_ptr = dynamic_cast<PointACIS*>(point_ptr);
- if( point_acis_ptr == NULL )
- {
- PRINT_ERROR( "Non-ACIS point encountered.\n" );
- return CUBIT_FAILURE;
- }
-
- VERTEX_ptr = point_acis_ptr->get_VERTEX_ptr();
-
- // Retrieve FACEs attached to this VERTEX
- DLIList<FACE*> FACE_list;
- AcisQueryEngine::instance()->get_FACEs( (ENTITY*)VERTEX_ptr, FACE_list );
-
- if( FACE_list.size() == 0 )
- {
- PRINT_ERROR( "Vertex found not attached to any surfaces.\n" );
- return CUBIT_FAILURE;
- }
-
- // Check all FACEs
- sheet_face = CUBIT_FALSE;
- solid_face = CUBIT_FALSE;
-
- for( j=FACE_list.size(); j--; )
- {
- FACE_ptr = FACE_list.get_and_step();
-
- if( FACE_ptr->sides() == DOUBLE_SIDED )
- sheet_face = CUBIT_TRUE;
- else
- solid_face = CUBIT_TRUE;
- }
-
- // Error if attached to both solid and sheet
- if( sheet_face == CUBIT_TRUE && solid_face == CUBIT_TRUE )
- {
- PRINT_ERROR( "Encountered vertex attached to both a sheet and a solid.\n" );
- return CUBIT_FAILURE;
- }
-
- if( sheet_face == CUBIT_TRUE )
- sheet_points.append( point_ptr );
- else
- solid_points.append( point_ptr );
- }
-
- return CUBIT_SUCCESS;
-}
-
-CubitStatus
-AcisTweakTool::tweak_chamfer_solid( DLIList<Point*> &point_list,
- double radius,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean keep_old_body,
- CubitBoolean preview )
-{
- if( point_list.size() == 0 )
- return CUBIT_SUCCESS;
-
- outcome result;
-
- BodySM *body_ptr;
-
- BODY *BODY_ptr;
- BODY *copied_BODY_ptr;
-
- int delete_attribs =
- (GeometryModifyTool::instance()->get_new_ids() || keep_old_body);
-
- // Copy the incoming point_list since we will be pulling points out of it.
- DLIList<PointACIS*> copied_point_list(point_list.size());
- CAST_LIST( point_list, copied_point_list, PointACIS );
- if (point_list.size() != copied_point_list.size())
- {
- PRINT_ERROR("Non-ACIS vertices encountered\n");
+ PRINT_ERROR("This feature is not implemented.\n");
return CUBIT_FAILURE;
- }
-
- copied_point_list.reset();
- while( copied_point_list.size() )
- {
- DLIList<VERTEX*> VERTEX_list;
- if( AME->get_copied_VERTICES_of_body( copied_point_list, VERTEX_list,
- copied_BODY_ptr ) == CUBIT_FAILURE )
- {
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- // Get original Body and BODY
- body_ptr = AQE->get_body_sm_of_ENTITY( copied_BODY_ptr );
- BODY_ptr = dynamic_cast<BodyACIS*>(body_ptr)->get_BODY_ptr();
-
- // Now, blend the edges on this body
- if( chamfer_vertices( VERTEX_list, radius ) == CUBIT_FAILURE )
- {
- api_delent(copied_BODY_ptr);
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- if( !preview )
- {
- // If we've made it this far, the copied_BODY has been
- // modified and we can update it in CUBIT
-
- // Now cleanout the owner attributes from the copied BODY, if required
- if( delete_attribs )
- AQE->remove_cubit_owner_attrib_in_BODY(copied_BODY_ptr);
-
- BodySM* new_body_ptr = AME->get_new_Body( body_ptr, BODY_ptr, copied_BODY_ptr,
- keep_old_body );
-
- if (new_body_ptr)
- new_bodysm_list.append( new_body_ptr );
- }
- else
- {
- GfxPreview::clear();
-
- ENTITY_LIST face_list;
- api_get_faces( copied_BODY_ptr, face_list);
- AcisBridge *ab_face_ptr = NULL;
- int i;
- for( i=0; i<face_list.count(); i++ )
- {
- ab_face_ptr = ATTRIB_CUBIT_OWNER::cubit_owner( face_list[i] );
- if( !ab_face_ptr )
- {
- // Draw this face
- AcisDrawTool::instance()->draw_FACE( (FACE*)face_list[i], CUBIT_BLUE );
- }
- }
-
- api_delent(copied_BODY_ptr);
- }
- }
-
- if( preview )
- GfxPreview::flush();
-
- return CUBIT_SUCCESS;
}
-CubitStatus
-AcisTweakTool::tweak_chamfer_fillet_sheet( DLIList<Point*> &input_point_list,
- double radius,
- int type,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean keep_old_bodies,
- CubitBoolean preview )
+CubitStatus AcisTweakTool::tweak_target( DLIList<Curve*> &curve_list,
+ DLIList<Curve*> &target_curve_list,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean extend_flg /*= CUBIT_TRUE*/,
+ CubitPlane *limit_plane /*= NULL*/,
+ CubitBoolean reverse_flg /*= CUBIT_FALSE*/,
+ CubitBoolean keep_old_body /*= CUBIT_FALSE*/,
+ CubitBoolean preview /*= CUBIT_FALSE*/,
+ double max_area_increase /*= 0*/ )
{
- if( input_point_list.size() == 0 )
- return CUBIT_SUCCESS;
-
- int i, j;
- EDGE *EDGE_ptr;
- outcome result;
-
- bool delete_attribs =
- (GeometryModifyTool::instance()->get_new_ids() || keep_old_bodies);
-
- // Copy the input point list as we will be removing points from it
- DLIList<Point*> copied_input_point_list = input_point_list;
-
- char type_name[8];
- if( type == 1 )
- strcpy( type_name, "chamfer" );
- else
- strcpy( type_name, "fillet" );
-
- // Get VERTICEs to chamfer or fillet
- DLIList<VERTEX*> VERTEX_list;
- if( get_VERTICEs( input_point_list, VERTEX_list ) == CUBIT_FAILURE )
+ PRINT_ERROR("This feature is not implemented.\n");
return CUBIT_FAILURE;
-
- while( VERTEX_list.size() )
- {
- BODY *input_BODY_ptr;
- BodySM *input_bodysm_ptr;
- DLIList<BODY*> thickened_BODY_list;
- DLIList<DLIList<FACE*>*> output_FACE_lists;
- DLIList<DLIList<VERTEX*>*> output_VERTEX_lists;
- DLIList<DLIList<EDGE*>*> output_EDGE_lists;
-
- // Get thickened BODIES of VERTICES from a common BODY
- if( get_thickened_BODIES_of_VERTICES( type_name, VERTEX_list,
- input_BODY_ptr, thickened_BODY_list, output_FACE_lists,
- output_VERTEX_lists, output_EDGE_lists ) == CUBIT_FAILURE )
- {
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- input_bodysm_ptr = AQE->get_body_sm_of_ENTITY( input_BODY_ptr );
-
- // Tweak the surfaces on the output BODIEs, pull the tweaked surfaces off,
- // and replace them in the original BODY
- // First copy the BODY
- BODY *copied_input_BODY_ptr = AME->copy_BODY(input_BODY_ptr, CUBIT_FALSE);
-
- BODY *thickened_BODY_ptr;
- DLIList<FACE*> *output_FACE_list_ptr;
- DLIList<VERTEX*> *output_VERTEX_list_ptr;
- DLIList<EDGE*> *output_EDGE_list_ptr;
- thickened_BODY_list.reset();
- output_FACE_lists.reset();
- output_VERTEX_lists.reset();
- output_EDGE_lists.reset();
- for( i=thickened_BODY_list.size(); i--; )
- {
- thickened_BODY_ptr = thickened_BODY_list.get_and_step();
- output_FACE_list_ptr = output_FACE_lists.get_and_step();
- output_VERTEX_list_ptr = output_VERTEX_lists.get_and_step();
- output_EDGE_list_ptr = output_EDGE_lists.get_and_step();
-
- // Note - the output EDGE list can have NULL entries in it, as thicken
- // doesn't always create a curve on the side of the thickened body at
- // each vertex. If there is a NULL entry, it means that there isn't
- // a discernable topology change in the body there anyway, which means
- // we wouldn't be able to chamfer it anyway. For now just ignore.
-
- // Keep track of the FACEs of interest, via their Cubit owners, which
- // will survive throughout the operation
- DLIList<AcisBridge*> owner_list;
- get_owner_list( *output_FACE_list_ptr, owner_list );
-
- // Error check
- int cnt = 0;
- for( j=output_EDGE_list_ptr->size(); j--; )
- {
- EDGE_ptr = output_EDGE_list_ptr->get_and_step();
- if( EDGE_ptr )
- cnt++;
- }
-
- if( cnt == 0 )
- {
- PRINT_ERROR( "Unable to %s vertices.\n", type_name );
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( output_VERTEX_lists.size() ) delete output_VERTEX_lists.pop();
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( thickened_BODY_list.size() )
- api_delent( thickened_BODY_list.pop() );
- api_delent( copied_input_BODY_ptr );
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- // Now, blend the edges on this thickened body
- CubitStatus status;
- if( type == 1 )
- status = chamfer_edges( *output_EDGE_list_ptr, radius );
- else
- status = blend_edges( *output_EDGE_list_ptr, radius );
-
-
- if( status == CUBIT_FAILURE )
- {
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( output_VERTEX_lists.size() ) delete output_VERTEX_lists.pop();
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( thickened_BODY_list.size() )
- api_delent( thickened_BODY_list.pop() );
- api_delent( copied_input_BODY_ptr );
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- // Get bodies ready to swap new surfaces for old
- if( prep_for_surface_swap( thickened_BODY_ptr, copied_input_BODY_ptr,
- owner_list ) == CUBIT_FAILURE )
- {
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( output_VERTEX_lists.size() ) delete output_VERTEX_lists.pop();
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( thickened_BODY_list.size() )
- api_delent( thickened_BODY_list.pop() );
- api_delent( copied_input_BODY_ptr );
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- } // End loop on thickened (separated) BODIES
-
- // Free memory
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( output_VERTEX_lists.size() ) delete output_VERTEX_lists.pop();
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
-
- // Unite the thickened BODIEs back into the copied_input_BODY_ptr
- BODY *master;
- if( unite_BODIES( copied_input_BODY_ptr, thickened_BODY_list, master ) == CUBIT_FAILURE )
- {
- // If failure, the unite_BODIES function cleaned up the memory
- // Return success if any bodies were created
- return new_bodysm_list.size() ? CUBIT_SUCCESS : CUBIT_FAILURE;
- }
-
- // This BODY is done (whew!)
-
- if( !preview )
- {
- // Now cleanout the owner attributes from the copied BODY, if required
- if( delete_attribs )
- AQE->remove_cubit_owner_attrib_in_BODY(master);
-
- BodySM *new_body = AME->get_new_Body( input_bodysm_ptr, input_BODY_ptr,
- master, keep_old_bodies );
-
- if( new_body )
- new_bodysm_list.append( new_body );
- }
- else
- {
- GfxPreview::clear();
-
- ENTITY_LIST edge_list;
- api_get_edges( master, edge_list );
- AcisBridge *ab_edge_ptr = NULL;
- for( i=0; i<edge_list.count(); i++ )
- {
- ab_edge_ptr = ATTRIB_CUBIT_OWNER::cubit_owner( edge_list[i] );
- if( !ab_edge_ptr )
- {
- // Draw this edge
- AcisDrawTool::instance()->draw_EDGE( (EDGE*)edge_list[i], CUBIT_BLUE );
- }
- }
-
- api_delent(master);
- }
- }
-
- if( preview )
- GfxPreview::flush();
-
- return CUBIT_SUCCESS;
}
-CubitStatus
-AcisTweakTool::tweak_chamfer_solid( Point* point_ptr,
- double r1,
- Curve *c1,
- double r2,
- Curve *c2,
- double r3,
- Curve *c3,
- BodySM *&new_bodysm_ptr,
- CubitBoolean keep_old_body,
- CubitBoolean preview )
+CubitStatus AcisTweakTool::tweak_target( Point *point_ptr,
+ DLIList<Surface*> &modify_surface_list,
+ CubitVector &target_loc,
+ BodySM *&new_bodysm_ptr,
+ CubitBoolean keep_old_body /*= CUBIT_FALSE*/,
+ CubitBoolean preview /*= CUBIT_FALSE*/ )
{
- outcome result;
-
- BodySM *body_ptr;
- BODY *BODY_ptr;
- BODY *copied_BODY_ptr;
-
- int delete_attribs =
- (GeometryModifyTool::instance()->get_new_ids() || keep_old_body);
-
- // Make sure at least curve 1 supplied
- if( c1 == NULL )
- {
- PRINT_ERROR( "Curve not supplied for radius.\n" );
+ PRINT_ERROR("This feature is not implemented.\n");
return CUBIT_FAILURE;
- }
-
- // Check for duplicate input curves. Note c2 and c3 could be NULL, so we
- // don't want to error in that case.
- if( c1==c2 || c1==c3 || (c2 && c2==c3) )
- {
- PRINT_ERROR( "Same curve cannot be specified for multiple radii.\n" );
- return CUBIT_FAILURE;
- }
-
- PointACIS *point_acis_ptr = CAST_TO( point_ptr, PointACIS );
- if( point_acis_ptr == NULL )
- {
- PRINT_ERROR( "Non-ACIS vertex encountered.\n" );
- return CUBIT_FAILURE;
- }
-
- DLIList<PointACIS*> copied_point_list(1);
- copied_point_list.append( point_acis_ptr );
-
- DLIList<VERTEX*> VERTEX_list;
- if( AME->get_copied_VERTICES_of_body( copied_point_list, VERTEX_list,
- copied_BODY_ptr ) == CUBIT_FAILURE )
- {
- return CUBIT_FAILURE;
- }
-
- // Get original Body and BODY
- body_ptr = AQE->get_body_sm_of_ENTITY( copied_BODY_ptr );
- BODY_ptr = dynamic_cast<BodyACIS*>(body_ptr)->get_BODY_ptr();
-
- if( VERTEX_list.size() != 1 )
- {
- PRINT_ERROR( "internal error - please report.\n" );
- api_delent(copied_BODY_ptr);
- return CUBIT_FAILURE;
- }
-
- VERTEX *VERTEX_ptr = VERTEX_list.get();
-
- // Get EDGEs attached to this vertex
- DLIList<EDGE*> EDGE_list;
- AQE->get_EDGEs( VERTEX_ptr, EDGE_list );
- if( EDGE_list.size() != 3 )
- {
- PRINT_ERROR( "found more than 3 curves attached to vertex.\n" );
- api_delent(copied_BODY_ptr);
- return CUBIT_FAILURE;
- }
-
- EDGE *ref_EDGE_ptr, *EDGE_ptr1, *EDGE_ptr2, *EDGE_ptr3;
- CurveACIS *curve_acis_ptr = CAST_TO( c1, CurveACIS );
- ref_EDGE_ptr = curve_acis_ptr->get_EDGE_ptr();
- EDGE_ptr1 = find_corresponding_EDGE( ref_EDGE_ptr, EDGE_list );
- if( EDGE_ptr1 == NULL )
- {
- PRINT_ERROR( "Supplied curve not found in volume.\n" );
- api_delent(copied_BODY_ptr);
- return CUBIT_FAILURE;
- }
-
- if( EDGE_list.move_to( EDGE_ptr1 ) == CUBIT_FALSE )
- {
- PRINT_ERROR( "First supplied curve not attached to vertex.\n" );
- api_delent(copied_BODY_ptr);
- return CUBIT_FAILURE;
- }
-
- // Remove this EDGE from the list
- EDGE_list.remove();
-
- // Handle cases where not all curves or radii were supplied
- if( c2 )
- {
- curve_acis_ptr = CAST_TO( c2, CurveACIS );
- ref_EDGE_ptr = curve_acis_ptr->get_EDGE_ptr();
- EDGE_ptr2 = find_corresponding_EDGE( ref_EDGE_ptr, EDGE_list );
- if( EDGE_ptr2 == NULL )
- {
- PRINT_ERROR( "Supplied curve not found in volume.\n" );
- api_delent(copied_BODY_ptr);
- return CUBIT_FAILURE;
- }
-
- if( EDGE_list.move_to( EDGE_ptr2 ) == CUBIT_FALSE )
- {
- PRINT_ERROR( "Second supplied curve not attached to vertex.\n" );
- api_delent(copied_BODY_ptr);
- return CUBIT_FAILURE;
- }
-
- EDGE_list.remove();
-
- if( c3 )
- {
- curve_acis_ptr = CAST_TO( c3, CurveACIS );
- ref_EDGE_ptr = curve_acis_ptr->get_EDGE_ptr();
- EDGE_ptr3 = find_corresponding_EDGE( ref_EDGE_ptr, EDGE_list );
- if( EDGE_ptr3 == NULL )
- {
- PRINT_ERROR( "Supplied curve not found in volume.\n" );
- api_delent(copied_BODY_ptr);
- return CUBIT_FAILURE;
- }
-
- if( EDGE_list.move_to( EDGE_ptr3 ) == CUBIT_FALSE )
- {
- PRINT_ERROR( "Third supplied curve not attached to vertex.\n" );
- api_delent(copied_BODY_ptr);
- return CUBIT_FAILURE;
- }
- }
- else
- EDGE_ptr3 = EDGE_list.get();
- }
- else
- {
- // Random results for the user - ok
- EDGE_ptr2 = EDGE_list.get_and_step();
- EDGE_ptr3 = EDGE_list.get();
- }
-
- if( r2 <= 0.0 )
- r2 = r1;
- if( r3 <= 0.0 )
- r3 = r2;
-
- // Setup tweak attributes so we can preserve Cubit owners
- DLIList<FACE*> pre_FACE_list;
- DLIList<EDGE*> pre_EDGE_list;
- DLIList<VERTEX*> pre_VERTEX_list;
- DLIList<AcisBridge*> ab_FACE_list, ab_EDGE_list, ab_VERTEX_list;
- assign_tweak_attribs( copied_BODY_ptr, "tweak", pre_FACE_list, ab_FACE_list,
- pre_EDGE_list, ab_EDGE_list, pre_VERTEX_list, ab_VERTEX_list );
-
- // Now, blend the edges on this body
- result = api_chamfer_vertex( VERTEX_ptr, r1, EDGE_ptr1, r2, EDGE_ptr2, r3,
- EDGE_ptr3 );
-
- if( !result.ok() )
- {
- AQE->ACIS_API_error(result);
- api_delent(copied_BODY_ptr);
- return CUBIT_FAILURE;
- }
-
- // Replace Cubit owners
- reassign_cubit_owners_from_tweak_attribs( copied_BODY_ptr, "tweak",
- pre_FACE_list, ab_FACE_list, pre_EDGE_list, ab_EDGE_list, pre_VERTEX_list,
- ab_VERTEX_list );
-
- // Remove tweak attributes
- remove_named_attribs( copied_BODY_ptr, "tweak" );
-
- if( !preview )
- {
-
- // If we've made it this far, the copied_BODY has been
- // modified and we can update it in CUBIT
-
- // Now cleanout the owner attributes from the copied BODY, if required
- if( delete_attribs )
- AQE->remove_cubit_owner_attrib_in_BODY(copied_BODY_ptr);
-
- new_bodysm_ptr = AME->get_new_Body( body_ptr, BODY_ptr, copied_BODY_ptr,
- keep_old_body );
- }
- else
- {
- GfxPreview::clear();
-
- ENTITY_LIST face_list;
- api_get_faces( copied_BODY_ptr, face_list );
- AcisBridge *ab_face_ptr = NULL;
- int i;
- for( i=0; i<face_list.count(); i++ )
- {
- ab_face_ptr = ATTRIB_CUBIT_OWNER::cubit_owner( face_list[i] );
- if( !ab_face_ptr )
- {
- // Draw this face
- AcisDrawTool::instance()->draw_FACE( (FACE*)face_list[i], CUBIT_BLUE );
- }
- }
-
- api_delent(copied_BODY_ptr);
-
- GfxPreview::flush();
- }
-
- return CUBIT_SUCCESS;
}
-CubitStatus
-AcisTweakTool::tweak_chamfer_sheet( Point* point_ptr,
- double r1,
- Curve *c1,
- double r2,
- Curve *c2,
- BodySM *&new_bodysm_ptr,
- CubitBoolean keep_old_body,
- CubitBoolean preview )
+CubitStatus AcisTweakTool::make_extended_sheet( DLIList<FACE*> &FACE_list,
+ BODY *&ext_BODY_ptr,
+ CubitBox *clip_box_ptr /*= NULL*/,
+ bool suppress_errors /*= false*/)
{
- int i, j;
- outcome result;
- EDGE *EDGE_ptr;
-
- int delete_attribs =
- (GeometryModifyTool::instance()->get_new_ids() || keep_old_body);
-
- // Make sure at least curve 1 supplied
- if( c1 == NULL )
- {
- PRINT_ERROR( "Curve not supplied for radius.\n" );
+ PRINT_ERROR("This feature is not implemented.\n");
return CUBIT_FAILURE;
- }
-
- // Check for duplicate input curves. Note c2 and c3 could be NULL, so we
- // don't want to error in that case.
- if( c1==c2 )
- {
- PRINT_ERROR( "Same curve cannot be specified for both radii.\n" );
- return CUBIT_FAILURE;
- }
-
- VERTEX *VERTEX_ptr = AQE->get_VERTEX( point_ptr );
- if( !VERTEX_ptr )
- {
- PRINT_ERROR( "Chamfer vertex must be an ACIS vertex.\n" );
- return CUBIT_FAILURE;
- }
-
- DLIList<VERTEX*> copied_input_VERTEX_list(1);
- copied_input_VERTEX_list.append( VERTEX_ptr );
-
- BodySM *input_bodysm_ptr;
- BODY *input_BODY_ptr;
- DLIList<BODY*> thickened_BODY_list;
- DLIList<DLIList<FACE*>*> output_FACE_lists;
- DLIList<DLIList<VERTEX*>*> output_VERTEX_lists;
- DLIList<DLIList<EDGE*>*> output_EDGE_lists;
- if( get_thickened_BODIES_of_VERTICES( "chamfer", copied_input_VERTEX_list,
- input_BODY_ptr, thickened_BODY_list, output_FACE_lists,
- output_VERTEX_lists, output_EDGE_lists ) == CUBIT_FAILURE )
- {
- return CUBIT_FAILURE;
- }
-
- input_bodysm_ptr = AQE->get_body_sm_of_ENTITY( input_BODY_ptr );
-
- // Tweak the surfaces on the output BODIEs, pull the tweaked surfaces off,
- // and replace them in the original BODY
- // First copy the BODY
- BODY *copied_input_BODY_ptr = AME->copy_BODY(input_BODY_ptr, CUBIT_FALSE);
-
- BODY *thickened_BODY_ptr;
- DLIList<FACE*> *output_FACE_list_ptr;
- DLIList<VERTEX*> *output_VERTEX_list_ptr;
- DLIList<EDGE*> *output_EDGE_list_ptr;
- thickened_BODY_list.reset();
- output_FACE_lists.reset();
- output_VERTEX_lists.reset();
- output_EDGE_lists.reset();
- for( i=thickened_BODY_list.size(); i--; )
- {
- thickened_BODY_ptr = thickened_BODY_list.get_and_step();
- output_FACE_list_ptr = output_FACE_lists.get_and_step();
- output_VERTEX_list_ptr = output_VERTEX_lists.get_and_step();
- output_EDGE_list_ptr = output_EDGE_lists.get_and_step();
-
- // Note - the output EDGE list can have NULL entries in it, as thicken
- // doesn't always create a curve on the side of the thickened body at
- // each vertex. If there is a NULL entry, it means that there isn't
- // a discernable topology change in the body there anyway, which means
- // we wouldn't be able to chamfer it anyway. For now just ignore.
-
- // Keep track of the FACEs of interest, via their Cubit owners, which
- // will survive throughout the operation
- DLIList<AcisBridge*> owner_list;
- get_owner_list( *output_FACE_list_ptr, owner_list );
-
- // Error check
- int cnt = 0;
- for( j=output_EDGE_list_ptr->size(); j--; )
- {
- EDGE_ptr = output_EDGE_list_ptr->get_and_step();
- if( EDGE_ptr )
- cnt++;
- }
-
- if( cnt == 0 )
- {
- PRINT_ERROR( "Unable to chamfer the vertex.\n" );
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( output_VERTEX_lists.size() ) delete output_VERTEX_lists.pop();
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( thickened_BODY_list.size() )
- api_delent( thickened_BODY_list.pop() );
- api_delent( copied_input_BODY_ptr );
- return CUBIT_FAILURE;
- }
-
- // Check supplied curves
- VERTEX *ref_VERTEX_ptr = output_VERTEX_list_ptr->get();
- EDGE *conj_EDGE_ptr = output_EDGE_list_ptr->get();
-
- // Get EDGEs attached to this vertex
- DLIList<EDGE*> EDGE_list;
- AQE->get_EDGEs( ref_VERTEX_ptr, EDGE_list );
- if( EDGE_list.size() != 3 )
- {
- PRINT_ERROR( "found too many curves attached to vertex.\n" );
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( output_VERTEX_lists.size() ) delete output_VERTEX_lists.pop();
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( thickened_BODY_list.size() )
- api_delent( thickened_BODY_list.pop() );
- api_delent( copied_input_BODY_ptr );
- return CUBIT_FAILURE;
- }
-
- EDGE *ref_EDGE_ptr, *EDGE_ptr1, *EDGE_ptr2;
- CurveACIS *curve_acis_ptr = CAST_TO( c1, CurveACIS );
- ref_EDGE_ptr = curve_acis_ptr->get_EDGE_ptr();
- EDGE_ptr1 = find_corresponding_EDGE( ref_EDGE_ptr, EDGE_list );
- if( EDGE_ptr1 == NULL )
- {
- PRINT_ERROR( "Supplied curve not found in volume.\n" );
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( output_VERTEX_lists.size() ) delete output_VERTEX_lists.pop();
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( thickened_BODY_list.size() )
- api_delent( thickened_BODY_list.pop() );
- api_delent( copied_input_BODY_ptr );
- return CUBIT_FAILURE;
- }
-
- if( EDGE_list.move_to( EDGE_ptr1 ) == CUBIT_FALSE )
- {
- PRINT_ERROR( "First curve not attached to vertex.\n" );
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( output_VERTEX_lists.size() ) delete output_VERTEX_lists.pop();
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( thickened_BODY_list.size() )
- api_delent( thickened_BODY_list.pop() );
- api_delent( copied_input_BODY_ptr );
- return CUBIT_FAILURE;
- }
-
- // Remove this EDGE from the list
- EDGE_list.remove();
-
- // Handle cases where not all curves or radii were supplied
- if( c2 )
- {
- curve_acis_ptr = CAST_TO( c2, CurveACIS );
- ref_EDGE_ptr = curve_acis_ptr->get_EDGE_ptr();
- EDGE_ptr2 = find_corresponding_EDGE( ref_EDGE_ptr, EDGE_list );
- if( EDGE_ptr2 == NULL )
- {
- PRINT_ERROR( "Second curve not found in volume.\n" );
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( output_VERTEX_lists.size() ) delete output_VERTEX_lists.pop();
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( thickened_BODY_list.size() )
- api_delent( thickened_BODY_list.pop() );
- api_delent( copied_input_BODY_ptr );
- return CUBIT_FAILURE;
- }
-
- if( EDGE_list.move_to( EDGE_ptr2 ) == CUBIT_FALSE )
- {
- PRINT_ERROR( "Second curve not attached to vertex.\n" );
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( output_VERTEX_lists.size() ) delete output_VERTEX_lists.pop();
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( thickened_BODY_list.size() )
- api_delent( thickened_BODY_list.pop() );
- api_delent( copied_input_BODY_ptr );
- return CUBIT_FAILURE;
- }
-
- EDGE_list.remove();
- }
- else
- {
- EDGE_ptr2 = EDGE_list.get_and_step();
- if( EDGE_ptr2 == conj_EDGE_ptr )
- EDGE_ptr2 = EDGE_list.get();
- }
-
- // Determine whether r1 and r2 need to be swapped
-
- // Are we on the end of the conjugate curve?
- int on_conj_end = 0;
- if( conj_EDGE_ptr->end() == ref_VERTEX_ptr )
- on_conj_end = 1;
-
- FACE *FACE_ptr = output_FACE_list_ptr->get();
- LOOP *LOOP_ptr = FACE_ptr->loop();
-
- // Find CoEdge whose end is our vertex
- COEDGE *COEDGE_ptr = LOOP_ptr->start();
- VERTEX *end_VERTEX_ptr;
- while( COEDGE_ptr != NULL )
- {
- end_VERTEX_ptr = COEDGE_ptr->end();
- if( end_VERTEX_ptr == ref_VERTEX_ptr )
- break;
-
- COEDGE_ptr = COEDGE_ptr->next();
- if( COEDGE_ptr == LOOP_ptr->start() )
- break;
- }
-
- double tmp_r;
- EDGE_ptr = COEDGE_ptr->edge();
-
- if( (EDGE_ptr == EDGE_ptr2 && on_conj_end) ||
- (EDGE_ptr == EDGE_ptr1 && !on_conj_end) )
- {
- // Swap
- tmp_r = r1;
- r1 = r2;
- r2 = tmp_r;
- }
-
- // Now, blend the edges on this thickened body
- if( chamfer_edges( *output_EDGE_list_ptr, r1, r2 ) == CUBIT_FAILURE )
- {
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( output_VERTEX_lists.size() ) delete output_VERTEX_lists.pop();
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( thickened_BODY_list.size() )
- api_delent( thickened_BODY_list.pop() );
- api_delent( copied_input_BODY_ptr );
- return CUBIT_FAILURE;
- }
-
- // Get bodies ready to swap new surfaces for old
- if( prep_for_surface_swap( thickened_BODY_ptr, copied_input_BODY_ptr,
- owner_list ) == CUBIT_FAILURE )
- {
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( output_VERTEX_lists.size() ) delete output_VERTEX_lists.pop();
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
- while( thickened_BODY_list.size() )
- api_delent( thickened_BODY_list.pop() );
- api_delent( input_BODY_ptr );
- return CUBIT_FAILURE;
- }
-
- } // End loop on thickened (separated) BODIES
-
- // Free memory
- while( output_FACE_lists.size() ) delete output_FACE_lists.pop();
- while( output_VERTEX_lists.size() ) delete output_VERTEX_lists.pop();
- while( output_EDGE_lists.size() ) delete output_EDGE_lists.pop();
-
- // Unite the thickened BODIEs back into the input_BODY_ptr
- BODY *master;
- if( unite_BODIES( input_BODY_ptr, thickened_BODY_list, master ) == CUBIT_FAILURE )
- {
- // If failure, the unite_BODIES function cleaned up the memory
- return CUBIT_FAILURE;
- }
-
- // This BODY is done (whew!)
-
- if( !preview )
- {
- // Now cleanout the owner attributes from the copied BODY, if required
- if( delete_attribs )
- AQE->remove_cubit_owner_attrib_in_BODY(master);
-
- new_bodysm_ptr = AME->get_new_Body( input_bodysm_ptr, input_BODY_ptr,
- master, keep_old_body );
- }
- else
- {
- ENTITY_LIST edge_list;
- api_get_edges( master, edge_list );
- AcisBridge *ab_edge_ptr = NULL;
- for( i=0; i<edge_list.count(); i++ )
- {
- ab_edge_ptr = ATTRIB_CUBIT_OWNER::cubit_owner( edge_list[i] );
- if( !ab_edge_ptr )
- {
- // Draw this edge
- AcisDrawTool::instance()->draw_EDGE( (EDGE*)edge_list[i], CUBIT_BLUE );
- }
- }
-
- api_delent(master);
-
- GfxPreview::flush();
- }
-
- return CUBIT_SUCCESS;
}
-CubitStatus
-AcisTweakTool::assign_tweak_attribs( BODY *BODY_ptr, const char *att_name,
- DLIList<FACE*> &FACE_list, DLIList<AcisBridge*> &ab_FACE_list,
- DLIList<EDGE*> &EDGE_list, DLIList<AcisBridge*> &ab_EDGE_list,
- DLIList<VERTEX*> &VERTEX_list, DLIList<AcisBridge*> &ab_VERTEX_list )
+CubitStatus AcisTweakTool::remove_topology( DLIList<Curve*> &curve_list,
+ DLIList<Surface*> &surface_list,
+ double backoff_distance,
+ double small_edge_size,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean preview )
{
- // Assign named attribs to faces, edges and vertices so we can get back to
- // them after a fillet or chamfer. These operations split these entities
- // to make room for the new surfaces, thus we can copy the owner att
- // during the split.
-
- int i;
- outcome result;
-
- // FACEs
- AQE->get_FACEs( BODY_ptr, FACE_list );
- FACE *FACE_ptr;
- FACE_list.reset();
- for( i=0; i<FACE_list.size(); i++ )
- {
- FACE_ptr = FACE_list.get_and_step();
- result = api_add_generic_named_attribute( FACE_ptr, att_name, i, SplitCopy );
- if( !result.ok() )
- {
- ab_FACE_list.append( NULL );
- continue;
- }
- ab_FACE_list.append( ATTRIB_CUBIT_OWNER::cubit_owner( FACE_ptr ) );
- }
-
-
- // EDGEs
- AQE->get_EDGEs( BODY_ptr, EDGE_list );
- EDGE *EDGE_ptr;
- EDGE_list.reset();
- for( i=0; i<EDGE_list.size(); i++ )
- {
- EDGE_ptr = EDGE_list.get_and_step();
- result = api_add_generic_named_attribute( EDGE_ptr, att_name, i, SplitCopy );
- if( !result.ok() )
- {
- ab_EDGE_list.append( NULL );
- continue;
- }
- ab_EDGE_list.append( ATTRIB_CUBIT_OWNER::cubit_owner( EDGE_ptr ) );
- }
-
- // VERTICEs
- AQE->get_VERTICEs( BODY_ptr, VERTEX_list );
- VERTEX *VERTEX_ptr;
- VERTEX_list.reset();
- for( i=0; i<VERTEX_list.size(); i++ )
- {
- VERTEX_ptr = VERTEX_list.get_and_step();
- result = api_add_generic_named_attribute( VERTEX_ptr, att_name, i, SplitCopy );
- if( !result.ok() )
- {
- ab_VERTEX_list.append( NULL );
- continue;
- }
- ab_VERTEX_list.append( ATTRIB_CUBIT_OWNER::cubit_owner( VERTEX_ptr ) );
- }
-
- return CUBIT_SUCCESS;
-}
-
-CubitStatus
-AcisTweakTool::find_corresponding_entity_from_tweak_attrib( BODY *BODY_ptr,
- const char *att_name,
- const int ent_type,
- int input_ent_id,
- ENTITY *&output_ENTITY_ptr )
-{
- output_ENTITY_ptr = NULL;
- ATTRIB_GEN_NAME *ret_att;
-
- outcome result;
-
- int i, ent_id;
- int found = 0;
- if( ent_type == FACE_TYPE )
- {
- DLIList<FACE*> FACE_list;
- AQE->get_FACEs( BODY_ptr, FACE_list );
- FACE *FACE_ptr;
- FACE_list.reset();
- for( i=FACE_list.size(); i--; )
- {
- FACE_ptr = FACE_list.get_and_step();
- result = api_find_named_attribute( FACE_ptr, att_name, ret_att );
-
- if( !result.ok() || !ret_att )
- continue;
-
- ent_id = ((ATTRIB_GEN_INTEGER *) ret_att)->value();
-
- if( ent_id == input_ent_id )
- {
- if( found == 1 )
- {
- // More than one entity with same att
- output_ENTITY_ptr = NULL;
- return CUBIT_FAILURE;
- }
- output_ENTITY_ptr = (ENTITY *)FACE_ptr;
- found = 1;
- break;
- }
- }
- if( found )
- return CUBIT_SUCCESS;
- else
- return CUBIT_FAILURE;
- }
-
- else if( ent_type == EDGE_TYPE )
- {
- DLIList<EDGE*> EDGE_list;
- AQE->get_EDGEs( BODY_ptr, EDGE_list );
- EDGE *EDGE_ptr;
- EDGE_list.reset();
- for( i=EDGE_list.size(); i--; )
- {
- EDGE_ptr = EDGE_list.get_and_step();
-
- result = api_find_named_attribute( EDGE_ptr, att_name, ret_att );
-
- if( !result.ok() || !ret_att )
- continue;
-
- ent_id = ((ATTRIB_GEN_INTEGER *) ret_att)->value();
-
- if( ent_id == input_ent_id )
- {
- if( found == 1 )
- {
- // More than one entity with same att
- output_ENTITY_ptr = NULL;
- return CUBIT_FAILURE;
- }
- output_ENTITY_ptr = (ENTITY *)EDGE_ptr;
- found = 1;
- break;
- }
- }
- if( found )
- return CUBIT_SUCCESS;
- else
- return CUBIT_FAILURE;
- }
-
- else if( ent_type == VERTEX_TYPE )
- {
- DLIList<VERTEX*> VERTEX_list;
- AQE->get_VERTICEs( BODY_ptr, VERTEX_list );
- VERTEX *VERTEX_ptr;
- VERTEX_list.reset();
- for( i=VERTEX_list.size(); i--; )
- {
- VERTEX_ptr = VERTEX_list.get_and_step();
-
- result = api_find_named_attribute( VERTEX_ptr, att_name, ret_att );
-
- if( !result.ok() || !ret_att )
- continue;
-
- ent_id = ((ATTRIB_GEN_INTEGER *) ret_att)->value();
-
- if( ent_id == input_ent_id )
- {
- if( found == 1 )
- {
- // More than one entity with same att
- output_ENTITY_ptr = NULL;
- return CUBIT_FAILURE;
- }
- output_ENTITY_ptr = (ENTITY *)VERTEX_ptr;
- found = 1;
- break;
- }
- }
- if( found )
- return CUBIT_SUCCESS;
- else
- return CUBIT_FAILURE;
- }
-
- return CUBIT_FAILURE;
-}
-
-CubitStatus
-AcisTweakTool::reassign_cubit_owners_from_tweak_attribs( BODY *BODY_ptr,
- const char *att_name,
- DLIList<FACE*> &FACE_list, DLIList<AcisBridge*> &ab_FACE_list,
- DLIList<EDGE*> &EDGE_list, DLIList<AcisBridge*> &ab_EDGE_list,
- DLIList<VERTEX*> &VERTEX_list, DLIList<AcisBridge*> &ab_VERTEX_list )
-{
-
- int i;
- ENTITY *corr_ENT_ptr;
- AcisBridge *ab_ptr;
-
- // FACEs
- FACE *FACE_ptr;
- FACE_list.reset();
- ab_FACE_list.reset();
- for( i=0; i<FACE_list.size(); i++ )
- {
- FACE_ptr = FACE_list.get_and_step();
- ab_ptr = ab_FACE_list.get_and_step();
- if( find_corresponding_entity_from_tweak_attrib(
- BODY_ptr, att_name, FACE_TYPE, i, corr_ENT_ptr ) == CUBIT_SUCCESS )
- {
- if( ab_ptr )
- ATTRIB_CUBIT_OWNER::set_cubit_owner( (FACE*)corr_ENT_ptr, ab_ptr );
- }
- }
-
- // EDGEs
- EDGE *EDGE_ptr;
- EDGE_list.reset();
- ab_EDGE_list.reset();
- for( i=0; i<EDGE_list.size(); i++ )
- {
- EDGE_ptr = EDGE_list.get_and_step();
- ab_ptr = ab_EDGE_list.get_and_step();
- if( find_corresponding_entity_from_tweak_attrib(
- BODY_ptr, att_name, EDGE_TYPE, i, corr_ENT_ptr ) == CUBIT_SUCCESS )
- {
- if( ab_ptr )
- ATTRIB_CUBIT_OWNER::set_cubit_owner( (EDGE*)corr_ENT_ptr, ab_ptr );
- }
- }
-
- // VERTICEs
- VERTEX *VERTEX_ptr;
- VERTEX_list.reset();
- ab_VERTEX_list.reset();
- for( i=0; i<VERTEX_list.size(); i++ )
- {
- VERTEX_ptr = VERTEX_list.get_and_step();
- ab_ptr = ab_VERTEX_list.get_and_step();
- if( find_corresponding_entity_from_tweak_attrib(
- BODY_ptr, att_name, VERTEX_TYPE, i, corr_ENT_ptr ) == CUBIT_SUCCESS )
- {
- if( ab_ptr )
- ATTRIB_CUBIT_OWNER::set_cubit_owner( (VERTEX*)corr_ENT_ptr, ab_ptr );
- }
- }
-
- return CUBIT_SUCCESS;
-}
-
-CubitStatus
-AcisTweakTool::remove_named_attribs( BODY *BODY_ptr, const char *name )
-{
- DLIList<FACE*> FACE_list;
- AQE->get_FACEs( BODY_ptr, FACE_list );
-
- int i;
- FACE *FACE_ptr;
- for( i=FACE_list.size(); i--; )
- {
- FACE_ptr = FACE_list.get_and_step();
- api_remove_generic_named_attribute(FACE_ptr, name);
- }
-
- // EDGEs
- DLIList<EDGE*> EDGE_list;
- AQE->get_EDGEs( BODY_ptr, EDGE_list );
-
- EDGE *EDGE_ptr;
- for( i=EDGE_list.size(); i--; )
- {
- EDGE_ptr = EDGE_list.get_and_step();
- api_remove_generic_named_attribute( EDGE_ptr, name );
- }
-
- // VERTICEs
- DLIList<VERTEX*> VERTEX_list;
- AQE->get_VERTICEs( BODY_ptr, VERTEX_list );
-
- VERTEX *VERTEX_ptr;
- for( i=VERTEX_list.size(); i--; )
- {
- VERTEX_ptr = VERTEX_list.get_and_step();
- api_remove_generic_named_attribute( VERTEX_ptr, name );
- }
-
- return CUBIT_SUCCESS;
-}
-
-CubitStatus
-AcisTweakTool::blend_edges( DLIList<EDGE*> EDGE_list, double radius )
-{
- int i;
- EDGE *EDGE_ptr;
- ENTITY_LIST ENTITY_list;
-
- EDGE_list.reset();
- for( i=EDGE_list.size(); i--; )
- {
- EDGE_ptr = EDGE_list.get_and_step();
- if( EDGE_ptr )
- ENTITY_list.add( EDGE_ptr );
- }
-
- if( ENTITY_list.count() == 0 )
+ PRINT_ERROR("This feature is not implemented.\n");
return CUBIT_FAILURE;
-
- BODY *BODY_ptr = AcisQueryEngine::instance()->get_BODY_of_ENTITY( ENTITY_list[0] );
-
- // Setup tweak attributes so we can preserve Cubit owners
- DLIList<FACE*> pre_FACE_list;
- DLIList<EDGE*> pre_EDGE_list;
- DLIList<VERTEX*> pre_VERTEX_list;
- DLIList<AcisBridge*> ab_FACE_list, ab_EDGE_list, ab_VERTEX_list;
- assign_tweak_attribs( BODY_ptr, "tweak", pre_FACE_list, ab_FACE_list,
- pre_EDGE_list, ab_EDGE_list, pre_VERTEX_list, ab_VERTEX_list );
-
- // Now, blend the edges on this body
- outcome result = api_blend_edges( ENTITY_list, radius );
-
- if( !result.ok() )
- {
- AcisQueryEngine::instance()->ACIS_API_error(result);
- return CUBIT_FAILURE;
- }
-
- //printout warnings too
- err_mess_type *warnings;
- int nwarn = get_warnings( warnings );
- if( nwarn > 0 )
- {
- PRINT_WARNING("API Warning(s):\n");
- for( i=0; i<nwarn; i++ )
- PRINT_INFO("%s\n", find_err_mess( warnings[i]));
- }
-
- // Replace Cubit owners
- reassign_cubit_owners_from_tweak_attribs( BODY_ptr, "tweak", pre_FACE_list,
- ab_FACE_list, pre_EDGE_list, ab_EDGE_list, pre_VERTEX_list,
- ab_VERTEX_list );
-
- // Remove tweak attributes
- remove_named_attribs( BODY_ptr, "tweak" );
-
- return CUBIT_SUCCESS;
}
-CubitStatus
-AcisTweakTool::chamfer_edges( DLIList<EDGE*> EDGE_list, double r1, double r2 )
-{
- if( r2 <= 0.0 )
- r2 = r1;
- int i;
- EDGE *EDGE_ptr;
- ENTITY_LIST ENTITY_list;
-
- EDGE_list.reset();
- for( i=EDGE_list.size(); i--; )
- {
- EDGE_ptr = EDGE_list.get_and_step();
- if( EDGE_ptr )
- ENTITY_list.add( EDGE_ptr );
- }
-
- if( ENTITY_list.count() == 0 )
- return CUBIT_FAILURE;
-
- BODY *BODY_ptr = AcisQueryEngine::instance()->get_BODY_of_ENTITY( ENTITY_list[0] );
-
- // Setup tweak attributes so we can preserve Cubit owners
- DLIList<FACE*> pre_FACE_list;
- DLIList<EDGE*> pre_EDGE_list;
- DLIList<VERTEX*> pre_VERTEX_list;
- DLIList<AcisBridge*> ab_FACE_list, ab_EDGE_list, ab_VERTEX_list;
- assign_tweak_attribs( BODY_ptr, "tweak", pre_FACE_list, ab_FACE_list,
- pre_EDGE_list, ab_EDGE_list, pre_VERTEX_list, ab_VERTEX_list );
-
- // Now, blend the edges on this body
- outcome result = api_chamfer_edges( ENTITY_list, r1, r2 );
-
- if( !result.ok() )
- {
- AcisQueryEngine::instance()->ACIS_API_error(result);
- return CUBIT_FAILURE;
- }
- else
- PRINT_INFO("Result was okay\n");
-
- // Replace Cubit owners
- reassign_cubit_owners_from_tweak_attribs( BODY_ptr, "tweak", pre_FACE_list,
- ab_FACE_list, pre_EDGE_list, ab_EDGE_list, pre_VERTEX_list,
- ab_VERTEX_list );
-
- // Remove tweak attributes
- remove_named_attribs( BODY_ptr, "tweak" );
-
- return CUBIT_SUCCESS;
-}
-
-CubitStatus
-AcisTweakTool::chamfer_vertices( DLIList<VERTEX*> VERTEX_list, double radius )
-{
- int i;
- VERTEX *VERTEX_ptr;
- ENTITY_LIST ENTITY_list;
-
- VERTEX_list.reset();
- for( i=VERTEX_list.size(); i--; )
- {
- VERTEX_ptr = VERTEX_list.get_and_step();
- if( VERTEX_ptr )
- ENTITY_list.add( VERTEX_ptr );
- }
-
- if( ENTITY_list.count() == 0 )
- return CUBIT_FAILURE;
-
- BODY *BODY_ptr = AcisQueryEngine::instance()->get_BODY_of_ENTITY( ENTITY_list[0] );
-
- // Setup tweak attributes so we can preserve Cubit owners
- DLIList<FACE*> pre_FACE_list;
- DLIList<EDGE*> pre_EDGE_list;
- DLIList<VERTEX*> pre_VERTEX_list;
- DLIList<AcisBridge*> ab_FACE_list, ab_EDGE_list, ab_VERTEX_list;
- assign_tweak_attribs( BODY_ptr, "tweak", pre_FACE_list, ab_FACE_list,
- pre_EDGE_list, ab_EDGE_list, pre_VERTEX_list, ab_VERTEX_list );
-
- // Now, blend the edges on this body
- outcome result = api_chamfer_vertices( ENTITY_list, radius );
-
- if( !result.ok() )
- {
- AcisQueryEngine::instance()->ACIS_API_error(result);
- return CUBIT_FAILURE;
- }
-
- // Replace Cubit owners
- reassign_cubit_owners_from_tweak_attribs( BODY_ptr, "tweak", pre_FACE_list,
- ab_FACE_list, pre_EDGE_list, ab_EDGE_list, pre_VERTEX_list,
- ab_VERTEX_list );
-
- // Remove tweak attributes
- remove_named_attribs( BODY_ptr, "tweak" );
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : get_EDGES_by_BODY
-// Member Type: PRIVATE
-// Description: Get separate lists of EDGEs from the input Curves by common
-// BODY
-// Author : Steve Storm
-// Date : 12/18/05
-//=============================================================================
-CubitStatus
-AcisTweakTool::get_EDGES_by_BODY( DLIList<Curve*> &input_curve_list,
- DLIList<BODY*> &BODY_list,
- DLIList<DLIList<EDGE*>*> &BODY_EDGE_lists )
-{
- int i;
- Curve *curve_ptr;
- EDGE *EDGE_ptr;
- BODY *BODY_ptr;
- BODY *curr_BODY_ptr;
-
- // Copy input curve list since we don't want to modify it
- DLIList<Curve*> copied_input_curve_list = input_curve_list;
-
- // Pull curves out of the input curve list that are from a common BODY
- DLIList<EDGE*> *curr_BODY_EDGE_list_ptr = NULL;
- while( copied_input_curve_list.size() )
- {
- curr_BODY_ptr = NULL;
- copied_input_curve_list.reset();
- for( i=copied_input_curve_list.size(); i--; )
- {
- curve_ptr = copied_input_curve_list.get();
- EDGE_ptr = AQE->get_EDGE( curve_ptr );
- if( EDGE_ptr == NULL )
- {
- PRINT_ERROR( "Non-ACIS curve encountered.\n" );
- BODY_list.clean_out();
- while( BODY_EDGE_lists.size() ) delete BODY_EDGE_lists.pop();
- return CUBIT_FAILURE;
- }
-
- BODY_ptr = AQE->get_BODY_of_ENTITY( EDGE_ptr );
- if( curr_BODY_ptr == NULL )
- {
- BODY_list.append( BODY_ptr );
- curr_BODY_ptr = BODY_ptr;
- curr_BODY_EDGE_list_ptr = new DLIList<EDGE*>;
- BODY_EDGE_lists.append( curr_BODY_EDGE_list_ptr );
- }
-
- if( curr_BODY_ptr == BODY_ptr )
- {
- curr_BODY_EDGE_list_ptr->append( EDGE_ptr );
- copied_input_curve_list.change_to( NULL );
- }
-
- copied_input_curve_list.step();
- }
-
- copied_input_curve_list.remove_all_with_value( NULL );
- curr_BODY_ptr = NULL;
- }
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : get_EDGES_by_BODY
-// Member Type: PRIVATE
-// Description: Get separate lists of EDGEs from the input Curves by common
-// BODY
-// Author : Steve Storm
-// Date : 12/18/05
-//=============================================================================
-CubitStatus
-AcisTweakTool::get_EDGES_by_BODY( DLIList<EDGE*> &input_EDGE_list,
- DLIList<BODY*> &BODY_list,
- DLIList<DLIList<EDGE*>*> &BODY_EDGE_lists )
-{
- int i;
- EDGE *EDGE_ptr;
- BODY *BODY_ptr;
- BODY *curr_BODY_ptr;
-
- // Copy input EDGE list since we don't want to modify it
- DLIList<EDGE*> copied_input_EDGE_list = input_EDGE_list;
-
- // Pull EDGEs out of the input EDGE list that are from a common BODY
- DLIList<EDGE*> *curr_BODY_EDGE_list_ptr = NULL;
- while( copied_input_EDGE_list.size() )
- {
- curr_BODY_ptr = NULL;
- copied_input_EDGE_list.reset();
- for( i=copied_input_EDGE_list.size(); i--; )
- {
- EDGE_ptr = copied_input_EDGE_list.get();
-
- BODY_ptr = AQE->get_BODY_of_ENTITY( EDGE_ptr );
- if( curr_BODY_ptr == NULL )
- {
- BODY_list.append( BODY_ptr );
- curr_BODY_ptr = BODY_ptr;
- curr_BODY_EDGE_list_ptr = new DLIList<EDGE*>;
- BODY_EDGE_lists.append( curr_BODY_EDGE_list_ptr );
- }
-
- if( curr_BODY_ptr == BODY_ptr )
- {
- curr_BODY_EDGE_list_ptr->append( EDGE_ptr );
- copied_input_EDGE_list.change_to( NULL );
- }
-
- copied_input_EDGE_list.step();
- }
-
- copied_input_EDGE_list.remove_all_with_value( NULL );
- curr_BODY_ptr = NULL;
- }
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : all_complete_holes
-// Member Type: PRIVATE
-// Description: Determine if given EDGEs form complete internal holes. LOOPs
-// must be on a sheet BODY. Return those LOOPs. All given EDGEs
-// must be in the same BODY.
-// Author : Steve Storm
-// Date : 12/18/05
-//=============================================================================
-CubitStatus
-AcisTweakTool::all_complete_internal_loops( DLIList<EDGE*> &BODY_EDGE_list,
- DLIList<LOOP*> &LOOP_list )
-{
- int i;
- EDGE *EDGE_ptr;
- LOOP *LOOP_ptr;
-
- DLIList<EDGE*> copied_EDGE_list = BODY_EDGE_list;
-
- while( copied_EDGE_list.size() )
- {
- copied_EDGE_list.reset();
- EDGE_ptr = copied_EDGE_list.get();
-
- DLIList<LOOP*> EDGE_LOOP_list;
- AQE->get_LOOPs( EDGE_ptr, EDGE_LOOP_list );
- if( EDGE_LOOP_list.size() == 0 )
- {
- LOOP_list.clean_out();
- return CUBIT_FAILURE;
- }
-
- // Should always be just one LOOP per EDGE
- LOOP_ptr = EDGE_LOOP_list.get();
-
- loop_type type;
- outcome result = api_loop_type( LOOP_ptr, type );
- if( !result.ok() )
- {
- AQE->ACIS_API_error(result);
- LOOP_list.clean_out();
- return CUBIT_FAILURE;
- }
- if( type != loop_hole )
- {
- LOOP_list.clean_out();
- return CUBIT_FAILURE;
- }
-
- DLIList<EDGE*> LOOP_EDGE_list;
- AQE->get_EDGEs( LOOP_ptr, LOOP_EDGE_list );
-
- LOOP_EDGE_list.reset();
- for( i=LOOP_EDGE_list.size(); i--; )
- {
- EDGE_ptr = LOOP_EDGE_list.get_and_step();
-
- if( copied_EDGE_list.move_to( EDGE_ptr ) == CUBIT_TRUE )
- {
- // Remove from the list
- copied_EDGE_list.change_to( NULL );
- }
- else
- {
- // All EDGEs must be in the input EDGE list
- LOOP_list.clean_out();
- return CUBIT_FAILURE;
- }
- }
-
- LOOP_list.append( LOOP_ptr );
-
- copied_EDGE_list.remove_all_with_value( NULL );
- }
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : remove_LOOPs
-// Member Type: PRIVATE
-// Description: Remove the given internal LOOPs (from a sheet BODY).
-// Author : Steve Storm
-// Date : 12/18/05
-//=============================================================================
-CubitStatus
-AcisTweakTool::remove_LOOPs( DLIList<LOOP*> &LOOP_list )
-{
- if( LOOP_list.size() == 0 )
- return CUBIT_SUCCESS;
-
- int i;
- FACE *FACE_ptr;
- LOOP *LOOP_ptr;
-
- LOOP_list.reset();
- for( i=LOOP_list.size(); i--; )
- {
- LOOP_ptr = LOOP_list.get_and_step();
-
- FACE_ptr = LOOP_ptr->face();
- if( FACE_ptr->sides() != DOUBLE_SIDED )
- {
- PRINT_ERROR("Cannot remove loops that are not on sheet bodies\n" );
- return CUBIT_FAILURE;
- }
-
- LOOP *tmp_LOOP_ptr = FACE_ptr->loop();
-
- if( tmp_LOOP_ptr == LOOP_ptr )
- {
- // First loop in list is an internal loop we are trying to remove
- tmp_LOOP_ptr = tmp_LOOP_ptr->next();
- FACE_ptr->set_loop( tmp_LOOP_ptr );
- }
- else
- {
- LOOP *prev_LOOP_ptr = NULL;
- LOOP *next_LOOP_ptr = NULL;
- while ( tmp_LOOP_ptr != LOOP_ptr )
- {
- prev_LOOP_ptr = tmp_LOOP_ptr;
- tmp_LOOP_ptr = tmp_LOOP_ptr->next();
- }
- next_LOOP_ptr = LOOP_ptr->next();
-
- // Now set the next LOOP pointer of the previous to the next
- prev_LOOP_ptr->set_next( next_LOOP_ptr );
- }
-
- // Now delete this LOOP and all entities below it
- outcome result = api_delent( LOOP_ptr );
- if( !result.ok() )
- {
- AcisQueryEngine::instance()->ACIS_API_error(result);
- PRINT_ERROR( "Unable to remove loop - aborting\n" );
- return CUBIT_FAILURE;
- }
- }
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : remove_holes
-// Member Type: PRIVATE
-// Description: Remove all holes from the given sheet BODY.
-// Author : Steve Storm
-// Date : 2/12/06
-//=============================================================================
-CubitStatus
-AcisTweakTool::remove_holes( BODY *sheet_BODY_ptr )
-{
- // Holes in a sheet body will be internal LOOPs with only 1 coedge on each
- // curve.
-
- // Get all LOOPs of the sheet BODY
- DLIList<LOOP*> LOOP_list;
- AQE->get_LOOPs( sheet_BODY_ptr, LOOP_list );
-
- // Put internal LOOPs to remove into a separate list
- DLIList<LOOP*> hole_LOOP_list;
- int i;
- outcome result;
- loop_type type;
- ENTITY_LIST COEDGES;
- LOOP *LOOP_ptr;
- for( i=LOOP_list.size(); i--; )
- {
- LOOP_ptr = LOOP_list.get_and_step();
-
- result = api_loop_type( LOOP_ptr, type );
- if( !result.ok() )
- {
- AQE->ACIS_API_error(result);
- return CUBIT_FAILURE;
- }
- if( type == loop_hole )
- {
- // Check coedges on edges in loop - if more than one it is shared and we
- // don't want to remove it.
- DLIList<EDGE*> EDGE_list;
- AQE->get_EDGEs( LOOP_ptr, EDGE_list );
- if( EDGE_list.size() )
- {
- EDGE *EDGE_ptr = EDGE_list.get();
-
- result = api_get_coedges( EDGE_ptr, COEDGES);
- if( !result.ok() )
- {
- AQE->ACIS_API_error(result);
- return CUBIT_FAILURE;
- }
-
- ENTITY *COEDGE_ptr;
- COEDGES.init();
-
- int good = 1;
-
- while( (COEDGE_ptr = COEDGES.next() ) != NULL )
- {
- if( COEDGES.iteration_count() == 1 )
- continue;
- good--;
- }
-
- COEDGES.clear();
-
- if( good > 0 )
- hole_LOOP_list.append( LOOP_ptr );
- }
- }
- }
-
- // Remove the internal LOOPs
- if( remove_LOOPs( hole_LOOP_list ) == CUBIT_FAILURE )
- return CUBIT_FAILURE;
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : extrema_pln_BODY
-// Member Type: PRIVATE
-// Description: Finds the extrema distance from a plane to an ACIS BODY
-// (perpendicular distance from plane to farthest extent of BODY),
-// on one side of the plane (by default on the front of the plane
-// - direction of plane normal). If the entire BODY lies on the
-// other side of the plane, the extrema distance is 0.0.
-// Author : Steve Storm
-// Date : 1/15/06
-//=============================================================================
-CubitStatus AcisTweakTool::extrema_pln_BODY( CubitPlane &plane, BODY *BODY_ptr,
- double &extrema_dist,
- int back_side )
-{
- // Method: find EXTREMA point of BODY in direction of plane norm, check
- // distance to plane.
- ENTITY_LIST ENTITY_list;
- ENTITY_list.add( BODY_ptr );
-
- CubitVector dir = back_side ? -(plane.normal()) : plane.normal();
-
- SPAvector acis_dirs[3];
- acis_dirs[0].set_x( dir.x() );
- acis_dirs[0].set_y( dir.y() );
- acis_dirs[0].set_z( dir.z() );
-
- SPAposition acis_pos;
- param_info info;
- outcome result = api_entity_extrema( ENTITY_list, 1, acis_dirs, acis_pos,
- info );
- if( !result.ok() )
- {
- AcisQueryEngine::instance()->ACIS_API_error( result );
- return CUBIT_FAILURE;
- }
-
- CubitVector extrema_pnt( acis_pos.x(), acis_pos.y(), acis_pos.z() );
-
- // Get intersection point on plane
- CubitVector int_pnt;
- int_pnt = plane.intersect( extrema_pnt, dir );
-
- // Get direction from int_pnt to extrema_pnt
- CubitVector dir2( int_pnt, extrema_pnt );
-
- // Note: angle between vectors acute (<90) if dot product > 0. In
- // this case the vectors would be going the same direction and the extrema
- // point is on the correct side of the plane
- if( dir % dir2 > 0.0 )
- extrema_dist = int_pnt.distance_between( extrema_pnt );
- else
- extrema_dist = 0.0;
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : tweak_FACEs_to_target
-// Member Type: PRIVATE
-// Description: Tweak the given FACEs (which must all be part of the same BODY)
-// to the given target FACE.
-// Author : Steve Storm
-// Date : 1/15/06
-//=============================================================================
-CubitStatus
-AcisTweakTool::tweak_FACEs_to_target( DLIList<FACE*> &source_FACE_list,
- FACE *target_FACE_ptr,
- CubitBoolean reverse_flg,
- CubitBoolean skip_self_int_check )
-{
- int i;
- outcome result;
- int num_faces = source_FACE_list.size();
-
- // Get normal of tool (target) surface
- CubitVector location;
- CubitVector target_normal_vec = surface_normal( target_FACE_ptr, location );
- if( reverse_flg )
- target_normal_vec = -target_normal_vec;
-
- // Save the center point of the bounding box of the target face
- SPAposition target_surf_bb_center( location.x(), location.y(), location.z() );
-
- // Create arrays of input FACEs for tweak API.
- // Note: Apparently the API requires a copy of the tool geometry for each
- // tweak surface
- FACE** source_FACES = new FACE*[num_faces];
- DLIList<FACE*> target_FACE_list(num_faces);
- SURFACE** target_SURFACES = new SURFACE*[num_faces];
- int* target_sense = new int[num_faces];
- FACE *FACE_ptr;
- source_FACE_list.reset();
- for( i=0; i<num_faces; i++ )
- {
- // Fill source_FACES array
- FACE_ptr = source_FACE_list.get_and_step();
- source_FACES[i] = FACE_ptr;
-
- // Fill target_SURFACES array
- ENTITY* copied_entity_ptr = 0;
- api_copy_entity_contents(target_FACE_ptr, copied_entity_ptr);
- if( copied_entity_ptr == 0 )
- {
- while( target_FACE_list.size() ) api_delent( target_FACE_list.pop() );
- delete []source_FACES;
- delete []target_SURFACES;
- delete []target_sense;
- PRINT_ERROR( "Invalid ACIS target surface -- aborting\n" );
- return CUBIT_FAILURE;
- }
- target_FACE_list.append( (FACE*)copied_entity_ptr );
- target_SURFACES[i] = ((FACE*)copied_entity_ptr)->geometry();
-
- SPAposition dummy;
- SPAunit_vector tmp_vec;
- FACE_ptr->geometry()->equation().point_perp( target_surf_bb_center, dummy, tmp_vec );
- CubitVector tweak_normal_vec( tmp_vec.x(), tmp_vec.y(), tmp_vec.z() );
-
- // Fill target_sense array
- target_sense[i] = ((tweak_normal_vec % target_normal_vec) < 0.0);
- }
-
- SPAposition box_h(0,0,0);
- SPAposition box_l(0,0,0);
-
- // This operation sometimes destroys owner attributes
- BODY *copied_BODY_ptr = AQE->get_BODY_of_ENTITY( source_FACE_list.get() );
- AcisBridge *ab_body_ptr;
- AcisBridge *ab_lump_ptr;
- AcisBridge *ab_shell_ptr;
- get_owner_attribs( copied_BODY_ptr, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
-
- // Setup tweak attributes so we can preserve Cubit owners
- DLIList<FACE*> pre_FACE_list;
- DLIList<EDGE*> pre_EDGE_list;
- DLIList<VERTEX*> pre_VERTEX_list;
- DLIList<AcisBridge*> ab_FACE_list, ab_EDGE_list, ab_VERTEX_list;
- assign_tweak_attribs( copied_BODY_ptr, "tweak", pre_FACE_list, ab_FACE_list,
- pre_EDGE_list, ab_EDGE_list, pre_VERTEX_list, ab_VERTEX_list );
-
-#if CUBIT_ACIS_VERSION < 1600
- result = api_tweak_faces( num_faces, (FACE**)source_FACES,
- target_SURFACES, target_sense, box_h, box_l );
-#else
- if( skip_self_int_check )
- {
- lop_options lop_opt = lop_options();
- lop_opt.set_repair_self_int(FALSE);
- result = api_tweak_faces( num_faces, (FACE**)source_FACES,
- target_SURFACES, target_sense, box_h, box_l, &lop_opt );
- }
- else
- {
- result = api_tweak_faces( num_faces, (FACE**)source_FACES,
- target_SURFACES, target_sense, box_h, box_l );
- }
-#endif
-
- // Reset the owner attributes
- reset_owner_attribs( copied_BODY_ptr, ab_body_ptr, ab_lump_ptr, ab_shell_ptr );
-
- // Replace Cubit owners
- reassign_cubit_owners_from_tweak_attribs( copied_BODY_ptr, "tweak",
- pre_FACE_list, ab_FACE_list, pre_EDGE_list, ab_EDGE_list, pre_VERTEX_list,
- ab_VERTEX_list );
-
- remove_named_attribs( copied_BODY_ptr, "tweak" );
-
- // Freeup memory
- while( target_FACE_list.size() ) api_delent( target_FACE_list.pop() );
- delete []source_FACES;
- delete []target_SURFACES;
- delete []target_sense;
-
- if( !result.ok() )
- {
- AcisQueryEngine::instance()->ACIS_API_error(result);
- return CUBIT_FAILURE;
- }
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : surface_normal
-// Member Type: PRIVATE
-// Description: Get normal of underlying surface of given FACE. The normal is
-// found at the approximate centroid of the FACE. Note the normal
-// is NOT adjusted for the FACE sense.
-// Author : Steve Storm
-// Date : 1/15/06
-//=============================================================================
-CubitVector
-AcisTweakTool::surface_normal( FACE *FACE_ptr, CubitVector &location,
- CubitBoolean calc_loc )
-{
- SPAunit_vector acis_normal;
-
- if( calc_loc )
- {
- // Get bounding box of FACE
- CubitBox box = AQE->bounding_box(AQE->bounding_box( FACE_ptr ));
-
- // Get center point of bounding box
- CubitVector center = box.center();
-
- // Move to the FACE and get the normal at that location
- SPAposition acis_point ( center.x(), center.y(), center.z() );
- SPAposition acis_point_on_surf;
- (FACE_ptr->geometry()->equation()).point_perp( acis_point,
- acis_point_on_surf, acis_normal );
-
- location.set( acis_point_on_surf.x(), acis_point_on_surf.y(),
- acis_point_on_surf.z() );
- }
- else
- {
- SPAposition acis_point ( location.x(), location.y(), location.z() );
- SPAposition acis_point_on_surf;
- (FACE_ptr->geometry()->equation()).point_perp( acis_point,
- acis_point_on_surf, acis_normal );
- }
-
- CubitVector return_vector( acis_normal.x(), acis_normal.y(),
- acis_normal.z() );
-
- return return_vector;
-}
-
-//=============================================================================
-// Function : FACE_normal
-// Member Type: PRIVATE
-// Description: Get normal of given FACE. The normal is found at the
-// approximate centroid of the FACE. Note the normal is adjusted
-// for the FACE sense.
-// Author : Steve Storm
-// Date : 1/28/06
-//=============================================================================
-CubitVector
-AcisTweakTool::FACE_normal( FACE *FACE_ptr, CubitVector &location,
- CubitBoolean calc_loc )
-{
- CubitVector FACE_normal = surface_normal( FACE_ptr, location, calc_loc );
-
- // Adjust for the FACE sense
- if( FACE_ptr->sense() == REVERSED )
- FACE_normal = -FACE_normal;
-
- return FACE_normal;
-}
-
-//=============================================================================
-// Function : weighted_average_FACE_normal
-// Member Type: PRIVATE
-// Description: Get weighted average normal of given FACEs. The normals are
-// weighted by FACE area utilizing the graphics facets.
-// Author : Steve Storm
-// Date : 2/21/06
-//=============================================================================
-CubitVector
-AcisTweakTool::weighted_average_FACE_normal( DLIList<FACE*> &FACE_list )
-{
- int i;
- FACE *FACE_ptr;
- CubitVector total_vec;
-
- for( i=FACE_list.size(); i--; )
- {
- FACE_ptr = FACE_list.get_and_step();
- CubitVector FACE_norm;
- double FACE_weight;
- weighted_average_FACE_normal( FACE_ptr, FACE_norm, FACE_weight );
-
- total_vec = total_vec += FACE_weight * FACE_norm;
- }
-
- //PRINT_INFO( "Weighted normal vec = %f, %f, %f\n", total_vec.x(), total_vec.y(),
- // total_vec.z() );
-
- total_vec.normalize();
- //PRINT_INFO( "Weighted normal normalized = %f, %f, %f\n", total_vec.x(), total_vec.y(),
- // total_vec.z() );
-
- return total_vec;
-}
-
-//=============================================================================
-// Function : weighted_average_FACE_normal
-// Member Type: PRIVATE
-// Description: Get normal (unit vector) and weight (area factor) of a given
-// FACE. The graphics facets are utilized in the calculation.
-// Author : Steve Storm
-// Date : 2/21/06
-//=============================================================================
-CubitStatus
-AcisTweakTool::weighted_average_FACE_normal( FACE *FACE_ptr,
- CubitVector &normal,
- double &weight )
-{
- int i;
- int num_tris, num_pnts, num_facets;
- GMem g_mem;
- unsigned short norm_tol = 10;
- double dist_tol = -1.0;
- AQE->get_graphics( FACE_ptr, num_tris, num_pnts, num_facets,
- &g_mem, norm_tol, dist_tol );
-
- if(num_tris < 1)
- {
- // Decrease tolerance and try again (we can get this for small features)
- norm_tol /= 2;
- AQE->get_graphics( FACE_ptr, num_tris, num_pnts, num_facets, &g_mem,
- norm_tol, dist_tol);
- }
-
- if(num_tris < 1)
- {
- // Lets give up
- PRINT_ERROR( "Unable to find average normal of a surface\n" );
- return CUBIT_FAILURE;
- }
-
- // Initialize
- weight = 0.0;
- normal.set( 0.0, 0.0, 0.0 );
-
- // Loop through the triangles
- double tri_weight, A, B, C;
- GPoint p[3];
- GPoint* plist = g_mem.point_list();
- int* facet_list = g_mem.facet_list();
- int c = 0;
- for( i=0; i<num_tris; i++ )
- {
- p[0] = plist[facet_list[++c]];
- p[2] = plist[facet_list[++c]];
- p[1] = plist[facet_list[++c]];
- c++;
-
- // Get centroid
- CubitVector p1( p[0].x, p[0].y, p[0].z );
- CubitVector p2( p[2].x, p[2].y, p[2].z );
- CubitVector p3( p[1].x, p[1].y, p[1].z );
-
- CubitVector center = (p1 + p2 + p3)/3.0;
-
- // Get normal direction at the point closest to the location on the
- // surface. This method usually returns the normal, but if the nearest
- // point is a singularity (like the apex of a cone), this method still
- // returns an outward direction. The base class definition returns
- // point_normal, which is used by default on simple surfaces.
- SPAposition acis_center( center.x(), center.y(), center.z() );
- SPAunit_vector acis_normal = (FACE_ptr->geometry()->equation()).
- point_outdir( acis_center );
-
- CubitVector norm( acis_normal.x(), acis_normal.y(), acis_normal.z() );
-
- // Get triangle area
- A = p1.y() * p2.z() + p1.z() * p3.y() + p2.y() * p3.z() -
- p2.z() * p3.y() - p1.y() * p3.z() - p1.z() * p2.y();
-
- B = p1.z() * p2.x() + p1.x() * p3.z() + p2.z() * p3.x() -
- p2.x() * p3.z() - p1.z() * p3.x() - p1.x() * p2.z();
-
- C = p1.x() * p2.y() + p1.y() * p3.x() + p2.x() * p3.y() -
- p2.y() * p3.x() - p1.x() * p3.y() - p1.y() * p2.x();
-
- //Note: triangle area = 0.5*(sqrt(A*A+B*B+C*C));
-
- tri_weight = 0.5*(A*A+B*B+C*C);
-
- normal += tri_weight * norm;
-
- weight += tri_weight;
-
- }
-
- //double FACE_area;
- //double accur_achieved;
- //outcome result = api_ent_area( FACE_ptr, .001, FACE_area, accur_achieved );
- //PRINT_INFO( "\nArea by ACIS = %f\n", FACE_area );
- //PRINT_INFO( "Area by facets = %f\n", weight );
-
- normal.normalize();
-
- if( FACE_ptr->sense() == REVERSED )
- normal = -normal;
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : create_offset_planar_body
-// Member Type: PRIVATE
-// Description: Create a planar ACIS BODY from the given CubitPlane and offset.
-// The offset is in the direction of the plane's normal. The
-// plane is arbitrarily 10x10x10 in size near the origin.
-// Author : Steve Storm
-// Date : 3/19/06
-//=============================================================================
-CubitStatus
-AcisTweakTool::create_offset_planar_body( CubitPlane &plane, double offset,
- BODY *&planar_BODY_ptr )
-{
- // Get corners of the surface
- CubitVector normal = plane.normal();
- CubitVector x, y;
- normal.orthogonal_vectors( x, y );
- // There is a bug in the point_on_plane (it needs to check against a small
- // value instead of an exact 0) - for now, do our own calculation. This
- // allows us to check for an invalid plane anyway...
- //CubitVector p1 = target_plane.point_on_plane();
- CubitVector p1;
- double coeff = plane.coefficient();
- if( fabs( normal.x() ) > 1e-6 )
- p1.set( -coeff/normal.x(), 0.0, 0.0 );
- else if( fabs( normal.y() ) > 1e-6 )
- p1.set( 0.0, -coeff/normal.y(), 0.0 );
- else if( fabs( normal.z() ) > 1e-6 )
- p1.set( 0.0, 0.0, -coeff/normal.z() );
- else
- {
- PRINT_ERROR( "Error constructing offset plane past the targets\n" );
- return CUBIT_FAILURE;
- }
-
- p1.next_point( normal, offset, p1 );
- CubitVector p2, p3, p4;
- p1.next_point( x, 5.0, p1 );
- p1.next_point( y, 5.0, p1 );
- p1.next_point( -x, 10.0, p2 );
- p2.next_point( -y, 10.0, p3 );
- p3.next_point( x, 10.0, p4 );
-
- planar_BODY_ptr = AME->make_planar_quad_BODY( p1, p2, p3, p4 );
- if( !planar_BODY_ptr )
- {
- PRINT_ERROR( "Error constructing offset plane past the targets\n" );
- return CUBIT_FAILURE;
- }
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : create_extended_sheet
-// Member Type: PRIVATE
-// Description: Extend out a set of FACEs and place into a new sheet BODY.
-// Holes are removed and the BODY is healed for consistent FACE
-// normals. The BODY is also regularized.
-// Author : Steve Storm
-// Date : 1/15/06
-//=============================================================================
-CubitStatus
-AcisTweakTool::create_extended_sheet( DLIList<FACE*> &FACE_list,
- BODY *&ext_BODY_ptr )
-{
- // Method:
- // Copy FACEs into separate sheet bodies
- // If not entirely surrounded by other FACEs, extend past super bounding box
- // Clip by a large bounding box so they are same size
- // Unite them all together
- // Remove FACEs that don't overlap original FACEs
- // Make sure FACE normals are consistent (we do this by healing)
- // Remove any holes
- // Remove unwanted topology (regularize)
-
- // It is useful to heal and regularize the surfaces first. The method we use
- // has problems with spline surfaces - by healing we hopefully simplify the
- // splines to analytics.
- BODY *sheet_body;
- if( copy_FACEs_into_sheet( FACE_list, sheet_body ) == CUBIT_FAILURE )
- return CUBIT_FAILURE;
-
- // Get the new FACEs
- DLIList<FACE*> new_FACE_list;
- AQE->get_FACEs( sheet_body, new_FACE_list );
-
- int i;
- FACE *FACE_ptr;
- FACE *new_FACE_ptr;
- BODY *BODY_ptr;
- DLIList<BODY*> ext_BODY_list;
- new_FACE_list.reset();
- for( i=new_FACE_list.size(); i--; )
- {
- FACE_ptr = new_FACE_list.get_and_step();
-
- // Do not extend if entirely enclosed by the other surfaces
- CubitBoolean extend = FACE_surrounded( FACE_ptr, new_FACE_list )
- ? CUBIT_FALSE : CUBIT_TRUE;
-
- new_FACE_ptr = AME->make_FACE( FACE_ptr, extend );
- if( new_FACE_ptr == NULL )
- {
- PRINT_ERROR( "Problem extending surface - aborting\n" );
- api_delent( sheet_body );
- while( ext_BODY_list.size() )
- api_delent( ext_BODY_list.pop() );
- return CUBIT_FAILURE;
- }
- // Get the BODY this new FACE is in
- BODY_ptr = AQE->get_BODY_of_ENTITY( new_FACE_ptr );
- if( BODY_ptr == NULL )
- {
- PRINT_ERROR( "Problem extending surface - aborting\n" );
- api_delent( sheet_body );
- while( ext_BODY_list.size() )
- api_delent( ext_BODY_list.pop() );
- return CUBIT_FAILURE;
- }
-
- ext_BODY_list.append( BODY_ptr );
- }
-
- // We are done with the sheet_body
- api_delent( sheet_body );
-
- // Unite all of the extended BODIES together
- outcome result;
- DLIList<BODY*> BODY_list;
- ext_BODY_list.reset();
- BODY *master = ext_BODY_list.extract();
- for( i=ext_BODY_list.size(); i--; )
- {
- BODY_ptr = ext_BODY_list.extract();
-
- // Do the union of the master and the BODY_ptr.
- // If this is successful, the result is master and
- // BODY_ptr will be deleted
- result = api_boolean( BODY_ptr, master, UNION );
- if( !result.ok() || (!master) )
- {
- AQE->ACIS_API_error(result);
- while( ext_BODY_list.size() )
- api_delent( ext_BODY_list.pop() );
- if (master != NULL) api_delent(master);
- return CUBIT_FAILURE;
- }
- }
-
- // Cut by a bounding box, so all entities are the same extents. Otherwise,
- // cylinders won't be handled correctly (they may remain full cylinders
- // which is undesireable).
- CubitBox box = GeometryQueryTool::instance()->model_bounding_box();
-
- // Check the box for zero dimensions, which can definitely occur if we are
- // working with 2D sheet bodies. If those exist, add a factor in that
- // direction. Here we pick 0.25 since when we thicken bodies we do it by
- // 0.2 - thus this should be safe to overlap those thickened bodies
- // completely.
- CubitVector box_min = box.minimum();
- CubitVector box_max = box.maximum();
-
- double f = .25;
-
- if( box_max.x() - box_min.x() < 1e-6 )
- {
- box_min.set( box_min.x()-f, box_min.y(), box_min.z() );
- box_max.set( box_max.x()+f, box_min.y(), box_min.z() );
- }
- if( box_max.y() - box_min.y() < 1e-6 )
- {
- box_min.set( box_min.x(), box_min.y()-f, box_min.z() );
- box_max.set( box_max.x(), box_max.y()+f, box_max.z() );
- }
- if( box_max.z() - box_min.z() < 1e-6 )
- {
- box_min.set( box_min.x(), box_min.y(), box_min.z()-f );
- box_max.set( box_max.x(), box_max.y(), box_max.z()+f );
- }
-
- CubitBox temp_box( box_min, box_max );
- box |= temp_box;
-
- // Scale the box up overall by a factor as well
- box *= 1.25;
-
- // Create sheet bodies (6) at box sides
- CubitVector c[8];
- box.get_corners( c );
-
- // 3+----------+2
- // /| /|
- // / | / |
- // / | / | Y
- // 7+----------+6 | ^
- // | | | | |
- // | 0+------|---+1 |
- // | / | / +---->X
- // | / | / /
- // |/ |/ /
- // 4+----------+5 Z
-
- SPAposition min( box.minimum().x(), box.minimum().y(), box.minimum().z() );
- SPAposition max( box.maximum().x(), box.maximum().y(), box.maximum().z() );
- SPAbox super_box( min, max );
-
- // Note - infinite plane is swept in the opposite direction from the normal
- // of the passed in points
- // Create infinite plane object at the FRONT of the box
- BODY_ptr = AME->create_infinite_plane_cutting_tool( c[6], c[5],
- c[4], super_box, false );
- // Subtract this object from the master (BODY_ptr is deleted)
- result = api_boolean( BODY_ptr, master, SUBTRACTION );
- // Do this for the other 5 sides of the box
- // RIGHT SIDE
- BODY_ptr = AME->create_infinite_plane_cutting_tool( c[6], c[2],
- c[1], super_box, false );
- result = api_boolean( BODY_ptr, master, SUBTRACTION );
- // BACK SIDE
- BODY_ptr = AME->create_infinite_plane_cutting_tool( c[1], c[2],
- c[3], super_box, false );
- result = api_boolean( BODY_ptr, master, SUBTRACTION );
- // LEFT SIDE
- BODY_ptr = AME->create_infinite_plane_cutting_tool( c[0], c[3],
- c[7], super_box, false );
- result = api_boolean( BODY_ptr, master, SUBTRACTION );
- // BOTTOM
- BODY_ptr = AME->create_infinite_plane_cutting_tool( c[0], c[4],
- c[5], super_box, false );
- result = api_boolean( BODY_ptr, master, SUBTRACTION );
- // TOP
- BODY_ptr = AME->create_infinite_plane_cutting_tool( c[3], c[2],
- c[6], super_box, false );
- result = api_boolean( BODY_ptr, master, SUBTRACTION );
-
- // Put original FACEs into a single sheet BODY
- BODY *orig_sheet;
- if( copy_FACEs_into_sheet( FACE_list, orig_sheet )
- == CUBIT_FAILURE )
- {
- api_delent( master );
- return CUBIT_FAILURE;
- }
-
- // Remove FACEs that don't overlap with the original target FACEs
- double overlap_area;
- DLIList<FACE*> master_FACE_list;
- AQE->get_FACEs( master, master_FACE_list );
- master_FACE_list.reset();
- for( i=master_FACE_list.size(); i--; )
- {
- FACE_ptr = master_FACE_list.get_and_step();
-
- // Make a copy of the FACE into a new BODY
- FACE *temp_FACE_ptr = AME->make_FACE( FACE_ptr, CUBIT_FALSE );
- if( temp_FACE_ptr == NULL )
- {
- api_delent( master );
- return CUBIT_FAILURE;
- }
- BODY *temp_BODY_ptr = AQE->get_BODY_of_ENTITY( temp_FACE_ptr );
-
- if( get_overlap_area( temp_BODY_ptr, orig_sheet, overlap_area )
- == CUBIT_FAILURE )
- {
- api_delent( temp_BODY_ptr );
- api_delent( master );
- return CUBIT_FAILURE;
- }
-
- api_delent( temp_BODY_ptr );
-
- if( overlap_area > 1e-5 )
- continue;
- else
- api_remove_face( FACE_ptr );
- }
-
- // Remove any internal holes in the body
- remove_holes( master );
-
- // Clean (regularize) to remove unwanted topology
- api_clean_entity( master );
-
- // Make sure FACE normals are consistent (api_body_to_1d could be used for
- // this, then convert back to double sided). Healing will also work.
- // Ignore return status as this is not fatal.
- heal_BODY( master );
-
- // Set output BODY
- ext_BODY_ptr = master;
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : prep_cutting_sheet
-// Member Type: PRIVATE
-// Description: Prepare the cutting sheet for chopping off the BODY in a
-// tweak_target_multiple operation.
-// Author : Steve Storm
-// Date : 3/18/06
-//=============================================================================
-CubitStatus
-AcisTweakTool::prep_cutting_sheet( BODY *&cutting_sheet,
- BODY *tweaked_BODY_ptr,
- BODY *ext_target_BODY_ptr,
- CubitVector &source_norm,
- CubitVector &target_norm,
- CubitBoolean check_crossing )
-{
- int i, j;
- outcome result;
-
- // Imprint, so as to score the cutting sheet. We have to do this with a
- // copied BODY, since the extended target could cross FACEs we don't want
- // to affect.
- BODY *tweaked_BODY_ptr2 = AME->copy_BODY( tweaked_BODY_ptr, CUBIT_TRUE );
- result = api_imprint( cutting_sheet, tweaked_BODY_ptr2 );
- if( !result.ok() )
- {
- AQE->ACIS_API_error(result);
- api_delent( tweaked_BODY_ptr2 );
- return CUBIT_FAILURE;
- }
- api_delent( tweaked_BODY_ptr2 );
-
- if( check_crossing == CUBIT_TRUE )
- {
- // Throw away individual cutting sheet patches that don't cross the FACEs we
- // want to cut.
- DLIList<FACE*> cut_FACE_list;
- DLIList<FACE*> temp_FACE_list;
- AQE->get_FACEs( tweaked_BODY_ptr, temp_FACE_list );
- FACE *FACE_ptr;
- ATTRIB_GEN_NAME *ret_att;
- for( i=temp_FACE_list.size(); i--; )
- {
- FACE_ptr = temp_FACE_list.get_and_step();
- api_find_named_attribute( FACE_ptr, "tweak", ret_att );
- if( ret_att )
- cut_FACE_list.append( FACE_ptr );
- }
- BODY *cut_FACE_sheet;
- // Note: healing a .2 thick sheet here will collapse the side FACEs out,
- // so we skip healing.
- copy_FACEs_into_sheet( cut_FACE_list, cut_FACE_sheet, CUBIT_FALSE );
-
- // Intersect this sheet with each cutting sheet. NULL or incomplete wires
- // will indicate an invalid crossing.
- BODY **sheets = NULL;
- int n_body = 0;
- result = api_separate_body( cutting_sheet, n_body, sheets );
- if (!result.ok())
- {
- AQE->ACIS_API_error(result);
- api_delent( cut_FACE_sheet );
- return CUBIT_FAILURE;
- }
-
- CubitBoolean good_crossing = CUBIT_FALSE;
- for( i=0; i<n_body; i++ )
- {
- BODY* slice = NULL;
-
- // Create the intersection graph between the given bodies
- result = api_slice( sheets[i], cut_FACE_sheet,
- *(SPAunit_vector *)NULL_REF, slice);
-
- if (!result.ok() || slice == NULL )
- good_crossing = CUBIT_FALSE;
- else
- {
- api_clean_wire( slice );
- int num = 0;
- BODY **wires = NULL;
- result = api_separate_body( slice, num, wires );
- if (!result.ok())
- {
- AQE->ACIS_API_error(result);
- api_delent( slice );
- for( j=0; j<n_body; j++ )
- if( sheets[j] ) api_delent(sheets[j]);
- api_delent( cut_FACE_sheet );
- return CUBIT_FAILURE;
- }
- if( num == 1 )
- good_crossing = CUBIT_TRUE;
- else
- good_crossing = CUBIT_FALSE;
-
- for( j=0; j<num; j++ )
- api_delent( wires[j] );
- }
-
- if( good_crossing == CUBIT_FALSE )
- {
- // Delete this BODY
- api_delent( sheets[i] );
- sheets[i] = NULL;
- }
- }
-
- // Delete the cut_FACE_sheet since we are done with it
- api_delent( cut_FACE_sheet );
-
- // Unite the remaining sheets back into cutting_sheet
- BODY *first_BODY_ptr = NULL;
- DLIList<BODY*> unite_BODY_list;
- for( i=0; i<n_body; i++ )
- {
- if( sheets[i] )
- {
- if( !first_BODY_ptr )
- first_BODY_ptr = sheets[i];
- else
- unite_BODY_list.append( sheets[i] );
- }
- }
- if( !first_BODY_ptr )
- {
- PRINT_ERROR( "Problem intersecting extended surface(s) with target\n" );
- return CUBIT_FAILURE;
- }
- if( unite_BODIES( first_BODY_ptr, unite_BODY_list, cutting_sheet )
- == CUBIT_FAILURE )
- {
- for( i=0; i<n_body; i++ )
- if( sheets[i] ) api_delent( sheets[i] );
- return CUBIT_FAILURE;
- }
- }
-
- // Remove periodic surfaces near nonmanifold EDGEs. Note if any remaining
- // nonmanifold EDGEs exist, this function will return failure (a nonmanifold
- // surface won't work as a cutting sheet). See picture in the function
- // for an example.
- if( remove_per_nonmanifold_FACEs( cutting_sheet ) == CUBIT_FAILURE )
- return CUBIT_FAILURE;
-
- // We need to check the normals on the cutting_sheet now against the normals
- // on the ext_target_BODY_ptr, since we can't be sure what the intersection
- // did with the normals. Unfortunately, we can't use the
- // make_surf_normals_consistent function because we might have disconnected
- // FACEs that are part of the back side of cylinders in the cutting_sheet.
- // If we were to use make_surf_normals_consistent it would align those FACEs
- // normals with the front FACE, and the cutting sheet would be invalid,
- // because the remove_aligned_periodic_FACEs will fail to remove those FACEs.
- // We use a computationally intense method instead.
- if( align_normals( cutting_sheet, ext_target_BODY_ptr ) == CUBIT_FAILURE )
- {
- PRINT_ERROR( "Unable to make target shell normals consistent - invalid target\n" );
- return CUBIT_FAILURE;
- }
-
- // Now remove unwanted periodic FACEs on the back of the cutting sheet. We
- // use the target normal as the basis. Since we worked very hard to keep the
- // normals consisent in relation to the target surfaces the user picked, this
- // will be fairly robust for most cases.
- CubitVector tmp_vec = -target_norm;
- remove_aligned_periodic_FACEs( cutting_sheet, tmp_vec );
-
- // Make sure there are still some FACEs left!
- DLIList<FACE*> cutting_sheet_FACE_list;
- AQE->get_FACEs( cutting_sheet, cutting_sheet_FACE_list );
- if( cutting_sheet_FACE_list.size() == 0 )
- {
- PRINT_ERROR( "Unable to tweak to targets\n" );
- return CUBIT_FAILURE;
- }
-
- // Clean the cutting sheet before using it - remove unnecessary topology -
- // this makes booleans more robust. Ignore result since not fatal.
- result = api_clean_entity( cutting_sheet );
-
- // Also remove any internal holes
- remove_holes( cutting_sheet );
-
- // Sheet direction should ALWAYS be pointing in the opposite direction as the
- // source_norm
- cutting_sheet_FACE_list.clean_out();
- AQE->get_FACEs( cutting_sheet, cutting_sheet_FACE_list );
- CubitVector sheet_norm = weighted_average_FACE_normal( cutting_sheet_FACE_list );
- if( sheet_norm.length() < 1e-12 )
- {
- PRINT_ERROR( "Unable to tweak to given surfaces\n" );
- return CUBIT_FAILURE;
- }
- if( sheet_norm % source_norm > 0.0 )
- api_reverse_body( cutting_sheet );
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : chop_off_with_sheet
-// Member Type: PRIVATE
-// Description: Chop off all the material in a BODY to one side of a sheet
-// body. The material is removed on the side of the sheet body
-// according to the surface normals of the sheet body (material
-// removed in the opposite direction of the surface normals of the
-// sheet body, which must be consistent).
-// Author : Steve Storm
-// Date : 1/29/06
-//=============================================================================
-CubitStatus
-AcisTweakTool::chop_off_with_sheet( BODY *BODY_ptr, BODY *sheet_BODY_ptr )
-{
- outcome result;
-
- // First test to see if these intersect. If they don't nothing will be done.
- if ( !AME->BODYs_interfering( BODY_ptr, sheet_BODY_ptr ) )
- {
- // BODIES don't intersect. Clean up and exit.
- PRINT_WARNING("Cutting sheet does not intersect the original volume.\n");
- return CUBIT_FAILURE;
- }
-
- BODY *copied_sheet_BODY = AME->copy_BODY( sheet_BODY_ptr );
-
- // Set all faces to one sided
- result = api_body_to_1d( copied_sheet_BODY, false );
- if( !result.ok() )
- {
- api_delent( copied_sheet_BODY );
- AQE->ACIS_API_error( result );
- return CUBIT_FAILURE;
- }
-
- // Setup tweak attributes so we can preserve Cubit owners
- DLIList<FACE*> pre_FACE_list;
- DLIList<EDGE*> pre_EDGE_list;
- DLIList<VERTEX*> pre_VERTEX_list;
- DLIList<AcisBridge*> ab_FACE_list, ab_EDGE_list, ab_VERTEX_list;
- assign_tweak_attribs( BODY_ptr, "tweak_own", pre_FACE_list, ab_FACE_list,
- pre_EDGE_list, ab_EDGE_list, pre_VERTEX_list, ab_VERTEX_list );
-
- // Now we simply have to subtract the copied_sheet_BODY from BODY_ptr
- result = api_boolean( copied_sheet_BODY, BODY_ptr, NONREG_SUBTRACTION );
-
- // Replace Cubit owners
- reassign_cubit_owners_from_tweak_attribs( BODY_ptr, "tweak_own",
- pre_FACE_list, ab_FACE_list, pre_EDGE_list, ab_EDGE_list, pre_VERTEX_list,
- ab_VERTEX_list );
-
- // Remove tweak attributes
- remove_named_attribs( BODY_ptr, "tweak_own" );
-
- if( !result.ok() || BODY_ptr->lump() == NULL ||
- !is_closed_solid_body( BODY_ptr ) )
- {
- CubitBoolean is_error = CUBIT_TRUE;
- if( result.ok() &&
- ( BODY_ptr->lump() == NULL ||
- !is_closed_solid_body( BODY_ptr )))
- {
- // This is where the sheet just intersects with the shell
- // of the outside body. Should do nothing here.
- is_error = CUBIT_FALSE;
- }
- if( !result.ok() ) //was already deleted if api_subtract was successfull
- api_delent( copied_sheet_BODY );
-
- if ( is_error )
- {
- if( !result.ok() )
- AQE->ACIS_API_error( result );
- else
- PRINT_ERROR( "problem trimming body\n" );
- }
- else
- {
- // Cutting surfaces graze volume
- PRINT_ERROR( "problem trimming body\n" );
- }
- return CUBIT_FAILURE;
- }
-
- AQE->clear_bounding_box( BODY_ptr );
- AQE->bounding_box( BODY_ptr );
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : get_overlap_area
-// Member Type: PRIVATE
-// Description: Determine the area of overlap of two BODIES. Uses an ACIS
-// intersection boolean so is quite expensive.
-// Author : Steve Storm
-// Date : 2/10/06
-//=============================================================================
-CubitStatus
-AcisTweakTool::get_overlap_area( BODY *BODY_ptr1, BODY *BODY_ptr2,
- double &overlap_area, double accuracy )
-{
- overlap_area = 0.0;
-
- BODY *int_sheet;
- outcome result = api_boolean( BODY_ptr1, BODY_ptr2, INTERSECTION,
- NDBOOL_KEEP_BOTH, int_sheet );
- if( !result.ok() )
- {
- AQE->ACIS_API_error(result);
- return CUBIT_FAILURE;
- }
-
- // Get surface area of int_sheet
- double accur_achieved;
- result = api_ent_area( int_sheet, accuracy, overlap_area, accur_achieved );
- api_delent( int_sheet );
- if( !result.ok() )
- {
- AQE->ACIS_API_error(result);
- return CUBIT_FAILURE;
- }
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : copy_FACEs_into_sheet
-// Member Type: PRIVATE
-// Description: Copies the given FACEs
-// Author : Steve Storm
-// Date : 2/10/06
-//=============================================================================
-CubitStatus
-AcisTweakTool::copy_FACEs_into_sheet( DLIList<FACE*> &FACE_list,
- BODY *&sheet_ptr,
- CubitBoolean heal )
-{
- DLIList<BODY*> temp_BODY_list;
- FACE *FACE_ptr;
- FACE *temp_FACE_ptr;
- BODY *temp_BODY_ptr;
- int i;
- FACE_list.reset();
- for( i=FACE_list.size(); i--; )
- {
- FACE_ptr = FACE_list.get_and_step();
-
- temp_FACE_ptr = AME->make_FACE( FACE_ptr, CUBIT_FALSE );
- if( temp_FACE_ptr == NULL )
- {
- while( temp_BODY_list.size() ) api_delent( temp_BODY_list.pop() );
- return CUBIT_FAILURE;
- }
-
- // Get the BODY this new FACE is in
- temp_BODY_ptr = AQE->get_BODY_of_ENTITY( temp_FACE_ptr );
- if( temp_BODY_ptr == NULL )
- {
- while( temp_BODY_list.size() ) api_delent( temp_BODY_list.pop() );
- return CUBIT_FAILURE;
- }
-
- temp_BODY_list.append( temp_BODY_ptr );
- }
-
- // Unite all of the temp BODIES together
- temp_BODY_list.reset();
- outcome result;
- BODY *master = temp_BODY_list.extract();
- for( i=temp_BODY_list.size(); i--; )
- {
- temp_BODY_ptr = temp_BODY_list.extract();
-
- // Do the union of the master and the BODY_ptr.
- // If this is successful, the result is master and
- // temp_BODY_ptr will be deleted
- result = api_boolean( temp_BODY_ptr, master, UNION );
- if( !result.ok() || (!master) )
- {
- AQE->ACIS_API_error(result);
- api_delent( temp_BODY_ptr );
- while( temp_BODY_list.size() ) api_delent( temp_BODY_list.pop() );
- if (master != NULL) api_delent(master);
- return CUBIT_FAILURE;
- }
- }
-
- // Heal the BODY if required
- if( heal )
- heal_BODY( master );
-
- // Clean (regularize) to remove unwanted topology
- api_clean_entity( master );
-
- sheet_ptr = master;
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : remove_per_nonmanifold_FACEs
-// Member Type: PRIVATE
-// Description: Removes cone, sphere or torus FACEs that are attached to a
-// nonmanifold EDGE. The portion of the periodic that is tangent
-// to the attached FACE is kept.
-// Author : Steve Storm
-// Date : 2/2/06
-//=============================================================================
-CubitStatus
-AcisTweakTool::remove_per_nonmanifold_FACEs( BODY *cutting_tool )
-{
- outcome result;
-
- // List to store FACEs to remove
- DLIList<FACE*> remove_FACE_list;
-
- // Find nonmanifold edges, remove attached periodic surface on side we
- // don't want to keep. We for sure want to remove these faces.
- //
- // Example: Diagram is an end view of a full cylinder with a plane attached.
- // The nonmanifold EDGE is on the right side. In this example we would
- // remove the short portion of the cylinder between the periods.
- // _____
- // / \
- // / \
- // | |
- // | . <-- nonmanifold EDGE (runs along cylinder length here)
- // | |
- // \ /|
- // \ __.__ / |
- // |
- // |
- // |
- // |
-
- // Loop through EDGEs
- DLIList<EDGE*> EDGE_list;
- AQE->get_EDGEs( cutting_tool, EDGE_list );
-
- int i, j;
- EDGE *EDGE_ptr;
- EDGE_list.reset();
- for( i=EDGE_list.size(); i--; )
- {
- EDGE_ptr = EDGE_list.get_and_step();
-
- DLIList<FACE*> FACE_list;
- AQE->get_FACEs( EDGE_ptr, FACE_list );
-
- if( FACE_list.size() < 3 )
- continue;
-
- // EDGE is nonmanifold - it has 3 FACEs attached to it. If two of the
- // FACEs are periodic types and one is not, then we will mark one of the
- // periodic types for deletion.
-
- // We can't handle this case
- if( FACE_list.size() > 3 )
- {
- PRINT_ERROR( "Ill-formed extended target encountered\n" );
- return CUBIT_FAILURE;
- }
-
- // Find the attached periodic surfaces
- FACE *per_FACE_ptr1 = NULL;
- FACE *per_FACE_ptr2 = NULL;
- FACE *other_FACE_ptr = NULL;
- FACE_list.reset();
- for( j=FACE_list.size(); j--; )
- {
- FACE *FACE_ptr = FACE_list.get_and_step();
- SURFACE *SURFACE_ptr = FACE_ptr->geometry();
- int type = SURFACE_ptr->identity();
- if( type==CONE_TYPE || type==SPHERE_TYPE || type== TORUS_TYPE )
- {
- if( per_FACE_ptr1 == NULL ){
- per_FACE_ptr1 = FACE_ptr;
- continue;
- }
-
- if( per_FACE_ptr2 == NULL )
- {
- per_FACE_ptr2 = FACE_ptr;
- continue;
- }
-
- if( per_FACE_ptr1 && per_FACE_ptr2 )
- {
- PRINT_ERROR( "Ill-formed extended target encountered\n" );
- return CUBIT_FAILURE;
- }
- }
- else if( other_FACE_ptr == NULL )
- other_FACE_ptr = FACE_ptr;
- }
-
- if( !(per_FACE_ptr1 && per_FACE_ptr2 && other_FACE_ptr) )
- {
- PRINT_ERROR( "Ill-formed extended target encountered\n" );
- return CUBIT_FAILURE;
- }
-
- // Figure out which periodic to remove. Compare vectors tangent to and
- // pointing away from the FACEs at the middle of the EDGE.
-
- // Get mid position
- SPAposition acis_mid_pnt = EDGE_ptr->mid_pos();
- CubitVector mid_pnt( acis_mid_pnt.x(), acis_mid_pnt.y(), acis_mid_pnt.z() );
-
- CubitVector vec1, vec2, vec3;
- tangent_outdir( per_FACE_ptr1, EDGE_ptr, mid_pnt, vec1 );
- tangent_outdir( per_FACE_ptr2, EDGE_ptr, mid_pnt, vec2 );
- tangent_outdir( other_FACE_ptr, EDGE_ptr, mid_pnt, vec3 );
-
- // FACE that is in same direction as other_FACE gets removed. If angle
- // between vectors is acute (dot product > 0) flag that FACE
- if( vec1 % vec3 > 0.0 )
- remove_FACE_list.append_unique( per_FACE_ptr1 );
- else if( vec2 % vec3 > 0.0 )
- remove_FACE_list.append_unique( per_FACE_ptr2 );
- }
-
- // Remove these FACEs
- for( i=remove_FACE_list.size(); i--; )
- api_remove_face( remove_FACE_list.get_and_step() );
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : tangent_outdir
-// Member Type: PRIVATE
-// Description: Given a FACE, EDGE and position, find the direction that is
-// normal to the EDGE and tangent to the FACE, pointing away from
-// the FACE boundary.
-// Author : Steve Storm
-// Date : 2/18/06
-//=============================================================================
-CubitStatus
-AcisTweakTool::tangent_outdir( FACE *FACE_ptr, EDGE *EDGE_ptr,
- CubitVector &pos, CubitVector &tangent_outvec )
-{
- // Get the normal to the FACE at the position
- SPAposition acis_pos( pos.x(), pos.y(), pos.z() );
- SPAposition acis_pos_on_surf;
- SPAunit_vector acis_face_norm;
- (FACE_ptr->geometry()->equation()).point_perp( acis_pos,
- acis_pos_on_surf, acis_face_norm );
-
- // Adjust for the FACE sense
- if( FACE_ptr->sense() == REVERSED )
- acis_face_norm = -acis_face_norm;
-
- // Get a vector tangent to the EDGE, adjusted for the EDGE sense on the FACE
- SPAunit_vector acis_tangent_vec = (EDGE_ptr->geometry()->equation()).
- point_direction( acis_pos );
- if( EDGE_ptr->sense() == REVERSED )
- acis_tangent_vec = -acis_tangent_vec;
-
- COEDGE *COEDGE_ptr = EDGE_ptr->coedge( FACE_ptr );
- if( COEDGE_ptr->sense() == REVERSED )
- acis_tangent_vec = -acis_tangent_vec;
-
- // Cross edge tangent with face normal to find desired direction
- CubitVector face_norm( acis_face_norm.x(), acis_face_norm.y(),
- acis_face_norm.z() );
- CubitVector tangent_vec( acis_tangent_vec.x(), acis_tangent_vec.y(),
- acis_tangent_vec.z() );
-
- tangent_outvec = tangent_vec * face_norm;
-
- tangent_outvec.normalize();
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : remove_aligned_periodic_FACEs
-// Member Type: PRIVATE
-// Description: Removes cone, sphere or torus FACEs that have normals aligned
-// with the given basis vector.
-// Author : Steve Storm
-// Date : 2/2/06
-//=============================================================================
-CubitStatus
-AcisTweakTool::remove_aligned_periodic_FACEs( BODY *cutting_tool,
- CubitVector &basis_vec )
-{
- outcome result;
- int i;
- CubitVector location;
- DLIList<FACE*> FACE_list;
- AQE->get_FACEs( cutting_tool, FACE_list );
- FACE_list.reset();
- for( i=FACE_list.size(); i--; )
- {
- FACE *FACE_ptr = FACE_list.get_and_step();
-
- SURFACE *SURFACE_ptr = FACE_ptr->geometry();
- int type = SURFACE_ptr->identity();
- if( type==CONE_TYPE || type==SPHERE_TYPE || type== TORUS_TYPE )
- {
- CubitVector FACE_norm = FACE_normal( FACE_ptr, location );
-
- // If dot product greater than zero, angle is acute
- if( FACE_norm % basis_vec > 0.0 )
- {
- result = api_remove_face( FACE_ptr );
- if( !result.ok() )
- {
- AQE->ACIS_API_error( result );
- return CUBIT_FAILURE;
- }
- }
- }
- }
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : heal_BODY
-// Member Type: PRIVATE
-// Description: Convenience function to use the ACIS healer to heal a BODY
-// Author : Steve Storm
-// Date : 2/20/06
-//=============================================================================
-CubitStatus
-AcisTweakTool::heal_BODY( BODY *BODY_ptr )
-{
- outcome result;
- result = api_hh_init_body_for_healing( BODY_ptr );
- if( !result.ok() )
- {
- AQE->ACIS_API_error( result );
- return CUBIT_FAILURE;
- }
-
- result = api_hh_auto_heal( BODY_ptr );
- if( !result.ok() )
- {
- AQE->ACIS_API_error( result );
- api_hh_end_body_for_healing( BODY_ptr );
- return CUBIT_FAILURE;
- }
-
- api_hh_end_body_for_healing( BODY_ptr );
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : align_normals
-// Member Type: PRIVATE
-// Description: Align the normals of the child's FACEs to the master FACEs. It
-// is assumed the child is a subset of the master (i.e., the
-// master is an extended BODY).
-// Author : Steve Storm
-// Date : 2/20/06
-//=============================================================================
-CubitStatus
-AcisTweakTool::align_normals( BODY *child, BODY *master )
-{
- DLIList<FACE*> child_FACE_list;
- AQE->get_FACEs( child, child_FACE_list );
-
- DLIList<FACE*> master_FACE_list;
- AQE->get_FACEs( master, master_FACE_list );
-
- int i;
- CubitVector loc;
- FACE *child_FACE_ptr = NULL;
- for( i=child_FACE_list.size(); i--; )
- {
- child_FACE_ptr = child_FACE_list.get_and_step();
-
- CubitVector child_norm = FACE_normal( child_FACE_ptr, loc );
-
- FACE *master_FACE_ptr = find_overlap_FACE( child_FACE_ptr, master_FACE_list );
-
- if( !master_FACE_ptr )
- return CUBIT_FAILURE;
-
- // Align the normals
- CubitVector master_norm = FACE_normal( master_FACE_ptr, loc, CUBIT_FALSE );
- if( child_norm % master_norm < 0.0 )
- api_reverse_face( child_FACE_ptr );
- }
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : find_overlap_FACE
-// Member Type: PRIVATE
-// Description: Find the FACE in FACE_list that overlaps with FACE_ptr.
-// Returns NULL if no overlap FACE found.
-// Author : Steve Storm
-// Date : 2/20/06
-//=============================================================================
-FACE *
-AcisTweakTool::find_overlap_FACE( FACE *FACE_ptr, DLIList<FACE*> &FACE_list )
-{
- int i;
- BODY *tmp_BODY_ptr1;
- FACE *face_list[1];
- face_list[0] = FACE_ptr;
- api_sheet_from_ff( 1, face_list, tmp_BODY_ptr1 );
- api_body_to_2d( tmp_BODY_ptr1 );
-
- FACE *FACE_ptr2;
- FACE *match_FACE_ptr = NULL;
- double overlap_area;
- for( i=FACE_list.size(); i--; )
- {
- FACE_ptr2 = FACE_list.get_and_step();
- if( !FACE_ptr2 )
- continue;
- BODY *tmp_BODY_ptr2;
- face_list[0] = FACE_ptr2;
- api_sheet_from_ff( 1, face_list, tmp_BODY_ptr2 );
- api_body_to_2d( tmp_BODY_ptr2 );
- get_overlap_area( tmp_BODY_ptr1, tmp_BODY_ptr2, overlap_area );
- api_delent( tmp_BODY_ptr2 );
- if( overlap_area > 1e-5 )
- {
- match_FACE_ptr = FACE_ptr2;
- break;
- }
- }
-
- api_delent( tmp_BODY_ptr1 );
-
- return match_FACE_ptr;
-}
-
-//=============================================================================
-// Function : make_surf_normals_consistent
-// Member Type: PRIVATE
-// Description: Make the surface normals in the given sheet BODY consistent.
-// The optional seed FACE must be part of the BODY. If none is
-// given, a random FACE is selected.
-// Author : Steve Storm
-// Date : 2/20/06
-//=============================================================================
-CubitStatus
-AcisTweakTool::make_surf_normals_consistent( BODY *BODY_ptr,
- FACE *seed_FACE_ptr )
-{
- int i;
- DLIList<FACE*> patch_list;
- DLIList<FACE*> FACE_list;
- AQE->get_FACEs( BODY_ptr, FACE_list );
-
- if( seed_FACE_ptr == NULL )
- seed_FACE_ptr = get_seed_FACE( FACE_list );
-
- api_add_generic_named_attribute( seed_FACE_ptr, "tweak_seed", 1, SplitCopy );
- patch_list.append( seed_FACE_ptr );
-
- int c = 0;
-
- while( patch_list.size() < FACE_list.size() )
- {
- // Find all neighbors. Note patch_list will change size within the loop.
- for( i=c; i<patch_list.size(); i++ )
- {
- if( append_neighbors( patch_list ) == CUBIT_FAILURE )
- {
- remove_named_attribs( BODY_ptr, "tweak_seed" );
- return CUBIT_FAILURE;
- }
-
- patch_list.step();
- }
-
- // Include disconnected FACE patches
- if( patch_list.size() < FACE_list.size() )
- {
- c = patch_list.size();
- ATTRIB_GEN_NAME *ret_att;
- FACE *FACE_ptr;
- DLIList<FACE*> processed_FACE_list;
-
- FACE_list.reset();
- for( i=FACE_list.size(); i--; )
- {
- FACE_ptr = FACE_list.get_and_step();
-
- api_find_named_attribute( FACE_ptr, "tweak_seed", ret_att );
- if( ret_att )
- processed_FACE_list.append( FACE_ptr );
- }
-
- CubitVector avg_norm = weighted_average_FACE_normal( processed_FACE_list );
-
- seed_FACE_ptr = get_seed_FACE( FACE_list );
- api_add_generic_named_attribute( seed_FACE_ptr, "tweak_seed", 1, SplitCopy );
- patch_list.append( seed_FACE_ptr );
-
- CubitVector loc;
- CubitVector seed_norm = FACE_normal( seed_FACE_ptr, loc );
-
- if( seed_norm % avg_norm < 0.0 )
- api_reverse_face( seed_FACE_ptr );
- }
- }
-
- remove_named_attribs( BODY_ptr, "tweak_seed" );
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : append_neighbors
-// Member Type: PRIVATE
-// Description: Helper function for make_surf_normals_consistent
-// Author : Steve Storm
-// Date : 2/20/06
-//=============================================================================
-CubitStatus
-AcisTweakTool::append_neighbors( DLIList<FACE*> &FACE_list )
-{
- int i, j;
- ATTRIB_GEN_NAME *ret_att;
-
- FACE *seed_FACE_ptr = FACE_list.get();
-
- // Get the edges
- DLIList<EDGE*> EDGE_list;
- AQE->get_EDGEs( seed_FACE_ptr, EDGE_list );
-
- EDGE *EDGE_ptr;
- FACE *FACE_ptr;
- COEDGE *seed_COEDGE_ptr;
- for( i=0; i<EDGE_list.size(); i++ )
- {
- EDGE_ptr = EDGE_list.get_and_step();
-
- seed_COEDGE_ptr = EDGE_ptr->coedge( seed_FACE_ptr );
-
- ENTITY_LIST COEDGES;
- api_get_coedges( EDGE_ptr, COEDGES );
- DLIList<COEDGE*> COEDGE_list;
- ENTITY *ENTITY_ptr;
- COEDGES.init();
- while( (ENTITY_ptr = COEDGES.next() ) != NULL )
- COEDGE_list.append( (COEDGE *)ENTITY_ptr );
- COEDGES.clear();
-
- if( COEDGE_list.size() == 1 )
- continue;
- if( COEDGE_list.size() == 2 )
- {
- // Normal case
- COEDGE *COEDGE_ptr2 = COEDGE_list.get_and_step();
- if( COEDGE_ptr2 == seed_COEDGE_ptr )
- COEDGE_ptr2 = COEDGE_list.get();
-
- DLIList<FACE*> temp_FACE_list;
- AQE->get_FACEs( COEDGE_ptr2, temp_FACE_list );
- if( temp_FACE_list.size() > 1 )
- {
- PRINT_ERROR( "Found more than one FACE attached to a COEDGE\n" );
- return CUBIT_FAILURE;
- }
- FACE_ptr = temp_FACE_list.get();
-
- // Don't consider FACEs that are already in the list
- api_find_named_attribute( FACE_ptr, "tweak_seed", ret_att );
- if( ret_att )
- continue;
-
- // If the sense's are the same, the FACE needs to be reversed
- if( seed_COEDGE_ptr->sense() == COEDGE_ptr2->sense() )
- api_reverse_face( FACE_ptr );
-
- FACE_list.append( FACE_ptr );
- api_add_generic_named_attribute( FACE_ptr, "tweak_seed", 1, SplitCopy );
- }
- else if( COEDGE_list.size() == 3 )
- {
- // Nonmanifold. Check for special case - periodic surface intersecting
- // (usually tangent) another surface. For now don't allow any other
- // special cases.
-
- // Find the attached periodic surfaces
- FACE *FACE_ptr2 = NULL;
- int num_per = 0;
- DLIList<FACE*> attached_FACE_list;
- AQE->get_FACEs( EDGE_ptr, attached_FACE_list );
- attached_FACE_list.reset();
- for( j=attached_FACE_list.size(); j--; )
- {
- FACE_ptr = attached_FACE_list.get_and_step();
- SURFACE *SURFACE_ptr = FACE_ptr->geometry();
- int type = SURFACE_ptr->identity();
- if( type==CONE_TYPE || type==SPHERE_TYPE || type== TORUS_TYPE )
- num_per++;
-
- if( FACE_ptr == seed_FACE_ptr )
- continue;
-
- api_find_named_attribute( FACE_ptr, "tweak_seed", ret_att );
- if( ret_att )
- continue;
-
- FACE_ptr2 = FACE_ptr;
- }
-
- if( FACE_ptr2 == NULL )
- continue;
- else if( attached_FACE_list.size() == 2 && num_per != 1 )
- {
- PRINT_ERROR( "Extended target cannot contain nonmanifold geometry\n" );
- return CUBIT_FAILURE;
- }
- else if( attached_FACE_list.size() == 3 && num_per != 2 )
- {
- PRINT_ERROR( "Extended target cannot contain nonmanifold geometry\n" );
- return CUBIT_FAILURE;
- }
-
- // Compare normal vectors at the mid position of the EDGE
-
- // Get mid position
- SPAposition acis_mid_pnt = EDGE_ptr->mid_pos();
- CubitVector mid_pnt( acis_mid_pnt.x(), acis_mid_pnt.y(), acis_mid_pnt.z() );
-
- CubitVector vec_seed, vec2;
- vec_seed = FACE_normal( seed_FACE_ptr, mid_pnt, CUBIT_FALSE );
- vec2 = FACE_normal( FACE_ptr2, mid_pnt, CUBIT_FALSE );
-
- // Check angle between FACEs
- if( vec_seed % vec2 < 0.0 )
- api_reverse_face( FACE_ptr2 );
-
- FACE_list.append( FACE_ptr2 );
- api_add_generic_named_attribute( FACE_ptr2, "tweak_seed", 1, SplitCopy );
- }
- else if( COEDGE_list.size() > 3 )
- {
- PRINT_ERROR( "Extended target cannot contain nonmanifold geometry\n" );
- return CUBIT_FAILURE;
- }
- else
- {
- PRINT_ERROR( "Targets appear to be ill-formed\n" );
- return CUBIT_FAILURE;
- }
- }
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : get_seed_FACE
-// Member Type: PRIVATE
-// Description: Get a seed FACE from the given list of FACEs. Only a seed FACE
-// without a named "tweak_seed" attribute on it will be returned.
-// Also, it may not be of advantage, but we try to find a FACE that
-// is not of type CONE, TORUS or SPHERE. If that is not possible,
-// we just return the first FACE in the list with no "tweak_seed"
-// attribute on it.
-// Author : Steve Storm
-// Date : 2/20/06
-//=============================================================================
-FACE *
-AcisTweakTool::get_seed_FACE( DLIList<FACE*> &FACE_list )
-{
- int i;
- FACE *seed_FACE_ptr = NULL;
- ATTRIB_GEN_NAME *ret_att;
-
- // Attempt to get a non-periodic seed FACE first
- FACE *FACE_ptr;
- FACE_list.reset();
- for( i=FACE_list.size(); i--; )
- {
- FACE_ptr = FACE_list.get_and_step();
- SURFACE *SURFACE_ptr = FACE_ptr->geometry();
- int type = SURFACE_ptr->identity();
- if( type==CONE_TYPE || type==SPHERE_TYPE || type== TORUS_TYPE )
- continue;
-
- api_find_named_attribute( FACE_ptr, "tweak_seed", ret_att );
-
- if( ret_att )
- continue;
-
- seed_FACE_ptr = FACE_ptr;
- break;
- }
-
- if( seed_FACE_ptr == NULL )
- {
- FACE_list.reset();
- for( i=FACE_list.size(); i--; )
- {
- FACE_ptr = FACE_list.get_and_step();
-
- api_find_named_attribute( FACE_ptr, "tweak_seed", ret_att );
-
- if( ret_att )
- continue;
-
- seed_FACE_ptr = FACE_ptr;
- break;
- }
- }
-
- return seed_FACE_ptr;
-}
-
-//=============================================================================
-// Function : draw_tweak_preview_omt
-// Member Type: PRIVATE
-// Description: Draw the preview EDGEs for tweak offset, move and target. The
-// method is to draw:
-// For sheet bodies:
-// -----------------
-// - EDGEs without owners and EDGEs attached to them
-// - EDGEs attached to given (by owner attribute) EDGEs
-// For solids:
-// -----------
-// - EDGEs on FACEs without owners and EDGEs attached to them
-// - EDGEs attached to given (by owner attribute) FACEs
-//
-// Author : Steve Storm
-// Date : 2/20/06
-//=============================================================================
-CubitStatus
-AcisTweakTool::draw_tweak_preview_omt( BODY *BODY_ptr,
- CubitBoolean flush,
- DLIList<AcisBridge*> *ab_list )
-{
- DLIList<FACE*> FACE_list;
- AQE->get_FACEs( BODY_ptr, FACE_list );
- if( !FACE_list.size() )
- return CUBIT_FAILURE;
-
- int i, j, k;
- DLIList<EDGE*> draw_EDGE_list;
- AcisBridge *ab_ptr = NULL;
- EDGE *EDGE_ptr;
-
- FACE *FACE_ptr = FACE_list.get_and_step();
- if( FACE_ptr->sides() == DOUBLE_SIDED )
- {
- // Sheet BODY
- // Draw EDGEs attached to EDGEs without Cubit owner attributes on them -
- // - this will draw the targets and "side" EDGEs too.
- // Note special case where we need to check if source and/or target still
- // exists - source could be tweaked to an existing EDGE on the same BODY.
- // For some reason the resulting EDGE at the target location inherits the
- // owner attributes of the target EDGE.
- DLIList<EDGE*> EDGE_list;
- AQE->get_EDGEs( BODY_ptr, EDGE_list );
-
- for( i=EDGE_list.size(); i--; )
- {
- EDGE_ptr = EDGE_list.get_and_step();
- ab_ptr = ATTRIB_CUBIT_OWNER::cubit_owner( EDGE_ptr );
- if( !ab_ptr || (ab_list && ab_list->is_in_list( ab_ptr )) )
- {
- // Get VERTICEs on this EDGE
- DLIList<VERTEX*> VERTEX_list;
- AQE->get_VERTICEs( EDGE_ptr, VERTEX_list );
-
- VERTEX *VERTEX_ptr;
- for( j=VERTEX_list.size(); j--; )
- {
- VERTEX_ptr = VERTEX_list.get_and_step();
- DLIList<EDGE*> att_EDGE_list;
- AQE->get_EDGEs( VERTEX_ptr, att_EDGE_list );
-
- for( k=att_EDGE_list.size(); k--; )
- {
- EDGE_ptr = att_EDGE_list.get_and_step();
- draw_EDGE_list.append_unique( EDGE_ptr );
- }
- }
- }
- }
- }
- else
- {
- // Solid BODY
- // Draw EDGEs attached to FACEs without Cubit owner attributes on them -
- // - this will draw the targets and "side" EDGEs too.
- // Note special case where we need to check if source still exists - source
- // could be tweaked to an existing FACE on the same BODY. For some reason
- // the resulting FACE at the target location inherits the owner attributes
- // of one of the source FACEs.
- for( i=FACE_list.size(); i--; )
- {
- FACE_ptr = FACE_list.get_and_step();
- ab_ptr = ATTRIB_CUBIT_OWNER::cubit_owner( FACE_ptr );
- if( !ab_ptr || (ab_list && ab_list->is_in_list( ab_ptr )) )
- {
- // Get VERTICEs on this FACE
- DLIList<VERTEX*> VERTEX_list;
- AQE->get_VERTICEs( FACE_ptr, VERTEX_list );
-
- VERTEX *VERTEX_ptr;
- for( j=VERTEX_list.size(); j--; )
- {
- VERTEX_ptr = VERTEX_list.get_and_step();
- DLIList<EDGE*> EDGE_list;
- AQE->get_EDGEs( VERTEX_ptr, EDGE_list );
-
- for( k=EDGE_list.size(); k--; )
- {
- EDGE_ptr = EDGE_list.get_and_step();
- draw_EDGE_list.append_unique( EDGE_ptr );
- }
- }
- }
- }
- }
-
- for( i=draw_EDGE_list.size(); i--; )
- {
- EDGE_ptr = draw_EDGE_list.get_and_step();
- AcisDrawTool::instance()->draw_EDGE( EDGE_ptr, CUBIT_BLUE );
- }
-
- if( flush )
- GfxPreview::flush();
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : tag_tweak_remove_faces_for_preview
-// Member Type: PRIVATE
-// Description: Add an attribute ("tweak_preview") to the required FACEs for a
-// tweak remove. For the preview we draw the EDGEs on the
-// surviving FACEs adjoining those that are removed. Input is the
-// copied BODY, along with the FACEs being removed.
-// Author : Steve Storm
-// Date : 2/20/06
-//=============================================================================
-CubitStatus
-AcisTweakTool::tag_tweak_remove_FACEs_for_preview( BODY *BODY_ptr,
- DLIList<FACE*> &remove_FACE_list )
-{
- // Add an attribute to adjoining FACEs we are removing. Then we can
- // draw these FACEs for the preview. Don't worry about putting
- // attributes on the FACEs we are removing since these FACEs won't exist
- // when we are done anyway.
- int i, j, k;
- FACE *FACE_ptr;
- ATTRIB_GEN_NAME *ret_att;
- for( i=remove_FACE_list.size(); i--; )
- {
- FACE_ptr = remove_FACE_list.get_and_step();
- DLIList<EDGE*> EDGE_list;
- AQE->get_EDGEs( FACE_ptr, EDGE_list );
-
- EDGE *EDGE_ptr;
- for( j=EDGE_list.size(); j--; )
- {
- EDGE_ptr = EDGE_list.get_and_step();
- DLIList<FACE*> att_FACE_list;
- AQE->get_FACEs( EDGE_ptr, att_FACE_list );
-
- for( k=att_FACE_list.size(); k--; )
- {
- FACE_ptr = att_FACE_list.get_and_step();
-
- api_find_named_attribute( FACE_ptr, "tweak_preview", ret_att );
- if( !ret_att )
- api_add_generic_named_attribute( FACE_ptr, "tweak_preview", 1, SplitCopy );
- }
- }
- }
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : tag_tweak_remove_faces_for_preview
-// Member Type: PRIVATE
-// Description: Add an attribute ("tweak_preview") to the required FACEs for a
-// tweak remove. For the preview we draw the EDGEs on the
-// surviving FACEs adjoining those that are removed. Input is the
-// copied BODY, along with the FACEs being removed.
-// Author : Steve Storm
-// Date : 2/20/06
-//=============================================================================
-CubitStatus
-AcisTweakTool::tag_tweak_remove_FACEs_for_preview( BODY *BODY_ptr,
- DLIList<EDGE*> &remove_EDGE_list )
-{
- // Add an attribute to adjoining FACEs we are removing. Then we can
- // draw these FACEs for the preview.
- int i, j;
- EDGE *EDGE_ptr;
- FACE *FACE_ptr;
- ATTRIB_GEN_NAME *ret_att;
- for( i=remove_EDGE_list.size(); i--; )
- {
- EDGE_ptr = remove_EDGE_list.get_and_step();
- DLIList<FACE*> att_FACE_list;
- AQE->get_FACEs( EDGE_ptr, att_FACE_list );
-
- for( j=att_FACE_list.size(); j--; )
- {
- FACE_ptr = att_FACE_list.get_and_step();
-
- api_find_named_attribute( FACE_ptr, "tweak_preview", ret_att );
- if( !ret_att )
- api_add_generic_named_attribute( FACE_ptr, "tweak_preview", 1, SplitCopy );
- }
- }
-
- return CUBIT_SUCCESS;
-}
-
-//=============================================================================
-// Function : draw_tweak_preview_tagged_FACEs
-// Member Type: PRIVATE
-// Description: Draw EDGEs on FACEs with the "tweak_preview" attribute on them.
-// Author : Steve Storm
-// Date : 2/20/06
-//=============================================================================
-CubitStatus
-AcisTweakTool::draw_tweak_preview_tagged_FACEs( BODY *BODY_ptr,
- CubitBoolean flush )
-{
- int i, j;
- FACE *FACE_ptr;
- ATTRIB_GEN_NAME *ret_att;
- DLIList<EDGE*> draw_EDGE_list;
- DLIList<FACE*> FACE_list;
- AQE->get_FACEs( BODY_ptr, FACE_list );
- for( i=FACE_list.size(); i--; )
- {
- FACE_ptr = FACE_list.get_and_step();
- api_find_named_attribute( FACE_ptr, "tweak_preview", ret_att );
- if( ret_att )
- {
- api_remove_generic_named_attribute( FACE_ptr, "tweak_preview" );
-
- DLIList<EDGE*> EDGE_list;
- AQE->get_EDGEs( FACE_ptr, EDGE_list );
-
- for( j=EDGE_list.size(); j--; )
- draw_EDGE_list.append_unique( EDGE_list.get_and_step() );
- }
- }
-
- for( i=draw_EDGE_list.size(); i--; )
- AcisDrawTool::instance()->draw_EDGE( draw_EDGE_list.get_and_step(),
- CUBIT_BLUE );
-
- if( flush )
- GfxPreview::flush();
-
- return CUBIT_SUCCESS;
-}
-
-
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisTweakTool.hpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisTweakTool.hpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/AcisTweakTool.hpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -11,9 +11,13 @@
class Surface;
class SurfaceACIS;
class BodySM;
+class EDGE;
+class FACE;
class BODY;
class AcisBridge;
class CubitPlane;
+class CubitString;
+class CubitBox;
class AcisQueryEngine;
class AcisModifyEngine;
template <class X> class DLIList;
@@ -30,28 +34,44 @@
static AcisTweakTool* instance();
//- Gives access to the singleton object of this class
+ virtual CubitStatus tweak_bend( DLIList<BodySM*> &bend_bodies,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitVector& neutral_root,
+ CubitVector& bend_axis,
+ CubitVector& bend_direction,
+ double radius,
+ double angle,
+ DLIList<CubitVector*> bend_regions,
+ double width = -1,
+ CubitBoolean center_bend = CUBIT_FALSE,
+ int num_points = 0,
+ CubitBoolean keep_old_body = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE);
+ /**< Bend solid bodies based on a bend radius and angle.
+ */
+
virtual CubitStatus tweak_chamfer( DLIList<Curve*> &curve_list,
- double left_offset,
- DLIList<BodySM*> &new_bodysm_list,
- double right_offset = -1.0,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
- /**< Chamfer curves on solid bodies. The left and right offsets are with
- * respect to the curve direction. If the given right offset is negative,
- * the left offset is used. Users can preview to clarify the meaning of
- * left and right.
+ double left_offset,
+ DLIList<BodySM*> &new_bodysm_list,
+ double right_offset = -1.0,
+ CubitBoolean keep_old_body = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE );
+ /**< Chamfer curves on solid or sheet bodies. The left and right offsets
+ * are with respect to the curve direction. If the given right offset is
+ * negative, the left offset is used. Users can preview to clarify the
+ * meaning of left and right.
*/
virtual CubitStatus tweak_chamfer( DLIList<Point*> &point_list,
- double offset1,
- DLIList<BodySM*> &new_bodysm_list,
- Curve *edge1 = NULL,
- double offset2 = -1.0,
- Curve *edge2 = NULL,
- double offset3 = -1.0,
- Curve *edge3 = NULL,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
+ double offset1,
+ DLIList<BodySM*> &new_bodysm_list,
+ Curve *edge1 = NULL,
+ double offset2 = -1.0,
+ Curve *edge2 = NULL,
+ double offset3 = -1.0,
+ Curve *edge3 = NULL,
+ CubitBoolean keep_old_body = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE );
/**< Chamfer vertices on solid or sheet bodies. On a solid body there can
* be up to 3 offsets; on a sheet body up to 2 offsets. The offsets are
* in the direction of the supplied edges. If multiple vertices are
@@ -59,72 +79,91 @@
*/
virtual CubitStatus tweak_fillet( DLIList<Curve*> &curve_list,
- double radius,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
- /**< Create a round fillet (or blend) at the given curves on solid bodies.
+ double radius,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean keep_old_body = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE );
+ /**< Create a round fillet (or blend) at the given curves on solid or sheet
+ * bodies.
*/
virtual CubitStatus tweak_fillet( Curve *curve_ptr,
- double start_radius,
- double end_radius,
- BodySM *&new_body_ptr,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
- /**< Create a round fillet (or blend) at the given curve on a solid body.
- * The fillet has a variable radius from the start to the end of the curve.
+ double start_radius,
+ double end_radius,
+ BodySM *&new_body_ptr,
+ CubitBoolean keep_old_body = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE );
+ /**< Create a round fillet (or blend) at the given curve on a solid or sheet
+ * body. The fillet has a variable radius from the start to the end of
+ * the curve.
*/
virtual CubitStatus tweak_fillet( DLIList<Point*> &point_list,
- double radius,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
+ double radius,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean keep_old_body = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE );
/**< Create a round fillet (or blend) at the given vertices on sheet bodies.
*/
virtual CubitStatus tweak_move( DLIList<Surface*> &surface_list,
- const CubitVector &delta,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
+ const CubitVector &delta,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean keep_old_body = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE );
/**< Tweak specified faces of a volume or volumes along a vector.
*/
virtual CubitStatus tweak_move( DLIList<Curve*> &curve_list,
- const CubitVector &delta,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
+ const CubitVector &delta,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean keep_old_body = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE );
/**< Tweak specified curves of a sheet body along a vector.
*/
virtual CubitStatus tweak_offset( DLIList<Surface*> &surface_list,
- double offset_distance,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
+ double offset_distance,
+ DLIList<Surface*> *add_surface_list_ptr,
+ DLIList<double> *add_offset_list_ptr,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean keep_old_body = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE );
/**< Tweak specified faces of a volume or volumes by offsetting those faces
- * by the offset distance.
+ * by the offset distance(s).
*/
+ virtual CubitStatus make_offset_sheet( DLIList<Surface*> &surface_list,
+ double def_offset,
+ DLIList<Surface*> *add_surface_list_ptr,
+ DLIList<double> *add_offset_list_ptr,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean preview = CUBIT_FALSE );
+ /**< Create a sheet body (or bodies) by offsetting the given surfaces.
+ * Different surfaces can have different offsets. Adjoining surfaces are
+ * extended or trimmed to remain joined in the new sheet body. Radial
+ * surfaces that cannot be so offset are removed and the resulting wound
+ * healed by the surrounding surfaces. The input surfaces can be from
+ * different bodies. Newly created sheet bodies are separated.
+ */
+
virtual CubitStatus tweak_offset( DLIList<Curve*> &curve_list,
- double offset_distance,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
+ double offset_distance,
+ DLIList<Curve*> *add_curve_list_ptr,
+ DLIList<double> *add_offset_list_ptr,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean keep_old_body = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE );
/**< Tweak specified curves of a sheet body or bodies by offsetting those
- * curves by the offset distance.
+ * curves by the offset distance(s).
*/
virtual CubitStatus tweak_remove( DLIList<Surface*> &surface_list,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean extend_adjoining = CUBIT_TRUE,
- CubitBoolean keep_surface = CUBIT_FALSE,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
- /**< Remove surfaces from a body or bodies and then by default extend
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean extend_adjoining = CUBIT_TRUE,
+ CubitBoolean keep_old_body = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE );
+ /**< Remove surfaces from solid or sheet bodies and then by default extend
* the adjoining surfaces to fill the gap or remove the hole. This
* requires functionality from the ACIS local operations husk. This
* capability can usually successfully remove fillets, chamfers, blind
@@ -132,50 +171,112 @@
*/
virtual CubitStatus tweak_remove( DLIList<Curve*> &curve_list,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean keep_old_body = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE );
/**< Remove curves from a sheet body or bodies and then extend the remaining
* curves to fill the gap. If an internal loop of curves is removed the
* hole is removed.
*/
virtual CubitStatus tweak_target( DLIList<Surface*> &surface_list,
- DLIList<Surface*> &target_surf_list,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean reverse_flg = CUBIT_FALSE,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
+ DLIList<Surface*> &target_surf_list,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean extend_flg = CUBIT_TRUE,
+ CubitPlane *limit_plane = NULL,
+ CubitBoolean reverse_flg = CUBIT_FALSE,
+ CubitBoolean keep_old_body = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE );
/**< Tweak specified faces of a volume or volumes up to a set of target
* surfaces. Topology is tweaked to the target surfaces. Think of this
* as extending/trimming the body up past the target surfaces, then
* webcutting it off with the extended target surfaces and throwing away
- * the excess. The reverse flag should never be needed - if it is, there
- * may be a bug or a bad normal on a body (i.e., negative volume body).
+ * the excess. If extend flag is true, extend out the targets before
+ * tweaking to them (only valid for multiple targets). The optional limit
+ * plane is only valid if extend_flg is TRUE; it will limit the tweak to
+ * not go past this plane in the case where the tweaked body would only
+ * partially intersect the extended targets. The reverse flag should
+ * never be needed - if it is, there may be a bug or a bad normal on a
+ * body (i.e., negative volume body), and is only retained for
+ * debugging.
*/
virtual CubitStatus tweak_target( DLIList<Curve*> &curve_list,
- DLIList<Surface*> &target_surf_list,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean reverse_flg = CUBIT_FALSE,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
+ DLIList<Surface*> &target_surf_list,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean extend_flg = CUBIT_TRUE,
+ CubitPlane *limit_plane = NULL,
+ CubitBoolean reverse_flg = CUBIT_FALSE,
+ CubitBoolean keep_old_body = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE,
+ double max_area_increase = 0 );
/**< Tweak specified edges of a surface or set of surfaces (in sheet bodies)
* up to a set of target surfaces. This essentially extends or trims the
- * attached surfaces of the sheet body.
+ * attached surfaces of the sheet body. If extend flag is true, extend
+ * out the targets before tweaking to them (only valid for multiple
+ * targets). The optional limit plane is only valid if extend_flg is
+ * TRUE; it will limit the tweak to not go past this plane in the case
+ * where the tweaked body would only partially intersect the extended
+ * targets. The reverse flag should never be needed - if it is, there may
+ * be a bug or a bad normal on a body (i.e., negative volume body), and is
+ * only retained for debugging.
*/
virtual CubitStatus tweak_target( DLIList<Curve*> &curve_list,
- DLIList<Curve*> &target_curve_list,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean reverse_flg = CUBIT_FALSE,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
+ DLIList<Curve*> &target_curve_list,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean extend_flg = CUBIT_TRUE,
+ CubitPlane *limit_plane = NULL,
+ CubitBoolean reverse_flg = CUBIT_FALSE,
+ CubitBoolean keep_old_body = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE,
+ double max_area_increase = 0 );
/**< Tweak specified edges of a sheet body or bodies up to a set of target
* curves that are part of a sheet body. The target is a set of surfaces
- * created by thickening the owning surfaces of the target curves.
+ * created by thickening the owning surfaces of the target curves. If
+ * extend flag is true, extend out the targets before tweaking to them
+ * (only valid for multiple targets). The optional limit plane is only
+ * valid if extend_flg is TRUE; it will limit the tweak to not go past
+ * this plane in the case where the tweaked body would only partially
+ * intersect the extended targets. The reverse flag should never be
+ * needed - if it is, there may be a bug or a bad normal on a body (i.e.,
+ * negative volume body), and is only retained for debugging.
*/
+ virtual CubitStatus tweak_target( Point *point_ptr,
+ DLIList<Surface*> &modify_surface_list,
+ CubitVector &target_loc,
+ BodySM *&new_bodysm_ptr,
+ CubitBoolean keep_old_body = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE );
+ /**< Tweak specified vertex of a sheet body to a given location. The
+ * given vertex must be part of a planar surface or surfaces attached to
+ * linear curves only. The user specified which of those surfaces to
+ * actually modify. The given location will be projected to be on the
+ * given planar surface(s) before being used - this projected location
+ * must be the same on all surfaces.
+ */
+
+ virtual CubitStatus make_extended_sheet( DLIList<FACE*> &FACE_list,
+ BODY *&ext_BODY_ptr,
+ CubitBox *clip_box_ptr = NULL,
+ bool suppress_errors = false);
+ /**< Extend out a set of FACEs and place into a new sheet BODY. Holes are
+ * removed and the BODY is healed for consistent FACE normals. The BODY
+ * is also regularized. Note this can result in a nonmanifold sheet,
+ * especially if it contains cylindrical FACEs as they turn into full
+ * cylinders. The resultant BODY can be optionally clipped by the given
+ * bounding box. NOTE: this function should be moved to AME, but it was
+ * easy to expose here, so this is left for the future.
+ */
+
+ virtual CubitStatus remove_topology( DLIList<Curve*> &curve_list,
+ DLIList<Surface*> &surface_list,
+ double backoff_distance,
+ double small_edge_size,
+ DLIList<BodySM*> &new_bodysm_list,
+ CubitBoolean preview );
+
protected:
AcisTweakTool();
//- Class Constructor. (Not callable by user code. Class is constructed
@@ -183,555 +284,37 @@
private:
- CubitStatus tweak_target_single( DLIList<Surface*> &surface_list,
- Surface *target_surf_ptr,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean reverse_flg = CUBIT_FALSE,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
- /**< Tweak specified faces of a volume or volumes up to a single target
- * surface. Topology is tweaked to the target surface. Think of this
- * as extending/trimming the body up past the target surface, then
- * webcutting it off with the extended target surface and throwing away
- * the excess. The reverse flag should never be needed - if it is, there
- * may be a bug or a bad normal on a body (i.e., negative volume body).
- */
+ virtual CubitBoolean set_silent( CubitBoolean flg );
+ //- Set the silent flag for certain messages, so that a thicken can be
+ //- retried and a tweak-target-multiple can be retried without printing
+ //- messages or incrementing the error count for the first try. This
+ //- was implemented in this manner in the hopes that a global silence
+ //- method will someday be implemented in UserInterface or CubitMessage.
+ //- Functions using this method will precede their messages with the
+ //- MSG macro, for a somewhat nonintrusive way to implement. Here are
+ //- the functions that use this: align_normals, append_neighbors
+ //- chop_off_with_sheet, copy_FACEs_into_sheet, create_offset_planar_body,
+ //- extrema_pln_BODY, find_overlap_FACE, get_overlap_area, get_seed_FACE,
+ //- heal_BODY, make_surf_normals_consistent, prep_cutting_sheet,
+ //- prep_for_surface_swap, remove_aligned_periodic_FACEs,
+ //- remove_per_nonmanifold_FACEs, thicken_BODY, tweak_FACEs_to_target,
+ //- tweak_target_multiple, weighted_average_FACE_normal
- CubitStatus tweak_target_multiple( DLIList<Surface*> &surface_list,
- DLIList<Surface*> &target_surf_list,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean reverse_flg = CUBIT_FALSE,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
- /**< Tweak specified faces of a volume or volumes up to a set of target
- * surfaces. Topology is tweaked to the target surfaces. Think of this
- * as extending/trimming the body up past the target surfaces, then
- * webcutting it off with the extended target surfaces and throwing away
- * the excess. The reverse flag should never be needed - if it is, there
- * may be a bug or a bad normal on a body (i.e., negative volume body).
- */
- CubitStatus tweak_target_single( DLIList<Curve*> &curve_list,
- Surface *target_surf_ptr,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean reverse_flg = CUBIT_FALSE,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
- /**< Tweak specified edges of a surface or set of surfaces (in sheet bodies)
- * up to a single target surface. This essentially extends or trims the
- * attached surfaces of the sheet body.
- */
- CubitStatus tweak_target_multiple( DLIList<Curve*> &curve_list,
- DLIList<Surface*> &target_surf_list,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean reverse_flg = CUBIT_FALSE,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
- /**< Tweak specified edges of a surface or set of surfaces (in sheet bodies)
- * up to a set of target surfaces. This essentially extends or trims the
- * attached surfaces of the sheet body.
- */
-
- CubitStatus tweak_target_single( DLIList<Curve*> &curve_list,
- Curve *target_curve_ptr,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean reverse_flg = CUBIT_FALSE,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
- /**< Tweak specified edges of a sheet body or bodies up to a single target
- * curve that is part of a sheet body. The target is a surface created
- * by thickening the owning surface of the target curve.
- */
-
- CubitStatus tweak_target_multiple( DLIList<Curve*> &curve_list,
- DLIList<Curve*> &target_curve_list,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean reverse_flg = CUBIT_FALSE,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
- /**< Tweak specified edges of a sheet body or bodies up to a set of target
- * curves that are part of a sheet body. The target is a set of surfaces
- * created by thickening the owning surfaces of the target curves.
- */
-
- CubitStatus tweak_target_multiple( DLIList<FACE*> &source_FACE_list,
- DLIList<FACE*> &target_FACE_list,
- BODY *ext_target_BODY_ptr,
- DLIList<BodySM*> &debug_BodySM_list,
- CubitBoolean reverse_flg = CUBIT_FALSE );
- //- Tweak target multiple workhorse function. The source FACE list must be
- //- from a single BODY. The target FACE list can be from multiple BODIES.
- //- The ext_target_BODY_ptr is passed in - you can create it from the targets
- //- by using the function "create_extended_sheet" (it is passed in instead of
- //- created in this function for efficiency since this function is likely
- //- called inside of a loop for multiple source BODIEs). The debug_BodySM_list
- //- is populated with debug BODIES if the debug flag 167 is turned on.
-
- CubitStatus get_ACIS_surfaces( DLIList<Surface*> &surface_list,
- DLIList<SurfaceACIS*> &acis_list );
- //- Get SurfaceACISs from Surfaces
-
- CubitStatus get_FACEs( DLIList<Surface*> &surface_list,
- DLIList<FACE*> &FACE_list );
- //- Get FACEs from Surfaces
-
- CubitStatus get_EDGEs( DLIList<Curve*> &curve_list,
- DLIList<EDGE*> &EDGE_list );
- //- Get EDGEs from Curves
-
- CubitStatus get_VERTICEs( DLIList<Point*> &point_list,
- DLIList<VERTEX*> &VERTEX_list );
- //- Get VERTICEs from Points
-
- CubitStatus tweak_target_single( DLIList<EDGE*> &input_EDGE_list,
- FACE *target_FACE_ptr,
- DLIList<BodySM*> &new_body_list,
- CubitBoolean reverse_flg = CUBIT_FALSE,
- CubitBoolean keep_old_bodies = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE,
- DLIList<AcisBridge*> *t_ab_list = NULL );
- //- Tweak EDGES workhorse function. Note this function will return SUCCESS
- //- if any new bodies were created (i.e., it could fail on some and still
- //- return SUCCESS). Last argument is needed for preview - if target was
- //- derived from an EDGE send in the AcisBridge of that EDGE - preview
- //- needs to know about this EDGE if it exists on the input BODY itself.
-
- CubitStatus tweak_target_multiple( DLIList<EDGE*> &input_EDGE_list,
- DLIList<FACE*> &target_FACE_list,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean reverse_flg = CUBIT_FALSE,
- CubitBoolean keep_old_bodies = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE,
- DLIList<AcisBridge*> *t_ab_list = NULL );
- //- Tweak EDGES to multiple FACEs workhorse function. Note this function
- //- will return SUCCESS if any new bodies were created (i.e., it could fail
- //- on some and still return SUCCESS). Last argument is needed for preview -
- //- if targets were derived from an EDGE list send in the AcisBridges of
- //- those EDGEs - it is possible (unlikely though) that these EDGEs (if
- //- part of the BODY itself) could exist in the final result and are needed
- //- for the preview.
-
- CubitStatus get_thickened_BODIES_of_EDGES( const char *command_name,
- DLIList<EDGE*> &EDGE_list,
- DLIList<EDGE*> &removed_EDGE_list,
- BODY *&common_BODY_ptr,
- DLIList<BODY*> &thickened_BODY_list,
- DLIList<DLIList<EDGE*>*> &output_EDGE_lists,
- DLIList<DLIList<FACE*>*> &output_FACE_lists,
- DLIList<DLIList<FACE*>*> &conjugate_FACE_lists,
- double thickness = 0.2 );
- //- Get thickened BODIES from an input list of EDGEs. This function can be
- //- called multiple times on the same list of EDGEs - each time, the EDGEs
- //- from the common body that is thickened are removed from the input EDGE
- //- list. The thickened BODIES are copied from the sheet the EDGEs are
- //- attached to (multiple BODIES can be returned because the returned
- //- thickened BODIES must be nonmanifold). For each BODY returned, also
- //- output a list of EDGES (corresponding to the original input EDGEs), a
- //- list of FACEs (corresponding to the original FACEs of the input BODY)
- //- and a list of conjugate FACEs (the "side" FACEs of the thickened BODY -
- //- these are the FACEs we can tweak).
-
- CubitStatus get_thickened_BODIES_of_VERTICES( const char *command_name,
- DLIList<VERTEX*> &input_VERTEX_list,
- BODY *&common_BODY_ptr,
- DLIList<BODY*> &thickened_BODY_list,
- DLIList<DLIList<FACE*>*> &output_FACE_lists,
- DLIList<DLIList<VERTEX*>*> &output_VERTEX_lists,
- DLIList<DLIList<EDGE*>*> &output_EDGE_lists,
- double thickness = 0.2 );
- //- Get thickened BODIES from an input list of VERTICEs. This function can
- //- be called multiple times on the same list of VERTICEs - each time, the
- //- VERTICEs from the common body that is thickened are removed from the
- //- input EDGE list. These thickened BODIES are copied from the sheets the
- //- VERTICEs are attached to (multiple BODIES can be returned because the
- //- thickened BODIES must be nonmanifold). For each BODY returned, also
- //- output a list of the FACEs (corresponding to the original FACEs of the
- //- sheet body), the VERTICEs (corresponding to the original VERTICEs), and
- //- a list of EDGEs created by the thickening process (from sweeping the
- //- original VERTEX - note it is possible that no EDGE was created, in which
- //- case a NULL value will exist in the list).
-
- CubitStatus copy_FACES_from_BODY( DLIList<FACE*> &FACE_list,
- BODY *&copied_BODY_ptr);
- //- Input FACE list must be in a single BODY. Copy these FACEs off into
- //- a new BODY, while retaining all the Cubit attributes. The input
- //- BODY (the parent BODY of the FACE_list) is NOT modified.
-
- CubitStatus remove_FACES_from_BODY( BODY *BODY_ptr,
- DLIList<FACE*> &remove_FACE_list );
- //- Remove the given FACEs from the BODY (modifying the input BODY).
-
- CubitStatus remove_FACES_from_BODY_except( BODY *BODY_ptr,
- DLIList<FACE*> &keep_FACE_list );
- //- Remove all FACEs from the BODY except those in the keep_FACE_list
- //- (modifying the input BODY).
-
- CubitStatus thicken_BODY( BODY *BODY_ptr, double thickness );
- //- Thicken a BODY. Remove CUBIT owner attributes from all VERTICEs, EDGEs,
- //- and FACEs except the original VERTICEs, EDGEs and FACEs.
-
- VERTEX *find_corresponding_VERTEX( VERTEX *ref_VERTEX_ptr, DLIList<VERTEX*> &VERTEX_list );
- //- Find the corresponding VERTEX in the input VERTEX_list to the ref_VERTEX_ptr
- //- using CUBIT owner attributes. For example, copy a BODY then use this
- //- function to find a corresponding VERTEX from the parent BODY on the copied
- //- BODY.
-
- EDGE *find_corresponding_EDGE( EDGE *ref_EDGE_ptr, DLIList<EDGE*> &EDGE_list );
- //- Find the corresponding EDGE in the input EDGE_list to the ref_EDGE_ptr
- //- using CUBIT owner attributes. For example, copy a BODY then use this
- //- function to find a corresponding EDGE from the parent BODY on the copied
- //- BODY.
-
- LOOP *find_corresponding_LOOP( LOOP *ref_LOOP_ptr, DLIList<LOOP*> &LOOP_list );
- //- Find the corresponding LOOP in the input LOOP_list to the ref_LOOP_ptr
- //- using CUBIT owner attributes. For example, copy a BODY then use this
- //- function to find a corresponding LOOP from the parent BODY on the copied
- //- BODY.
-
- FACE *find_corresponding_FACE( FACE *ref_FACE_ptr, DLIList<FACE*> &FACE_list );
- //- Find the corresponding FACE in the input FACE_list to the ref_FACE_ptr
- //- using CUBIT owner attributes. For example, copy a BODY then use this
- //- function to find a corresponding FACE from the parent BODY on the copied
- //- BODY.
-
- FACE *find_corresponding_FACE( AcisBridge *ab_ptr, BODY *BODY_ptr);
- //- Find FACE with given owner in the BODY_ptr
-
- LOOP *find_corresponding_LOOP( AcisBridge *ab_ptr, BODY *BODY_ptr);
- //- Find LOOP with given owner in the BODY_ptr
-
- CubitStatus get_owner_list( DLIList<EDGE*> &EDGE_list,
- DLIList<AcisBridge*> &owner_list );
- //- Get a list of Cubit owners corresponding to the input EDGE list.
- //- Appends (unique) to the input list.
-
- CubitStatus get_owner_list( DLIList<FACE*> &FACE_list,
- DLIList<AcisBridge*> &owner_list );
- //- Get a list of Cubit owners corresponding to the input FACE list.
- //- Appends (unique) to the input list.
-
- CubitStatus get_owner_list( DLIList<LOOP*> &LOOP_list,
- DLIList<AcisBridge*> &owner_list );
- //- Get a list of Cubit owners corresponding to the input LOOP list.
- //- Appends (unique) to the input list.
-
- CubitStatus get_corresponding_FACE_list( DLIList<AcisBridge*> &owner_list,
- BODY *BODY_ptr,
- DLIList<FACE*> &corresponding_FACE_list );
- //- Find the FACEs in BODY_ptr corresponding to the given owners
-
- CubitStatus get_corresponding_LOOP_list( DLIList<AcisBridge*> &owner_list,
- BODY *BODY_ptr,
- DLIList<LOOP*> &corresponding_LOOP_list );
- //- Find the LOOPs in BODY_ptr corresponding to the given owners
-
- CubitStatus prep_for_surface_swap( BODY *thickened_BODY_ptr,
- BODY *copied_input_BODY_ptr,
- DLIList<AcisBridge*> &owner_FACE_list );
- //- Prepare to swap the non-extended surfaces in the (original)
- //- copied_input_BODY_ptr with the extended surfaces in the
- //- thickened_BODY_ptr. This function removes ALL BUT the input
- //- FACEs from the thickend_BODY_ptr (so we just have the extended or
- //- trimmed FACEs left), and removes the input FACEs from the
- //- copied_input_BODY_ptr. These two BODIEs can be united later for the
- //- end result - the sheet BODY surfaces have been extended/trimmed/etc.!
-
- CubitStatus unite_BODIES( BODY *copied_input_BODY_ptr,
- DLIList<BODY*> &thickened_BODY_list,
- BODY *&output_BODY_ptr );
- //- Unite all the given BODIES.
-
- CubitStatus get_owner_attribs( BODY *BODY_ptr, AcisBridge *&ab_body_ptr,
- AcisBridge *&ab_lump_ptr, AcisBridge *&ab_shell_ptr);
- //- Get owner attributes on the BODY, LUMP, SHELL
-
- CubitStatus reset_owner_attribs( BODY *BODY_ptr, AcisBridge *ab_body_ptr,
- AcisBridge *ab_lump_ptr, AcisBridge *ab_shell_ptr);
- //- Reset owner attributes on the BODY, LUMP, SHELL, since some operations
- //- remove them.
-
- CubitStatus sort_points_by_body_type( DLIList<Point*> &point_list,
- DLIList<Point*> &solid_points, DLIList<Point*> &sheet_points );
- //- Sort the incoming point list by the type of owning body of the points -
- //- solids or sheet bodies.
-
- CubitStatus tweak_chamfer_solid( DLIList<Point*> &point_list,
- double radius,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
- //- Chamfer vertices on solid bodies
-
- CubitStatus tweak_chamfer_fillet_sheet( DLIList<Point*> &point_list,
- double radius,
- int type,
- DLIList<BodySM*> &new_bodysm_list,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
- //- Chamfer or fillet vertices on sheet bodies.
- //- Type = 1=chamfer
- //- 2=fillet
-
- CubitStatus tweak_chamfer_solid( Point* point_ptr,
- double r1,
- Curve *c1,
- double r2,
- Curve *c2,
- double r3,
- Curve *c3,
- BodySM *&new_bodysm_ptr,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
- //- Chamfer a vertex on a solid body with variable radii. Radii correspond
- //- to given curves.
-
- CubitStatus tweak_chamfer_sheet( Point* point_ptr,
- double r1,
- Curve *c1,
- double r2,
- Curve *c2,
- BodySM *&new_bodysm_ptr,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE );
- //- Chamfer a vertex on a sheet body with variable radii. Radii correspond
- //- to given curves.
-
- CubitStatus assign_tweak_attribs( BODY *BODY_ptr, const char *att_name,
- DLIList<FACE*> &FACE_list, DLIList<AcisBridge*> &ab_FACE_list,
- DLIList<EDGE*> &EDGE_list, DLIList<AcisBridge*> &ab_EDGE_list,
- DLIList<VERTEX*> &VERTEX_list, DLIList<AcisBridge*> &ab_VERTEX_list );
- //- Assign named attribs to faces, edges and vertices so we can get back to
- //- them after a fillet or chamfer. These operations split these entities
- //- to make room for the new surfaces, and the original entities (and
- //- owner atributes) are lost. Thus we copy the owner atts during the split.
- //- This ultimately will allow us to preserve Cubit owners through a chamfer
- //- or fillet operation
-
- CubitStatus find_corresponding_entity_from_tweak_attrib( BODY *BODY_ptr,
- const char *att_name,
- const int ent_type,
- int ent_integer,
- ENTITY *&output_ENTITY_ptr );
- //- Find a corresponding entity to the input ENTITY_ptr using the tweak
- //- attributes assigned by assign_tweak_attribs.
- //- Input is of type ent_type, either FACE_TYPE, EDGE_TYPE, VERTEX_TYPE
-
- CubitStatus reassign_cubit_owners_from_tweak_attribs( BODY *BODY_ptr,
- const char *att_name,
- DLIList<FACE*> &FACE_list, DLIList<AcisBridge*> &ab_FACE_list,
- DLIList<EDGE*> &EDGE_list, DLIList<AcisBridge*> &ab_EDGE_list,
- DLIList<VERTEX*> &VERTEX_list, DLIList<AcisBridge*> &ab_VERTEX_list );
- //- Using the tweak attributes assigned by assign_tweak_attribs, reset
- //- the Cubit owners back on the proper entities.
-
- CubitStatus remove_named_attribs( BODY *BODY_ptr, const char *name );
- //- Remove the named attributes from FACEs, EDGEs and VERTICEs
-
- CubitStatus blend_edges( DLIList<EDGE*> EDGE_list, double radius );
- //- Perform a blend operation. This maintains Cubit owners where
- //- possible through the operation.
-
- CubitStatus chamfer_edges( DLIList<EDGE*> EDGE_list, double r1, double r2 = -1.0 );
- //- Perform a chamfer operation. This maintains Cubit owners where
- //- possible through the operation.
-
- CubitStatus chamfer_vertices( DLIList<VERTEX*> VERTEX_list, double radius );
- //- Perform a chamfer operation. This maintains Cubit owners where
- //- possible through the operation.
-
- CubitBoolean FACE_surrounded( FACE *ref_FACE_ptr,
- DLIList<FACE*> &FACE_list );
- //- Determine if given (reference) FACE is entirely surrounded by
- //- the FACEs in FACE_list (reference FACE can be contained in
- //- FACE_list).
-
- CubitStatus get_outer_EDGEs( FACE *FACE_ptr, DLIList<EDGE*> &EDGE_list );
- //- Get EDGEs from outer LOOP of FACE
-
- CubitStatus get_EDGES_by_BODY( DLIList<Curve*> &input_curve_list,
- DLIList<BODY*> &BODY_list,
- DLIList<DLIList<EDGE*>*> &BODY_EDGE_lists );
- CubitStatus get_EDGES_by_BODY( DLIList<EDGE*> &input_EDGE_list,
- DLIList<BODY*> &BODY_list,
- DLIList<DLIList<EDGE*>*> &BODY_EDGE_lists );
- //- Get separate lists of EDGEs from the input EDGEs by common BODY. Be
- //- sure to free the individual lists in BODY_EDGE_lists when you are done
- //- with them, as this function allocates the memory for these lists.
-
- CubitStatus all_complete_internal_loops( DLIList<EDGE*> &BODY_EDGE_list,
- DLIList<LOOP*> &LOOP_list );
- //- Determine if given EDGEs form complete internal LOOPs. LOOPs must be on
- //- a sheet BODY. Return those LOOPs. All given EDGEs must be in the same
- //- BODY.
-
- CubitStatus remove_LOOPs( DLIList<LOOP*> &LOOP_list );
- //- Remove the given internal LOOPs (from sheet BODIES).
-
- CubitStatus remove_holes( BODY *sheet_BODY_ptr );
- //- Remove all of the holes (internal LOOPs) in the given sheet BODY.
-
- CubitStatus extrema_pln_BODY( CubitPlane &plane, BODY *BODY_ptr,
- double &extrema_dist, int back_side = 0 );
- //- Finds the extrema distance from a plane to an ACIS BODY (perpendicular
- //- distance from plane to farthest extent of BODY), on one side of the
- //- plane (by default on the front of the plane - direction of plane
- //- normal). If the entire BODY lies on the other side of the plane, the
- //- extrema distance is 0.0.
-
- CubitStatus tweak_FACEs_to_target( DLIList<FACE*> &tweak_FACE_list,
- FACE *target_FACE, CubitBoolean reverse_flg = CUBIT_FALSE,
- CubitBoolean skip_self_int_check = CUBIT_FALSE );
- //- Tweak the given FACEs (which must all be part of the same BODY) to the
- //- given target FACE. The reverse flag should never be needed - if it is,
- //- there may be a bug or a bad normal on a body (i.e., negative volume
- //- body. However, it is here as a workaround if needed.
-
- CubitVector surface_normal( FACE *FACE_ptr, CubitVector &location,
- CubitBoolean calc_loc = CUBIT_TRUE );
- //- Get normal of underlying surface of given FACE. If calc_loc is
- //- CUBIT_TRUE, the location vector is calculated as the closest location on
- //- the FACE to the center of the bounding box of the FACE, and the normal
- //- is found there. If calc_loc is CUBIT_FALSE, the normal is found at the
- //- given location. Note the normal is NOT adjusted for the FACE sense.
-
- CubitVector FACE_normal( FACE *FACE_ptr, CubitVector &location,
- CubitBoolean calc_loc = CUBIT_TRUE );
- //- Get normal of given FACE. If calc_loc is CUBIT_TRUE, the location
- //- vector is calculated as the closest location on the FACE to the center
- //- of the bounding box of the FACE, and the normal is found there. If
- //- calc_loc is CUBIT_FALSE, the normal is found at the given location.
- //- Note the normal is adjusted for the FACE sense.
-
- CubitVector weighted_average_FACE_normal( DLIList<FACE*> &FACE_list );
- //- Get weighted average normal of given FACEs. The normals are weighted
- //- by a factor related to FACE area utilizing the graphics facets.
-
- CubitStatus weighted_average_FACE_normal( FACE *FACE_ptr, CubitVector &norm,
- double &weight );
- //- Get weighted average normal of give FACE. The normal is weighted
- //- by a factor related to FACE area utilizing the graphics facets. Note
- //- for a surface like a full cylinder, this can result in a 0,0,0 normal
- //- vector.
-
- CubitStatus create_offset_planar_body( CubitPlane &plane, double offset,
- BODY *&planar_BODY_ptr );
- //- Create a planar ACIS BODY from the given CubitPlane and offset. The
- //- offset is in the direction of the plane's normal. The plane is
- //- arbitrarily 10x10x10 in size near the origin.
-
- CubitStatus create_extended_sheet( DLIList<FACE*> &FACE_list,
- BODY *&ext_BODY_ptr );
- //- Extend out a set of FACEs and place into a new sheet BODY.
-
- CubitStatus prep_cutting_sheet( BODY *&cutting_sheet,
- BODY *tweaked_BODY_ptr,
- BODY *ext_target_BODY_ptr,
- CubitVector &source_norm,
- CubitVector &target_norm,
- CubitBoolean check_crossing = CUBIT_TRUE );
- //- Prepare the cutting sheet for chopping off the BODY in a
- //- tweak_target_multiple operation. Inputs include the cutting sheet,
- //- the tweaked BODY (the BODY that will be cut), the extended target BODY
- //- with consistent normals and reference source and target normals. The
- //- cutting sheet can optionally be trimmed to including only FACEs crossed
- //- by the extended target (the "side" FACEs) that we want to cut. Note
- //- named "tweak" attributes must exist on the side FACEs prior to calling
- //- this function if "check_crossing" is true.
-
- CubitStatus chop_off_with_sheet( BODY *BODY_ptr, BODY *sheet_BODY_ptr );
- //- Chop off all the material in a BODY to one side of a sheet body. The
- //- material is removed on the side of the sheet body according to the
- //- surface normals of the sheet body (material removed in the direction of
- //- the surface normals of the sheet body, which must be consistent).
-
- CubitStatus get_overlap_area( BODY *BODY_ptr1, BODY *BODY_ptr2,
- double &overlap_area, double accuracy = 1e-5 );
- //- Determine the area of overlap of two BODIES. Uses an ACIS intersection
- //- boolean so is quite expensive.
-
- CubitStatus copy_FACEs_into_sheet( DLIList<FACE*> &FACE_list,
- BODY *&sheet_ptr,
- CubitBoolean heal = CUBIT_TRUE );
- //- Copies the given FACEs into a sheet BODY. The FACEs are united together
- //- into the new BODY. Note a regularized boolean is performed (so the body
- //- is regularized). By default the sheet BODY is healed, but this can be
- //- turned off. Note healing will make the normals consistent, unless there
- //- is nonmanifold geometry in the body.
-
- CubitStatus remove_per_nonmanifold_FACEs( BODY *cutting_tool );
- //- Removes undesired nonmanifold FACEs in the cutting sheet. See
- //- diagram in function for one such case. If any nonmanifold edges exist
- //- in the model that can't be removed, CUBIT_FAILURE is returned.
-
- CubitStatus tangent_outdir( FACE *FACE_ptr, EDGE *EDGE_ptr,
- CubitVector &pos, CubitVector &tangent_outvec );
- //- Finds the direction tangent to and pointing away from the FACE boundary
- //- at the given location on the EDGE.
-
- CubitStatus remove_aligned_periodic_FACEs( BODY *cutting_tool,
- CubitVector &basis_vec );
- //- Removes cone, sphere or torus FACEs that have normals aligned with the
- //- given basis vector.
-
- CubitStatus heal_BODY( BODY *BODY_ptr );
- //- Use the ACIS healer to heal the given sheet BODY.
-
- CubitStatus align_normals( BODY *child, BODY *master );
- //- Align the normals of the child's FACEs to the master FACEs. It is
- //- assumed the child is a subset of the master (i.e., the master is an
- //- extended BODY).
-
- FACE * find_overlap_FACE( FACE *FACE_ptr, DLIList<FACE*> &FACE_list );
- //- Find the FACE in FACE_list that overlaps with FACE_ptr. Returns
- //- NULL if no overlap FACE found.
-
- CubitStatus make_surf_normals_consistent( BODY *BODY_ptr,
- FACE *seed_FACE = NULL );
- //- Make the shell normals in the given sheet BODY consistent. The optional
- //- seed FACE must be part of the BODY. If none given, get_seed_FACE (see
- //- below) is used to select a seed FACE.
-
- CubitStatus append_neighbors( DLIList<FACE*> &FACE_list );
- //- Helper function for make_shell_normals_consistent
-
- FACE *get_seed_FACE( DLIList<FACE*> &FACE_list );
- //- Get a seed FACE from the given list of FACEs. Only a seed FACE without
- //- a named "tweak" attribute on it will be returned. Also, it may not be
- //- of advantage, but we try to find a FACE that is not of type CONE, TORUS
- //- or SPHERE. If that is not possible, we just return the first FACE in
- //- the list with no "tweak" attribute on it.
-
- CubitStatus draw_tweak_preview_omt( BODY *BODY_ptr, CubitBoolean flush,
- DLIList<AcisBridge*> *prev_ab_list = NULL );
- //- Draw the preview EDGEs for tweak offset, move and target, for solid and
- //- sheetbodies. The function works by finding EDGEs or FACEs without Cubit
- //- owner attributes on them and drawing those EDGEs as well as the EDGEs
- //- attached to them. The "prev_ab_list" may be needed for special cases
- //- where the target is on the BODY itself. I recommend always sending in
- //- the sources and target entities in this list.
-
- CubitStatus tag_tweak_remove_FACEs_for_preview( BODY *BODY_ptr,
- DLIList<FACE*> &remove_FACE_list );
- //- Add an attribute ("tweak_preview") to the required FACEs for a tweak
- //- remove. For the preview we draw the EDGEs on the surviving FACEs
- //- adjoining those that are removed. Input is the copied BODY, along with
- //- the FACEs being removed.
-
- CubitStatus tag_tweak_remove_FACEs_for_preview( BODY *BODY_ptr,
- DLIList<EDGE*> &remove_EDGE_list );
- //- Add an attribute ("tweak_preview") to the required FACEs for a tweak
- //- remove. For the preview we draw the EDGEs on the surviving FACEs
- //- adjoining the EDGEs that are removed. Input is the copied BODY, along
- //- with the EDGEs being removed.
-
- CubitStatus draw_tweak_preview_tagged_FACEs( BODY *BODY_ptr,
- CubitBoolean flush );
- //- Draw EDGEs on FACEs with the "tweak_preview" attribute on them.
-
+protected:
static AcisTweakTool* instance_;
AcisQueryEngine *AQE; // For convenience
AcisModifyEngine *AME; // For convenience
+ CubitBoolean silent; // True if no output should be made from *certain*
+ // functions (PRINT_ERROR, etc.) - see above
};
+inline CubitBoolean AcisTweakTool::set_silent( CubitBoolean flg )
+{
+ CubitBoolean old_flg = silent;
+ silent = flg;
+ return old_flg;
+}
+
#endif
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/BodyACIS.cpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/BodyACIS.cpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/BodyACIS.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -19,26 +19,6 @@
// ********** END STANDARD INCLUDES **********
// ********** BEGIN ACIS INCLUDES **********
-#if CUBIT_ACIS_VERSION < 1100
-#include "constrct/kernapi/api/cstrapi.hxx"
-#include "kernel/kerndata/top/body.hxx"
-#include "kernel/kerndata/top/lump.hxx"
-#include "kernel/kerndata/top/shell.hxx"
-#include "kernel/kerndata/top/face.hxx"
-#include "kernel/kerndata/transent/transent.hxx"
-#include "kernel/kerndata/geom/transfrm.hxx"
-#include "kernel/kernapi/api/api.hxx"
-#include "kernel/kernapi/api/kernapi.hxx"
-#include "kernel/kerndata/lists/lists.hxx"
-#include "intersct/kernapi/api/intrapi.hxx"
-#include "baseutil/vector/vector.hxx"
-#include "baseutil/vector/transf.hxx"
-#include "baseutil/vector/box.hxx"
-#include "operator/kernapi/api/operapi.hxx"
-#include "kernel/kernutil/tensor/tensor.hxx"
-#include "intersct/kernapi/api/ptcont.hxx"
-
-#else
#include "cstrapi.hxx"
#include "body.hxx"
#include "lump.hxx"
@@ -57,9 +37,6 @@
#include "warp_api.hxx"
#include "tensor.hxx"
#include "ptcont.hxx"
-#include "insanity_list.hxx"
-#include "err_ent.hxx"
-#endif
// ********** END ACIS INCLUDES **********
// ********** BEGIN CUBIT INCLUDES **********
@@ -72,22 +49,13 @@
#include "BodyACIS.hpp"
#include "BodySM.hpp"
-#include "Lump.hpp"
#include "Body.hpp"
#include "GeometryQueryTool.hpp"
#include "AcisQueryEngine.hpp"
+#include "AcisToolUtil.hpp"
#include "CubitSimpleAttrib.hpp"
-#include "CubitUtil.hpp"
-#include "RefVertex.hpp"
-#include "RefEdge.hpp"
-#include "CoEdge.hpp"
-#include "Loop.hpp"
-#include "RefFace.hpp"
-#include "Shell.hpp"
-#include "RefVolume.hpp"
-
// ********** END CUBIT INCLUDES **********
// ********** BEGIN STATIC DECLARATIONS **********
@@ -358,11 +326,11 @@
// Creation Date : 3/6/98
//-------------------------------------------------------------------------
-int BodyACIS::validate( const CubitString &user_name,
+int BodyACIS::validate( const CubitString &entity_name,
DLIList <TopologyEntity*> &bad_entities)
{
insanity_list *entity_list = NULL;
- outcome result = api_check_entity (get_BODY_ptr(), entity_list );
+ outcome result = api_check_entity(get_BODY_ptr(), entity_list );
if ( result.ok() && entity_list == NULL )
{
@@ -375,10 +343,10 @@
if ( entity_list )
{
- convert_entity_list( entity_list, bad_entities );
- show_bad_geom( bad_entities, user_name );
+ AcisToolUtil::convert_entity_list( entity_list, bad_entities );
+ AcisToolUtil::show_bad_geom( bad_entities, entity_name );
PRINT_ERROR("with '%s' in the ACIS geometry.\n",
- user_name.c_str());
+ entity_name.c_str());
}
else
@@ -527,185 +495,8 @@
// ********** BEGIN PRIVATE FUNCTIONS **********
-void BodyACIS::convert_entity_list( insanity_list *ent_list,
- DLIList <TopologyEntity*> &topo_entity_list)
-{
- int i;
- if( ent_list->count() )
- {
- insanity_list *tmp_list = ent_list;
- for(; tmp_list; tmp_list = tmp_list->next() )
- {
- insanity_data *error_data = tmp_list->data();
- ENTITY *bad_ent = error_data->get_ent();
- ENTITY_LIST bad_ents;
- if(bad_ent->identity() == ERROR_ENTITY_TYPE )
- {
- ERROR_ENTITY *error_ent = (ERROR_ENTITY*)bad_ent;
- bad_ents.add( error_ent->get_owner(0) );
- bad_ents.add( error_ent->get_owner(1) );
- }
- else
- bad_ents.add( bad_ent );
-
- bad_ents.init();
-
- PRINT_INFO("%s: ", error_data->get_message() );
-
- while( (bad_ent = bad_ents.next()) != NULL )
- {
- TopologyEntity* te_ptr = NULL;
- te_ptr = ATTRIB_CUBIT_OWNER::get_topology_entity( bad_ent );
- if( te_ptr )
- {
- RefEntity *ref_ent = CAST_TO( te_ptr, RefEntity );
- topo_entity_list.append_unique(te_ptr);
- if( ref_ent )
- PRINT_INFO(" %s %d", ref_ent->class_name(), ref_ent->id() );
- }
- else
- PRINT_INFO("%s",bad_ent->type_name() );
- }
- PRINT_INFO("\n");
- }
- }
-}
-
-CubitStatus BodyACIS::show_bad_geom(DLIList <TopologyEntity*> &ent_list,
- const CubitString &user_name)
-{
- DLIList<RefVertex*> vertex_list;
- DLIList<RefEdge*> edge_list;
- DLIList<RefEdge*> curve_coedge_list;
- DLIList<CoEdge*> coedge_list;
- DLIList<Loop*> loop_list;
- DLIList<RefFace*> face_list;
- DLIList<Shell*> shell_list;
- DLIList<RefVolume*> volume_list;
- int i;
- // We need an encapsulated class to handle this sort of thing...
- for (i=0;i<ent_list.size();i++)
- {
- TopologyEntity* TE_ptr = ent_list.get_and_step();
- RefVertex* ref_vertex;
- RefEdge* ref_edge;
- CoEdge* co_edge;
- Loop* loop;
- RefFace* face;
- Shell* shell;
- RefVolume* volume;
-
- if( (ref_vertex = CAST_TO( TE_ptr, RefVertex ) ) != NULL )
- vertex_list.append_unique(ref_vertex);
- else if( (ref_edge = CAST_TO( TE_ptr, RefEdge ) ) != NULL )
- edge_list.append_unique(ref_edge);
- else if( (co_edge = CAST_TO( TE_ptr, CoEdge ) ) != NULL )
- coedge_list.append_unique(co_edge);
- else if( (loop = CAST_TO( TE_ptr, Loop ) ) != NULL )
- loop_list.append_unique(loop);
- else if( (face = CAST_TO( TE_ptr, RefFace ) ) != NULL )
- face_list.append_unique(face);
- else if( (shell = CAST_TO( TE_ptr, Shell ) ) != NULL )
- shell_list.append_unique(shell);
- else if( (volume = CAST_TO( TE_ptr, RefVolume ) ) != NULL )
- volume_list.append_unique(volume);
- }
-
- char pre[100];
-
- if( vertex_list.size() )
- {
- sprintf( pre, "Found %d bad vertices in %s. The vertices: ", vertex_list.size(),
- user_name.c_str() );
- DLIList<CubitEntity*> cubit_list;
- CAST_LIST( vertex_list, cubit_list, CubitEntity );
- CubitUtil::list_entity_ids( pre, cubit_list );
- }
-
- if( edge_list.size() )
- {
- sprintf( pre, "Found %d bad curves in %s. The curves: ", edge_list.size(),
- user_name.c_str() );
- DLIList<CubitEntity*> cubit_list;
- CAST_LIST( edge_list, cubit_list, CubitEntity );
- CubitUtil::list_entity_ids( pre, cubit_list );
- }
-
- for( i=0; i<coedge_list.size(); i++ )
- {
- RefEdge* ref_edge_ptr = coedge_list.get_and_step()->get_ref_edge_ptr();
- curve_coedge_list.append_unique( ref_edge_ptr );
- }
- if( coedge_list.size() )
- {
- sprintf( pre, "Found %d bad coedges in %s. The curves: ", coedge_list.size(),
- user_name.c_str() );
- DLIList<CubitEntity*> cubit_list;
- CAST_LIST( curve_coedge_list, cubit_list, CubitEntity );
- CubitUtil::list_entity_ids( pre, cubit_list );
- }
-
- // LOOPS
- Loop* loop_ptr;
- DLIList<RefEdge*> curve_loop_list;
- for( i=0; i<curve_loop_list.size(); i++ )
- {
- loop_ptr = loop_list.get_and_step();
- DLIList<RefEdge*> tmp_curve_list;
- loop_ptr->ordered_ref_edges( tmp_curve_list );
- curve_loop_list.merge_unique( tmp_curve_list );
- }
- curve_loop_list.reset();
- if( curve_loop_list.size() )
- {
- sprintf( pre, "Found %d bad loops in %s. The curves: ", loop_list.size(), user_name.c_str() );
- DLIList<CubitEntity*> cubit_list;
- CAST_LIST( curve_loop_list, cubit_list, CubitEntity );
- CubitUtil::list_entity_ids( pre, cubit_list );
- }
-
- // SURFACES
- if( face_list.size() )
- {
- sprintf( pre, "Found %d bad surfaces in %s. The surfaces: ", face_list.size(), user_name.c_str() );
- DLIList<CubitEntity*> cubit_list;
- CAST_LIST( face_list, cubit_list, CubitEntity );
- CubitUtil::list_entity_ids( pre, cubit_list );
- }
-
- // SHELLS
- Shell* shell_ptr;
- DLIList<RefFace*> face_shell_list;
- for( i=0; i<shell_list.size(); i++ )
- {
- shell_ptr = shell_list.get_and_step();
- DLIList<RefFace*> tmp_surface_list;
- shell_ptr->ref_faces( tmp_surface_list );
- face_shell_list.merge_unique( tmp_surface_list );
- }
- if( face_shell_list.size() )
- {
- sprintf( pre, "Found %d bad shells in %s. The surfaces: ", shell_list.size(), user_name.c_str() );
- DLIList<CubitEntity*> cubit_list;
- CAST_LIST( face_shell_list, cubit_list, CubitEntity );
- CubitUtil::list_entity_ids( pre, cubit_list );
- }
-
- // LUMPS
- if( volume_list.size() )
- {
- sprintf( pre, "Found %d bad volumes in %s. The volumes: ", volume_list.size(), user_name.c_str() );
- DLIList<CubitEntity*> cubit_list;
- CAST_LIST( volume_list, cubit_list, CubitEntity );
- CubitUtil::list_entity_ids( pre, cubit_list );
- }
-
- return CUBIT_SUCCESS;
-}
-
-
// ********** END PRIVATE FUNCTIONS **********
// ********** BEGIN HELPER CLASSES **********
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/BodyACIS.hpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/BodyACIS.hpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/BodyACIS.hpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -19,13 +19,8 @@
// ********** END STANDARD INCLUDES **********
// ********** BEGIN ACIS INCLUDES **********
-#if CUBIT_ACIS_VERSION < 1100
-#include "baseutil/vector/transf.hxx"
-#include "kernel/kerndata/top/body.hxx"
-#else
#include "transf.hxx"
#include "body.hxx"
-#endif
// ********** END ACIS INCLUDES **********
// ********** BEGIN CUBIT INCLUDES **********
@@ -157,18 +152,6 @@
//- the BODY to "absorb" the transformation.
#endif
-
- CubitStatus show_bad_geom( DLIList <TopologyEntity*> &ent_list,
- const CubitString &user_name);
- // This was put in only to display bad geometry from a validate. Needs to
- // be encapsulated in another class...
-
- void convert_entity_list( insanity_list *ent_list,
- DLIList <TopologyEntity*> &topology_entities);
- // Given the acis entities, gets the corrisponding topology entities in
- // cubit by which they are represented.
-
-
};
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/CMakeLists.txt
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/CMakeLists.txt 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/CMakeLists.txt 2010-01-27 02:15:23 UTC (rev 3496)
@@ -1,19 +1,24 @@
PROJECT(cubit_acis)
+OPTION(CGM_ACIS_USE_TWEAK "my docs" OFF)
+
SET(ACIS_SRCS
AcisBridge.cpp
AcisEdgeTool.cpp
AcisFacetManager.cpp
AcisFeatureEngine.cpp
AcisHealerTool.cpp
+ AcisHistory.cpp
AcisModifyEngine.cpp
AcisQueryEngine.cpp
AcisSurfaceTool.cpp
AcisToolUtil.cpp
AcisTweakTool.cpp
+ AcisTopologyTool.cpp
AcisDrawTool.cpp
attrib_cubit_owner.cpp
+ attrib_history.cpp
attrib_snl.cpp
attrib_snl_simple.cpp
BodyACIS.cpp
@@ -26,6 +31,10 @@
SurfaceACIS.cpp
)
+IF(CGM_ACIS_USE_TWEAK)
+ SET(ACIS_SRCS ${ACIS_SRCS} ${cubit_acis_SOURCE_DIR}/CAT/AcisTweakToolCAT.cpp)
+ENDIF(CGM_ACIS_USE_TWEAK)
+
# for convenience, include this in the project
IF(WIN32)
FOREACH(var ${ACIS_SRCS})
@@ -37,36 +46,54 @@
ENDIF(NOT ${CMAKE_GENERATOR} MATCHES "NMake")
ENDIF(WIN32)
-
INCLUDE(${cubit_acis_SOURCE_DIR}/UseACIS.cmake)
+IF(CUBIT_GEOM_EXTERNAL_GTCATTRIB)
+ INCLUDE_DIRECTORIES(${gtcAttrib_SOURCE_DIR}/incl)
+ELSE(CUBIT_GEOM_EXTERNAL_GTCATTRIB)
+ SUBDIRS(gtcAttrib)
+ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/gtcAttrib/incl)
+ENDIF(CUBIT_GEOM_EXTERNAL_GTCATTRIB)
+
# add acis includes to current project
-INCLUDE_DIRECTORIES(${ACIS_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/gtcAttrib/incl)
+INCLUDE_DIRECTORIES(${ACIS_INCLUDE_DIR})
+IF(CGM_ACIS_USE_TWEAK)
+ INCLUDE_DIRECTORIES(${cubit_SOURCE_DIR}/geom/ACIS/CAT)
+ENDIF(CGM_ACIS_USE_TWEAK)
+
+IF(CMAKE_COMPILER_IS_GNUCC)
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated")
+ENDIF(CMAKE_COMPILER_IS_GNUCC)
+
# build cubit acis library from sources
ADD_LIBRARY(cubit_ACIS ${ACIS_SRCS} ${ACIS_HEADERS} ${EXTRA_ACIS_SRCS})
+TARGET_LINK_LIBRARIES(cubit_ACIS ${ACIS_LIBS})
-SUBDIRS(gtcAttrib)
+# install ACIS libs
+IF(WIN32)
+ STRING(REGEX REPLACE "/lib/" "/bin/" ACIS_INSTALL_LIBS "${ACIS_RELEASE_LIBS}")
+ STRING(REGEX REPLACE "/lib/" "/bin/" ACIS_INSTALL_DEBUG_LIBS "${ACIS_DEBUG_LIBS}")
+ STRING(REGEX REPLACE "\\.lib" ".dll" ACIS_INSTALL_LIBS "${ACIS_INSTALL_LIBS}")
+ STRING(REGEX REPLACE "\\.lib" ".dll" ACIS_INSTALL_DEBUG_LIBS "${ACIS_INSTALL_DEBUG_LIBS}")
+ELSE(WIN32)
+ SET(ACIS_INSTALL_LIBS ${ACIS_RELEASE_LIBS})
+ SET(ACIS_INSTALL_DEBUG_LIBS ${ACIS_DEBUG_LIBS})
+ENDIF(WIN32)
-IF(UNIX)
-ADD_CUSTOM_TARGET(switch_acis ${CMAKE_MAKE_PROGRAM} clean)
-ENDIF(UNIX)
-
-# install ACIS libs
-SET(CMAKE_INSTALL_3RD_PARTY_PREFIX ${CMAKE_INSTALL_PREFIX} CACHE PATH "Install prefix for 3rd party libraries")
SET(CMAKE_INSTALL_BINARY_DIR "bin" CACHE PATH "Install directory for binaries")
-IF(CMAKE_INSTALL_3RD_PARTY_PREFIX)
- SET(ACIS_INSTALL_PREFIX ${CMAKE_INSTALL_3RD_PARTY_PREFIX}/${CMAKE_INSTALL_BINARY_DIR})
- IF(WIN32)
- STRING(REGEX REPLACE "/lib/" "/bin/" ACIS_SHARED_LIBRARY_DIR ${ACIS_LIBRARY_DIR})
- STRING(REGEX REPLACE "/lib/" "/bin/" ACIS_SHARED_LIBRARY_DIR_DEBUG ${ACIS_LIBRARY_DIR_DEBUG})
- SET(ACIS_INSTALL_LIBS ${ACIS_RELEASE_LIBS})
- SET(ACIS_INSTALL_LIBS_DEBUG ${ACIS_DEBUG_LIBS})
- ELSE(WIN32)
- SET(ACIS_SHARED_LIBRARY_DIR ${ACIS_LIBRARY_DIR})
- SET(ACIS_INSTALL_LIBS ${ACIS_LIBS})
- ENDIF(WIN32)
- CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/InstallACIS.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/InstallACIS.cmake @ONLY)
- SET_TARGET_PROPERTIES(cubit_ACIS PROPERTIES POST_INSTALL_SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/InstallACIS.cmake)
-ENDIF(CMAKE_INSTALL_3RD_PARTY_PREFIX)
+IF(CMAKE_CONFIGURATION_TYPES)
+ INSTALL(FILES ${ACIS_INSTALL_LIBS}
+ DESTINATION ${CMAKE_INSTALL_BINARY_DIR}
+ CONFIGURATIONS Release
+ COMPONENT Runtime)
+ INSTALL(FILES ${ACIS_INSTALL_DEBUG_LIBS}
+ DESTINATION ${CMAKE_INSTALL_BINARY_DIR}
+ CONFIGURATIONS Debug
+ COMPONENT Runtime)
+ELSE(CMAKE_CONFIGURATION_TYPES)
+ INSTALL(FILES ${ACIS_INSTALL_LIBS}
+ DESTINATION ${CMAKE_INSTALL_BINARY_DIR}
+ COMPONENT Runtime)
+ENDIF(CMAKE_CONFIGURATION_TYPES)
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/CoEdgeACIS.cpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/CoEdgeACIS.cpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/CoEdgeACIS.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -16,19 +16,11 @@
// ********** END STANDARD INCLUDES **********
// ********** BEGIN ACIS INCLUDES **********
-#if CUBIT_ACIS_VERSION < 1100
-#include "kernel/kernapi/api/kernapi.hxx"
-#include "kernel/kerndata/data/datamsc.hxx"
-#include "kernel/kerndata/top/coedge.hxx"
-#include "kernel/kerndata/top/loop.hxx"
-#include "kernel/kerndata/top/edge.hxx"
-#else
#include "kernapi.hxx"
#include "datamsc.hxx"
#include "coedge.hxx"
#include "loop.hxx"
#include "edge.hxx"
-#endif
// ********** END ACIS INCLUDES **********
// ********** BEGIN CUBIT INCLUDES **********
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/CurveACIS.cpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/CurveACIS.cpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/CurveACIS.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -17,24 +17,6 @@
// ********** END STANDARD INCLUDES **********
// ********** BEGIN ACIS INCLUDES **********
-#if CUBIT_ACIS_VERSION < 1100
-#include "kernel/acis.hxx"
-#include "kernel/kernapi/api/api.hxx"
-#include "kernel/kernapi/api/kernapi.hxx"
-#include "intersct/kernapi/api/intrapi.hxx"
-#include "kernel/kerndata/data/entity.hxx"
-#include "kernel/kerndata/top/edge.hxx"
-#include "kernel/kerndata/top/vertex.hxx"
-#include "kernel/kerndata/geom/point.hxx"
-#include "kernel/kerndata/geom/allcurve.hxx"
-#include "kernel/kerndata/lists/lists.hxx"
-#include "kernel/kerndata/top/alltop.hxx" // Required for is_TEDGE
-#include "kernel/kernint/d3_chk/chk_stat.hxx"
-#include "intersct/sg_husk/query/sgquery.hxx"
-#include "intersct/sg_husk/query/sgquertn.hxx"
-#include "baseutil/vector/position.hxx"
-#include "baseutil/vector/interval.hxx"
-#else
#include "acis.hxx"
#include "api.hxx"
#include "kernapi.hxx"
@@ -51,7 +33,6 @@
#include "sgquertn.hxx"
#include "position.hxx"
#include "interval.hxx"
-#endif
/*
//Added for G1_discontinous(..)
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/CurveACIS.hpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/CurveACIS.hpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/CurveACIS.hpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -19,13 +19,8 @@
// ********** END STANDARD INCLUDES **********
// ********** BEGIN ACIS INCLUDES **********
-#if CUBIT_ACIS_VERSION < 1100
-#include "kernel/kerndata/top/edge.hxx"
-#include "kernel/kerndata/geom/allcurve.hxx"
-#else
#include "edge.hxx"
#include "allcurve.hxx"
-#endif
// ********** END ACIS INCLUDES **********
// ********** BEGIN CUBIT INCLUDES **********
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/LoopACIS.cpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/LoopACIS.cpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/LoopACIS.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -17,17 +17,11 @@
// ********** END STANDARD INCLUDES **********
// ********** BEGIN ACIS INCLUDES **********
-#if CUBIT_ACIS_VERSION < 1100
-#include "kernel/kernapi/api/kernapi.hxx"
-#include "kernel/kerndata/data/datamsc.hxx"
-#include "kernel/kerndata/top/loop.hxx"
-#include "kernel/kerndata/top/coedge.hxx"
-#else
#include "kernapi.hxx"
#include "datamsc.hxx"
#include "loop.hxx"
#include "coedge.hxx"
-#endif
+#include "cstrapi.hxx" // for api_loop_external()
#include "attrib_cubit_owner.hpp"
#include "attrib_snl_simple.hpp"
@@ -150,6 +144,33 @@
AcisBridge::remove_all_simple_attribute_virt();
}
+LoopType LoopACIS::loop_type()
+{
+ LOOP* cur_loop = get_LOOP_ptr();
+ ::loop_type type;
+ int d[2];
+ outcome result = api_loop_type(cur_loop, type, d);
+ if (result.ok())
+ {
+ switch(type)
+ {
+ case loop_unknown:
+ return LOOP_TYPE_UNKNOWN;
+ case loop_periphery:
+ return LOOP_TYPE_EXTERNAL;
+ case loop_hole:
+ return LOOP_TYPE_HOLE;
+ case loop_u_separation:
+ return LOOP_TYPE_V_PERIODIC;
+ case loop_v_separation:
+ return LOOP_TYPE_U_PERIODIC;
+ case loop_uv_separation:
+ return LOOP_TYPE_UNKNOWN;
+ }
+ }
+ return LOOP_TYPE_UNKNOWN;
+}
+
//-------------------------------------------------------------------------
// Purpose : The purpose of this function is to get the
// attributes attached to this geometry entity. The name is
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/LoopACIS.hpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/LoopACIS.hpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/LoopACIS.hpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -54,6 +54,8 @@
//- This function returns a pointer to the geometric modeling engine
//- associated with the object.
+ virtual LoopType loop_type() ;
+
virtual void append_simple_attribute_virt(CubitSimpleAttrib*);
//R void
//I
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/LumpACIS.cpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/LumpACIS.cpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/LumpACIS.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -17,20 +17,6 @@
// ********** END STANDARD INCLUDES **********
// ********** BEGIN ACIS INCLUDES **********
-#if CUBIT_ACIS_VERSION < 1100
-#include "kernel/kernapi/api/kernapi.hxx"
-#include "kernel/kerndata/data/datamsc.hxx"
-#include "constrct/kernapi/api/cstrapi.hxx"
-#include "kernel/kernutil/tensor/tensor.hxx"
-#include "kernel/kerndata/top/lump.hxx"
-#include "kernel/kerndata/top/body.hxx"
-#include "kernel/kerndata/lists/lists.hxx"
-#include "intersct/kernapi/api/intrapi.hxx"
-#include "baseutil/vector/position.hxx"
-#include "baseutil/vector/unitvec.hxx"
-#include "baseutil/vector/box.hxx"
-
-#else
#include "kernapi.hxx"
#include "datamsc.hxx"
#include "cstrapi.hxx"
@@ -43,7 +29,6 @@
#include "unitvec.hxx"
#include "box.hxx"
#include "mprop.hxx"
-#endif
// ********** END ACIS INCLUDES **********
// ********** BEGIN CUBIT INCLUDES **********
@@ -51,6 +36,7 @@
#include "attrib_snl_simple.hpp"
#include "AcisQueryEngine.hpp"
+#include "AcisToolUtil.hpp"
#include "LumpACIS.hpp"
#include "CastTo.hpp"
#include "CubitString.hpp"
@@ -292,7 +278,60 @@
return CUBIT_SUCCESS;
}
+CubitStatus LumpACIS::mass_properties( CubitVector principal_axes[3],
+ CubitVector &principal_moments,
+ CubitVector ¢roid,
+ double &volume )
+{
+ // Create a temporary ACIS BODY using a temporary copy of this LUMP
+ // and ask ACIS to compute the volume of that BODY. The reason this
+ // needs to be done is that ACIS does not provide a function to
+ // compute the volume of a LUMP. This is wrapped with an API_NOP macro
+ // so that ACIS rolls back to destroy the new temporary objects
+ // created during this operation.
+ API_NOP_BEGIN; // This "prevents" any changes from occurring to the BODY
+ // upto the corresponding API_NOP_END
+
+ // Make a BODY from this LUMP. Note that this modifies the input LUMP
+ // which is one of the reasons for having the API_NOP macros.
+ get_LUMP_ptr()->set_next(( LUMP*)NULL );
+ BODY* BODYPtr = new BODY(get_LUMP_ptr());
+ mass_props volume_props;
+ mass_props_options volume_props_options;
+ volume_props_options.set_level(VOLUME_CENTROID_AND_INERTIA);
+
+ outcome result = api_body_mass_props( BODYPtr, volume_props, &volume_props_options );
+ if( !result.ok() )
+ return CUBIT_FAILURE;
+
+ volume = volume_props.get_volume();
+ SPAposition tmp_centroid = volume_props.get_centroid();
+ centroid.set( tmp_centroid.x(), tmp_centroid.y(), tmp_centroid.z() );
+
+ // get the principal axes out of the results
+ SPAunit_vector p_axes[3];
+ volume_props.get_p_axes(p_axes);
+
+ // load the axes into the CubitVector array
+ SPAunit_vector x_axis = p_axes[0];
+ SPAunit_vector y_axis = p_axes[1];
+ SPAunit_vector z_axis = p_axes[2];
+ principal_axes[0].set(x_axis.x(), x_axis.y(), x_axis.z());
+ principal_axes[1].set(y_axis.x(), y_axis.y(), y_axis.z());
+ principal_axes[2].set(z_axis.x(), z_axis.y(), z_axis.z());
+
+ // get the principal moments of inertia
+ double p_moments[3];
+ volume_props.get_p_moments(p_moments);
+ principal_moments.set(p_moments[0], p_moments[1], p_moments[2]);
+
+ API_NOP_END;
+
+ return CUBIT_SUCCESS;
+}
+
+
//-------------------------------------------------------------------------
// Purpose : Checks the validity of this lump
//
@@ -305,10 +344,9 @@
int LumpACIS::validate(const CubitString &entity_name,
DLIList <TopologyEntity*> &bad_entities)
{
- ENTITY_LIST entity_list;
- FILE *file_ptr = NULL;
- outcome result = api_check_entity(get_LUMP_ptr(), &entity_list, file_ptr);
- if ( result.ok() && entity_list.count() == 0 )
+ insanity_list *entity_list = NULL;
+ outcome result = api_check_entity(get_LUMP_ptr(), entity_list );
+ if ( result.ok() && entity_list == NULL )
{
return 0;
}
@@ -317,9 +355,10 @@
get_acis_query_engine()->ACIS_API_error(result);
}
- if ( entity_list.count() )
+ if ( entity_list )
{
- convert_entity_list( entity_list, bad_entities );
+ AcisToolUtil::convert_entity_list( entity_list, bad_entities );
+ AcisToolUtil::show_bad_geom( bad_entities, entity_name );
PRINT_ERROR("with '%s' in the ACIS geometry.\n",
entity_name.c_str());
}
@@ -329,20 +368,6 @@
return 1;
}
-void LumpACIS::convert_entity_list( ENTITY_LIST &ent_list,
- DLIList <TopologyEntity*> &topo_entity_list)
-{
- TopologyEntity* te_ptr = NULL;
- int i;
- for (i=0;i<ent_list.count();i++)
- {
- te_ptr = ATTRIB_CUBIT_OWNER::get_topology_entity(ent_list[i]);
- if ( te_ptr != NULL )
- topo_entity_list.append(te_ptr);
- }
-}
-
-
/*
void LumpACIS::bodysms(DLIList<BodySM*> &bodies)
{
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/LumpACIS.hpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/LumpACIS.hpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/LumpACIS.hpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -118,6 +118,16 @@
//- 1.0 for Point
virtual CubitStatus mass_properties( CubitVector ¢roid, double &volume );
+ virtual CubitStatus mass_properties( CubitVector principal_axes[3],
+ CubitVector &principal_moments,
+ CubitVector ¢roid,
+ double &volume );
+ //R CubitStatus - CUBIT_SUCCESS/CUBIT_FAILURE
+ //R - centroid of the lump
+ //R - volume of the lump
+ //R - principal axes of the lump
+ //R - principal moments of inertia of the lump
+ //- Calculated using standard kernel mass property functions
virtual int validate(const CubitString &entity_name,
DLIList <TopologyEntity*> &bad_entities);
@@ -129,14 +139,7 @@
void get_parents_virt( DLIList<TopologyBridge*>& parents );
void get_children_virt( DLIList<TopologyBridge*>& children );
-
-protected:
-private:
- void convert_entity_list(ENTITY_LIST &ent_list,
- DLIList <TopologyEntity*> &topo_entity_list);
- //- From the ent_list, it populates the topo_entity_list with the
- //- related cubit entities from their corrisponding acis entity.
} ;
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/Makefile.am
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/Makefile.am 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/Makefile.am 2010-01-27 02:15:23 UTC (rev 3496)
@@ -24,13 +24,17 @@
AcisFacetManager.cpp \
AcisFeatureEngine.cpp \
AcisHealerTool.cpp \
+ AcisHistory.cpp \
AcisModifyEngine.cpp \
AcisQueryEngine.cpp \
AcisSurfaceTool.cpp \
AcisToolUtil.cpp \
+ AcisTopologyTool.cpp \
AcisTweakTool.cpp \
AcisDrawTool.cpp \
attrib_cubit_owner.cpp \
+ attrib_history.cpp \
+ attrib_history.hpp \
attrib_snl.cpp \
attrib_snl_simple.cpp \
BodyACIS.cpp \
@@ -55,10 +59,12 @@
AcisFacetManager.hpp \
AcisFeatureEngine.hpp \
AcisHealerTool.hpp \
+ AcisHistory.hpp \
AcisModifyEngine.hpp \
AcisQueryEngine.hpp \
AcisSurfaceTool.hpp \
AcisToolUtil.hpp \
+ AcisTopologyTool.hpp \
AcisTweakTool.hpp \
AcisTypes.h \
BodyACIS.hpp \
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/PointACIS.cpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/PointACIS.cpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/PointACIS.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -17,17 +17,10 @@
// ********** END STANDARD INCLUDES **********
// ********** BEGIN ACIS INCLUDES **********
-#if CUBIT_ACIS_VERSION < 1100
-#include "kernel/kernapi/api/kernapi.hxx"
-#include "kernel/kerndata/data/datamsc.hxx"
-#include "kernel/kerndata/top/vertex.hxx"
-#include "kernel/kerndata/geom/point.hxx"
-#else
#include "kernapi.hxx"
#include "datamsc.hxx"
#include "vertex.hxx"
#include "point.hxx"
-#endif
#include "attrib_cubit_owner.hpp"
#include "attrib_snl_simple.hpp"
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/ShellACIS.cpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/ShellACIS.cpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/ShellACIS.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -17,17 +17,10 @@
// ********** END STANDARD INCLUDES **********
// ********** BEGIN ACIS INCLUDES **********
-#if CUBIT_ACIS_VERSION < 1100
-#include "kernel/kernapi/api/kernapi.hxx"
-#include "kernel/kerndata/data/datamsc.hxx"
-#include "kernel/kerndata/top/shell.hxx"
-#include "kernel/kerndata/top/lump.hxx"
-#else
#include "kernapi.hxx"
#include "datamsc.hxx"
#include "shell.hxx"
#include "lump.hxx"
-#endif
// ********** END ACIS INCLUDES **********
// ********** BEGIN CUBIT INCLUDES **********
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/SurfaceACIS.cpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/SurfaceACIS.cpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/SurfaceACIS.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -16,30 +16,8 @@
// ********** END STANDARD INCLUDES **********
// ********** BEGIN ACIS INCLUDES **********
-#if CUBIT_ACIS_VERSION < 1100
-#include "kernel/acis.hxx"
-#include "kernel/kernapi/api/kernapi.hxx"
-#include "kernel/kerndata/data/datamsc.hxx"
-#include "constrct/kernapi/api/cstrapi.hxx"
-#include "intersct/kernapi/api/intrapi.hxx"
-#include "kernel/kernapi/api/api.hxx"
-#include "kernel/kerndata/top/face.hxx"
-#include "kernel/kerndata/top/alltop.hxx"
-#include "kernel/kerndata/geom/allsurf.hxx"
-#include "kernel/kerndata/lists/lists.hxx"
-#include "kernel/kerngeom/surface/surdef.hxx"
-#include "kernel/sg_husk/query/q_wire.hxx"
-#include "kernel/sg_husk/face/faceutil.hxx"
-#include "kernel/kernint/d3_chk/chk_stat.hxx"
-#include "intersct/kerndata/ptinface/ptinface.hxx"
-#include "baseutil/vector/position.hxx"
-#include "baseutil/vector/param.hxx"
-#include "baseutil/vector/vector.hxx"
-#include "baseutil/vector/unitvec.hxx"
-#include "baseutil/vector/interval.hxx"
-
-#else
#include "acis.hxx"
+#include "acistype.hxx"
#include "kernapi.hxx"
#include "datamsc.hxx"
#include "cstrapi.hxx"
@@ -61,7 +39,6 @@
#include "getbox.hxx"
#include "faceutil.hxx"
#include "raytest.hxx"
-#endif
// ********** END ACIS INCLUDES **********
// ********** BEGIN CUBIT INCLUDES **********
@@ -212,6 +189,28 @@
return get_acis_query_engine();
}
+// Get the normalized surface parameter direction associated with
+// the passed in world space direction and position on surface.
+void SurfaceACIS::param_dir(CubitVector &unit_dir_in_world_space,
+ CubitVector &pos_on_surf, double &du, double &dv)
+{
+ du = 0.0;
+ dv = 0.0;
+
+ FACE *FACE_ptr = this->get_FACE_ptr();
+ if(FACE_ptr)
+ {
+ SPAposition foot, pos(pos_on_surf.x(), pos_on_surf.y(), pos_on_surf.z());
+ SPApar_pos uv;
+ SPAunit_vector unit_dir(unit_dir_in_world_space.x(), unit_dir_in_world_space.y(),
+ unit_dir_in_world_space.z());
+ FACE_ptr->geometry()->equation().point_perp(pos, foot, *(SPApar_pos*)NULL_REF, uv);
+ SPApar_dir surf_dir = FACE_ptr->geometry()->equation().param_dir(unit_dir, uv);
+ du = surf_dir.du;
+ dv = surf_dir.dv;
+ }
+}
+
//-------------------------------------------------------------------------
// Purpose : Get the bounding box of the object.
//
@@ -680,7 +679,7 @@
{
// Get the number of LOOPs that bound a FACE of this object.
int num_loops = number_of_LOOPs();
-
+
if ( num_loops == 2 &&
( this->geometry_type() == CONE_SURFACE_TYPE ||
this->geometry_type() == SPHERE_SURFACE_TYPE ||
@@ -1000,28 +999,18 @@
// surface
CubitBoolean alls_well = CUBIT_TRUE;
-// SPApar_box face_range;
+ SPApar_box face_range;
-// API_BEGIN
-// sg_get_face_par_box( FACE_ptr, face_range );
-// API_END
+ API_BEGIN
+ sg_get_face_par_box( FACE_ptr, face_range );
+ API_END
-// // Make sure it is bounded and return the appropriate values
-// if ( face_range.u_range().bounded() )
-// {
-// lower_bound = face_range.u_range().start_pt();
-// upper_bound = face_range.u_range().end_pt();
-// }
- SPAbox *bbox = FACE_ptr->bound();
- SPAinterval u_face_range;
- u_face_range = FACE_ptr->geometry()->equation().param_range_u(*bbox);
-// Make sure it is bounded and return the appropriate values
- if ( u_face_range.bounded() )
- {
- lower_bound = u_face_range.start_pt();
- upper_bound = u_face_range.end_pt();
- }
-
+ // Make sure it is bounded and return the appropriate values
+ if ( face_range.u_range().bounded() )
+ {
+ lower_bound = face_range.u_range().start_pt();
+ upper_bound = face_range.u_range().end_pt();
+ }
// The parameter range is unbounded in one or both directions.
else
{
@@ -1066,28 +1055,18 @@
// surface
CubitBoolean alls_well = CUBIT_TRUE;
-// SPApar_box face_range;
+ SPApar_box face_range;
-// API_BEGIN
-// sg_get_face_par_box( FACE_ptr, face_range );
-// API_END
+ API_BEGIN
+ sg_get_face_par_box( FACE_ptr, face_range );
+ API_END
-// // Make sure it is bounded and return the appropriate values
-// if ( face_range.v_range().bounded() )
-// {
-// lower_bound = face_range.v_range().start_pt();
-// upper_bound = face_range.v_range().end_pt();
-// }
- SPAbox *bbox = FACE_ptr->bound();
- SPAinterval v_face_range;
- v_face_range = FACE_ptr->geometry()->equation().param_range_v(*bbox);
-// Make sure it is bounded and return the appropriate values
- if ( v_face_range.bounded() )
- {
- lower_bound = v_face_range.start_pt();
- upper_bound = v_face_range.end_pt();
- }
-
+ // Make sure it is bounded and return the appropriate values
+ if ( face_range.v_range().bounded() )
+ {
+ lower_bound = face_range.v_range().start_pt();
+ upper_bound = face_range.v_range().end_pt();
+ }
else
{
alls_well = CUBIT_FALSE;
@@ -1157,6 +1136,36 @@
}
//-------------------------------------------------------------------------
+// Purpose : Returns a true if the Surface is a cylinder. This value is
+// determined by ACIS.
+//
+// Special Notes : This code is very ACIS-specific and could change with
+// new versions of ACIS. There are #defines for the
+// various surface type ID's. These are defined in the
+// header files of each of the specific surface classes
+// in ACIS.
+//
+// This was not added into the geometry_type because that
+// function is widely used to verify quadric surface types.
+//
+// Creator : KGM
+//
+// Creation Date : 03/26/07
+//-------------------------------------------------------------------------
+GeometryType SurfaceACIS::is_cylindrical()
+{
+ GeometryType local_type = UNDEFINED_SURFACE_TYPE;
+
+ // Get the first FACE associated with this SurfaceACIS object
+ FACE* FACE_ptr = get_FACE_ptr();
+
+ if (is_cylindrical_face(FACE_ptr))
+ local_type = CYLINDER_SURFACE_TYPE;
+
+ return local_type;
+}
+
+//-------------------------------------------------------------------------
// Purpose : Returns the area of the Surface
//
// Special Notes :
@@ -1241,16 +1250,12 @@
// Let the function figure-out uv coordinates
point_face_containment pf_rel;
-#if CUBIT_ACIS_VERSION < 1100
- pf_rel = point_in_face( test_point, FACE_ptr, ftrans );
-#else
outcome r = api_point_in_face( test_point, FACE_ptr, ftrans, pf_rel );
if (!r.ok())
{
PRINT_ERROR("ACIS api_point_in_face failed.\n");
return CUBIT_PNT_UNKNOWN;
}
-#endif
switch( pf_rel )
{
@@ -1279,16 +1284,12 @@
point_face_containment pf_rel;
-#if CUBIT_ACIS_VERSION < 1100
- pf_rel = point_in_face( test_point, FACE_ptr, ftrans, test_uv);
-#else
outcome r = api_point_in_face( test_point, FACE_ptr, ftrans, pf_rel, test_uv );
if (!r.ok())
{
PRINT_ERROR("ACIS api_point_in_face failed.\n");
return CUBIT_PNT_UNKNOWN;
}
-#endif
switch( pf_rel )
{
@@ -1317,16 +1318,12 @@
SPAtransf ftrans;
point_face_containment pf_rel;
-#if CUBIT_ACIS_VERSION < 1100
- pf_rel = point_in_face( test_point, FACE_ptr, ftrans, test_uv);
-#else
outcome r = api_point_in_face( test_point, FACE_ptr, ftrans, pf_rel, test_uv );
if (!r.ok())
{
PRINT_ERROR("ACIS api_point_in_face failed.\n");
return CUBIT_PNT_UNKNOWN;
}
-#endif
switch( pf_rel )
{
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/SurfaceACIS.hpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/SurfaceACIS.hpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/SurfaceACIS.hpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -83,6 +83,9 @@
void set_FACE_ptr(FACE* FACE_ptr);
//- I FACE_ptr - The FACE to be associated with this object.
//- It replaces any previous FACE.
+
+ virtual void param_dir(CubitVector &unit_dir_in_world_space,
+ CubitVector &pos_on_surf, double &du, double &dv);
virtual void append_simple_attribute_virt(CubitSimpleAttrib*);
//R void
@@ -384,6 +387,10 @@
//R GeometryType (enum)
//R- The enumerated type of the geometric representation
+ GeometryType is_cylindrical();
+ //R GeometryType (enum)
+ //R- CYLINDRICAL_SURFACE_TYPE if true else UNDEFINED_SURFACE_TYPE
+
virtual double measure();
//R double
//R- The numeric value of the measure (its units depend on the dimension
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/UseACIS.cmake
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/UseACIS.cmake 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/UseACIS.cmake 2010-01-27 02:15:23 UTC (rev 3496)
@@ -7,15 +7,10 @@
# ACIS_LIBS, ACIS_DEBUG_LIBS, ACIS_RELEASE_LIBS
# also automatically add -D definitions for compiling
+IF(NOT CUBITROOT)
+ MESSAGE(ERROR "CUBITROOT not set")
+ENDIF(NOT CUBITROOT)
-IF(UNIX)
- SET(CUBITROOT $ENV{CUBIT})
-ELSE(UNIX)
- SET(CUBITROOT $ENV{CUBITROOT})
-ENDIF(UNIX)
-
-STRING(REGEX REPLACE "\\\\" "/" CUBITROOT "${CUBITROOT}")
-
# allow override of ACIS_DIR
IF(NOT MYOWN_ACIS_DIR)
SET(MYOWN_ACIS_DIR "" CACHE PATH "")
@@ -24,17 +19,22 @@
SET(ACIS_DIR ${MYOWN_ACIS_DIR})
ENDIF(MYOWN_ACIS_DIR)
+IF(CMAKE_COMPILER_IS_GNUCXX)
+ IF(NOT GNUCXX_VERSION)
+ EXEC_PROGRAM(${CMAKE_CXX_COMPILER}
+ ARGS -dumpversion OUTPUT_VARIABLE output_version)
+ SET(GNUCXX_VERSION ${output_version} CACHE STRING "gcc version")
+ ENDIF(NOT GNUCXX_VERSION)
+ENDIF(CMAKE_COMPILER_IS_GNUCXX)
+
# if ACIS_DIR isn't set yet, then we'll set the default
IF(NOT ACIS_DIR)
- IF(CMAKE_SYSTEM MATCHES "IRIX")
- SET(ACIS_DIR ${CUBITROOT}/acis/acis14.1)
- ELSE(CMAKE_SYSTEM MATCHES "IRIX")
- IF(CMAKE_SYSTEM MATCHES "Darwin")
- SET(ACIS_DIR ${CUBITROOT}/acis/acis16.3)
- ELSE(CMAKE_SYSTEM MATCHES "Darwin")
- SET(ACIS_DIR ${CUBITROOT}/acis/acis16.1)
- ENDIF(CMAKE_SYSTEM MATCHES "Darwin")
- ENDIF(CMAKE_SYSTEM MATCHES "IRIX")
+ SET(ACIS_DIR ${CUBITROOT}/acis/acis19.2)
+ IF(CMAKE_SYSTEM MATCHES "Linux")
+ IF(GNUCXX_VERSION MATCHES "^3\\.")
+ SET(ACIS_DIR ${CUBITROOT}/acis/acis17.2)
+ ENDIF(GNUCXX_VERSION MATCHES "^3\\.")
+ ENDIF(CMAKE_SYSTEM MATCHES "Linux")
ENDIF(NOT ACIS_DIR)
# allow override of acis version
@@ -45,131 +45,215 @@
SET(ACIS_VERSION ${MYOWN_ACIS_VERSION})
ENDIF(MYOWN_ACIS_VERSION)
-# default to version 1601, 1401 for SGI, 1603 for Mac
+# default to version of acis
IF(NOT ACIS_VERSION)
- IF(CMAKE_SYSTEM MATCHES "IRIX")
- SET(ACIS_VERSION 1401)
- ELSE(CMAKE_SYSTEM MATCHES "IRIX")
- IF(CMAKE_SYSTEM MATCHES "Darwin")
- SET(ACIS_VERSION 1603)
- ELSE(CMAKE_SYSTEM MATCHES "Darwin")
- SET(ACIS_VERSION 1601)
- ENDIF(CMAKE_SYSTEM MATCHES "Darwin")
- ENDIF(CMAKE_SYSTEM MATCHES "IRIX")
+ SET(ACIS_VERSION 1902)
+ IF(CMAKE_SYSTEM MATCHES "Linux")
+ IF(GNUCXX_VERSION MATCHES "^3\\.")
+ SET(ACIS_VERSION 1702)
+ ENDIF(GNUCXX_VERSION MATCHES "^3\\.")
+ ENDIF(CMAKE_SYSTEM MATCHES "Linux")
ENDIF(NOT ACIS_VERSION)
# set the include directory
SET (ACIS_INCLUDE_DIR ${ACIS_DIR}/include)
-SET(ACIS_LIBS)
+IF(ACIS_VERSION LESS 1900)
+ # acis step interop libraries
+ SET(ACIS_STEP_LIBS acisstep xstep)
+ # acis iges interop libraries
+ SET(ACIS_IGES_LIBS acisiges xiges)
+ELSE(ACIS_VERSION LESS 1900)
+ # acis step interop libraries
+ SET(ACIS_STEP_LIBS xstep)
+ # acis iges interop libraries
+ SET(ACIS_IGES_LIBS xiges)
+ENDIF(ACIS_VERSION LESS 1900)
-IF(NOT BUILD_64)
-OPTION(ACIS_STEP "Build with ACIS STEP Translator" ON)
-IF(ACIS_STEP)
- ADD_DEFINITIONS(-DACIS_STEP_TRANSLATOR)
- SET(ACIS_LIBS ${ACIS_LIBS} acisstep xstep)
-ENDIF(ACIS_STEP)
-ENDIF(NOT BUILD_64)
+# acis interop libraries
+SET(ACIS_INTEROP_LIBS xacis2k xcore2k SPAXAcisBase SPAXAssemblyRep SPAXDefaultGeometryRep SPAXInterop SPAXBase)
+IF(NOT ACIS_VERSION LESS 1600)
+ SET(ACIS_INTEROP_LIBS ${ACIS_INTEROP_LIBS} SPAXGeometryRepresentation)
+ENDIF(NOT ACIS_VERSION LESS 1600)
+IF(NOT ACIS_VERSION LESS 1900)
+ SET(ACIS_INTEROP_LIBS ${ACIS_INTEROP_LIBS} SPAXAcisKernel icuio38 icuin38 icuuc38 )
+ SET(ACIS_INTEROP_LIBS_EXTRA icudt38)
+ENDIF(NOT ACIS_VERSION LESS 1900)
-IF(NOT BUILD_64)
-OPTION(ACIS_IGES "Build with ACIS IGES Translator" ON)
-IF(ACIS_IGES)
- ADD_DEFINITIONS(-DACIS_IGES_TRANSLATOR)
- SET(ACIS_LIBS ${ACIS_LIBS} acisiges xiges)
-ENDIF(ACIS_IGES)
-ENDIF(NOT BUILD_64)
-
-#IF(NOT BUILD_64)
-#OPTION(ACIS_HEALER "Build with ACIS Healer" ON)
-##IF(ACIS_HEALER)
- ADD_DEFINITIONS(-DACIS_HEALER)
- # hmm what are the healer libs?
- #SET(ACIS_LIBS ${ACIS_LIBS} xiges acisiges)
-#ENDIF(ACIS_HEALER)
-#ENDIF(NOT BUILD_64)
-
-
-IF(NOT BUILD_64)
- IF(ACIS_STEP OR ACIS_IGES)
- SET(ACIS_LIBS ${ACIS_LIBS} xacis2k xcore2k SPAXAcisBase SPAXAssemblyRep SPAXDefaultGeometryRep SPAXInterop SPAXBase )
- IF(ACIS_VERSION GREATER 1600)
- SET(ACIS_LIBS ${ACIS_LIBS} SPAXGeometryRepresentation)
- ENDIF(ACIS_VERSION GREATER 1600)
- ENDIF(ACIS_STEP OR ACIS_IGES)
-ENDIF(NOT BUILD_64)
-
-SET(ACIS_LIBS ${ACIS_LIBS}
- SpaAVis SpaAWarp SpaASurf SpaALops SpaABlend SpaACIS SpaBase )
-
-
+# basic acis libraries
+SET(ACIS_CORE_LIBS SpaAVis SpaAWarp SpaASurf SpaALops SpaABlend SpaAAsm SpaACIS SpaBase )
+
IF(WIN32)
-# .Net acis libs have n in their names
- IF(NOT ${CMAKE_GENERATOR} MATCHES "Visual Studio 6")
+
+ #add in the license library we need....only on windows
+ SET(ACIS_CORE_LIBS ${ACIS_CORE_LIBS} SpaLicExtBase )
+ SET(ACIS_LIB_EXT ".lib")
+ SET(ACIS_LIB_PREFIX "")
+ SET(ACIS_DEBUG_SUFFIX d)
+
+ # .Net acis libs have n in their names
+ IF(MSVC70 OR MSVC71)
SET(ACIS_LIB_SUFFIX n)
SET(ACIS_DIR_ADD _NET)
- ENDIF(NOT ${CMAKE_GENERATOR} MATCHES "Visual Studio 6")
+ ENDIF(MSVC70 OR MSVC71)
+
+ IF(MSVC80)
+ SET(ACIS_DIR_ADD _VC8)
+ SET(ACIS_LIB_SUFFIX)
+ IF(CMAKE_C_SIZEOF_DATA_PTR MATCHES 8)
+ SET(ACIS_DIR_ADD _AMD_64)
+ SET(ACIS_LIB_SUFFIX a)
+ ENDIF(CMAKE_C_SIZEOF_DATA_PTR MATCHES 8)
+ ENDIF(MSVC80)
- SET(TMP_ACIS_LIB_DIR ${ACIS_DIR}/lib)
+ IF(MSVC90)
+ SET(ACIS_DIR_ADD _VC9)
+ SET(ACIS_LIB_SUFFIX)
+ IF(CMAKE_C_SIZEOF_DATA_PTR MATCHES 8)
+ SET(ACIS_DIR_ADD _AMD_64)
+ SET(ACIS_LIB_SUFFIX a)
+ ENDIF(CMAKE_C_SIZEOF_DATA_PTR MATCHES 8)
+ ENDIF(MSVC90)
+
+
SET(ACIS_LIBRARY_DIR ${ACIS_DIR}/lib/NT${ACIS_DIR_ADD}_DLL)
SET(ACIS_LIBRARY_DIR_DEBUG ${ACIS_DIR}/lib/NT${ACIS_DIR_ADD}_DLLD)
- SET(ACIS_DEBUG_LIBS)
- SET(ACIS_RELEASE_LIBS)
+
+ELSE(WIN32)
- FOREACH(var ${ACIS_LIBS})
- SET(ACIS_DEBUG_LIBS ${ACIS_DEBUG_LIBS} ${var}${ACIS_LIB_SUFFIX}d)
-
- SET(ACIS_RELEASE_LIBS ${ACIS_RELEASE_LIBS} ${var}${ACIS_LIB_SUFFIX})
- ENDFOREACH(var ${ACIS_LIBS})
- SET(ACIS_LIBS)
- FOREACH(var ${ACIS_DEBUG_LIBS})
- SET(ACIS_LIBS ${ACIS_LIBS} debug ${var})
- ENDFOREACH(var ${ACIS_DEBUG_LIBS})
- FOREACH(var ${ACIS_RELEASE_LIBS})
- SET(ACIS_LIBS ${ACIS_LIBS} optimized ${var})
- ENDFOREACH(var ${ACIS_RELEASE_LIBS})
+ SET(ACIS_LIB_EXT ${CMAKE_SHARED_LIBRARY_SUFFIX})
+ SET(ACIS_LIB_PREFIX "lib")
-ENDIF(WIN32)
-
-IF(UNIX)
# based on the system, define where the acis libraries are
IF(CMAKE_SYSTEM MATCHES "Linux")
SET(ACIS_ARCH linux)
- IF(BUILD_64)
+ IF(CMAKE_C_SIZEOF_DATA_PTR MATCHES 8)
SET (ACIS_SYSTEM linux_amd_64_so)
- ELSE(BUILD_64)
+ ELSE(CMAKE_C_SIZEOF_DATA_PTR MATCHES 8)
SET (ACIS_SYSTEM linux_so)
- ENDIF(BUILD_64)
+ ENDIF(CMAKE_C_SIZEOF_DATA_PTR MATCHES 8)
ENDIF(CMAKE_SYSTEM MATCHES "Linux")
- IF(CMAKE_SYSTEM MATCHES "Darwin")
- SET(ACIS_SYSTEM macho)
- SET(ACIS_ARCH mac)
+ IF(CMAKE_SYSTEM MATCHES "Darwin")
+ SET(ACIS_SYSTEM maci386)
+ SET(ACIS_ARCH mac)
ENDIF(CMAKE_SYSTEM MATCHES "Darwin")
+ SET (ACIS_LIBRARY_DIR ${ACIS_DIR}/bin/${ACIS_SYSTEM})
+ SET (ACIS_LIBRARY_DIR_DEBUG ${ACIS_DIR}/bin/${ACIS_SYSTEM})
- IF(CMAKE_SYSTEM MATCHES "SunOS")
- SET(ACIS_SYSTEM solaris_so)
- SET(ACIS_ARCH solaris)
- ENDIF(CMAKE_SYSTEM MATCHES "SunOS")
+ENDIF(WIN32)
- IF(CMAKE_SYSTEM MATCHES "IRIX")
- SET(ACIS_ARCH sgi)
- IF(BUILD_64)
- SET (ACIS_SYSTEM sgi_64_so)
- ELSE(BUILD_64)
- SET (ACIS_SYSTEM sgi_so)
- ENDIF(BUILD_64)
- ENDIF(CMAKE_SYSTEM MATCHES "IRIX")
- IF(CMAKE_SYSTEM MATCHES "HP-UX")
- SET(ACIS_ARCH hp700)
- SET(ACIS_SYSTEM hp700_11_so)
- ENDIF(CMAKE_SYSTEM MATCHES "HP-UX")
+FOREACH(libgroup ACIS_CORE_LIBS ACIS_INTEROP_LIBS ACIS_STEP_LIBS ACIS_IGES_LIBS)
+ SET(${libgroup}_DEBUG)
+ SET(${libgroup}_RELEASE)
+ SET(${libgroup}_EXISTS OFF)
+ FOREACH(lib ${${libgroup}})
+ SET(tmp_debug_lib
+ "${ACIS_LIBRARY_DIR_DEBUG}/${ACIS_LIB_PREFIX}${lib}${ACIS_LIB_SUFFIX}${ACIS_DEBUG_SUFFIX}${ACIS_LIB_EXT}")
+ SET(tmp_release_lib
+ "${ACIS_LIBRARY_DIR}/${ACIS_LIB_PREFIX}${lib}${ACIS_LIB_SUFFIX}${ACIS_LIB_EXT}")
- SET (ACIS_LIBRARY_DIR ${ACIS_DIR}/bin/${ACIS_SYSTEM})
-ENDIF(UNIX)
+ IF(EXISTS "${tmp_debug_lib}" AND EXISTS "${tmp_release_lib}")
+ SET(${libgroup}_EXISTS ON)
+ SET(${libgroup}_DEBUG ${${libgroup}_DEBUG} "${tmp_debug_lib}")
+ SET(${libgroup}_RELEASE ${${libgroup}_RELEASE} "${tmp_release_lib}")
+ ENDIF(EXISTS "${tmp_debug_lib}" AND EXISTS "${tmp_release_lib}")
+ ENDFOREACH(lib)
+ENDFOREACH(libgroup)
+# this list of libs has no 'd' suffix
+SET(ACIS_INTEROP_LIBS_EXTRA_DEBUG)
+SET(ACIS_INTEROP_LIBS_EXTRA_RELEASE)
+FOREACH(var ${ACIS_INTEROP_LIBS_EXTRA})
+ SET(ACIS_INTEROP_LIBS_EXTRA_DEBUG ${ACIS_INTEROP_LIBS_EXTRA_DEBUG}
+ "${ACIS_LIBRARY_DIR_DEBUG}/${ACIS_LIB_PREFIX}${var}${ACIS_LIB_EXT}")
+ SET(ACIS_INTEROP_LIBS_EXTRA_RELEASE ${ACIS_INTEROP_LIBS_EXTRA_RELEASE}
+ "${ACIS_LIBRARY_DIR}/${ACIS_LIB_PREFIX}${var}${ACIS_LIB_EXT}")
+ENDFOREACH(var ${ACIS_INTEROP_LIBS_EXTRA})
+
+
+IF(ACIS_INTEROP_LIBS_EXISTS)
+ OPTION(ACIS_STEP "Build with ACIS STEP Translator, if available" ON)
+ OPTION(ACIS_IGES "Build with ACIS IGES Translator, if available" ON)
+ELSE(ACIS_INTEROP_LIBS_EXISTS)
+ IF(ACIS_STEP OR ACIS_IGES)
+ MESSAGE(STATUS "Ignoring ACIS_STEP and ACIS_IGES options because libraries not found")
+ ENDIF(ACIS_STEP OR ACIS_IGES)
+ SET(ACIS_STEP OFF)
+ SET(ACIS_IGES OFF)
+ENDIF(ACIS_INTEROP_LIBS_EXISTS)
+
+# now fill in public variables
+SET(ACIS_LIBS)
+SET(ACIS_DEBUG_LIBS)
+SET(ACIS_RELEASE_LIBS)
+
+IF(ACIS_IGES)
+ FOREACH(lib ${ACIS_IGES_LIBS_DEBUG})
+ SET(ACIS_DEBUG_LIBS ${ACIS_DEBUG_LIBS} "${lib}")
+ ENDFOREACH(lib ${ACIS_IGES_LIBS_DEBUG})
+ FOREACH(lib ${ACIS_IGES_LIBS_RELEASE})
+ SET(ACIS_RELEASE_LIBS ${ACIS_RELEASE_LIBS} "${lib}")
+ ENDFOREACH(lib ${ACIS_IGES_LIBS_RELEASE})
+ENDIF(ACIS_IGES)
+
+IF(ACIS_STEP)
+ FOREACH(lib ${ACIS_STEP_LIBS_DEBUG})
+ SET(ACIS_DEBUG_LIBS ${ACIS_DEBUG_LIBS} "${lib}")
+ ENDFOREACH(lib ${ACIS_STEP_LIBS_DEBUG})
+ FOREACH(lib ${ACIS_STEP_LIBS_RELEASE})
+ SET(ACIS_RELEASE_LIBS ${ACIS_RELEASE_LIBS} "${lib}")
+ ENDFOREACH(lib ${ACIS_STEP_LIBS_RELEASE})
+ENDIF(ACIS_STEP)
+
+IF(ACIS_STEP OR ACIS_IGES)
+ FOREACH(lib ${ACIS_INTEROP_LIBS_DEBUG})
+ SET(ACIS_DEBUG_LIBS ${ACIS_DEBUG_LIBS} "${lib}")
+ ENDFOREACH(lib ${ACIS_INTEROP_LIBS_DEBUG})
+ FOREACH(lib ${ACIS_INTEROP_LIBS_RELEASE})
+ SET(ACIS_RELEASE_LIBS ${ACIS_RELEASE_LIBS} "${lib}")
+ ENDFOREACH(lib ${ACIS_INTEROP_LIBS_RELEASE})
+
+ FOREACH(lib ${ACIS_INTEROP_LIBS_EXTRA_DEBUG})
+ SET(ACIS_DEBUG_LIBS ${ACIS_DEBUG_LIBS} "${lib}")
+ ENDFOREACH(lib ${ACIS_INTEROP_LIBS_EXTRA_DEBUG})
+ FOREACH(lib ${ACIS_INTEROP_LIBS_EXTRA_RELEASE})
+ SET(ACIS_RELEASE_LIBS ${ACIS_RELEASE_LIBS} "${lib}")
+ ENDFOREACH(lib ${ACIS_INTEROP_LIBS_EXTRA_RELEASE})
+ENDIF(ACIS_STEP OR ACIS_IGES)
+
+IF(NOT ACIS_CORE_LIBS_EXISTS)
+ MESSAGE(SEND_ERROR "Couldn't find acis libraries in ${ACIS_LIBRARY_DIR}")
+ENDIF(NOT ACIS_CORE_LIBS_EXISTS)
+
+FOREACH(lib ${ACIS_CORE_LIBS_DEBUG})
+ SET(ACIS_DEBUG_LIBS ${ACIS_DEBUG_LIBS} "${lib}")
+ENDFOREACH(lib ${ACIS_CORE_LIBS_DEBUG})
+FOREACH(lib ${ACIS_CORE_LIBS_RELEASE})
+ SET(ACIS_RELEASE_LIBS ${ACIS_RELEASE_LIBS} "${lib}")
+ENDFOREACH(lib ${ACIS_CORE_LIBS_RELEASE})
+
+
+FOREACH(var ${ACIS_DEBUG_LIBS})
+ SET(ACIS_LIBS ${ACIS_LIBS} debug ${var})
+ENDFOREACH(var ${ACIS_DEBUG_LIBS})
+FOREACH(var ${ACIS_RELEASE_LIBS})
+ SET(ACIS_LIBS ${ACIS_LIBS} optimized ${var})
+ENDFOREACH(var ${ACIS_RELEASE_LIBS})
+
+IF(ACIS_STEP)
+ ADD_DEFINITIONS(-DACIS_STEP_TRANSLATOR)
+ENDIF(ACIS_STEP)
+
+IF(ACIS_IGES)
+ ADD_DEFINITIONS(-DACIS_IGES_TRANSLATOR)
+ENDIF(ACIS_IGES)
+
+ADD_DEFINITIONS(-DACIS_TWEAK)
+ADD_DEFINITIONS(-DACIS_HEALER)
ADD_DEFINITIONS(-DACIS_3D -DACIS_LOCAL_OPS)
ADD_DEFINITIONS(-DACIS${ACIS_VERSION} -DCUBIT_ACIS_VERSION=${ACIS_VERSION})
IF(UNIX)
@@ -178,6 +262,7 @@
ENDIF(UNIX)
IF(WIN32)
ADD_DEFINITIONS(-DACIS_DLL -DSPA_NO_AUTO_LINK)
+ # no auto link to make us consistent in specifying library dependencies
ENDIF(WIN32)
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_cubit_owner.cpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_cubit_owner.cpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_cubit_owner.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -15,17 +15,10 @@
// ********** END STANDARD INCLUDES **********
// ********** BEGIN ACIS INCLUDES **********
-#if CUBIT_ACIS_VERSION < 1100
-#include "kernel/kernapi/api/api.hxx"
-#include "kernel/kerndata/data/datamsc.hxx"
-#include "kernel/kerndata/geom/transfrm.hxx"
-#include "kernel/kerndata/bulletin/bulletin.hxx"
-#else
#include "api.hxx"
#include "datamsc.hxx"
#include "transfrm.hxx"
#include "bulletin.hxx"
-#endif
// ********** END ACIS INCLUDES **********
// ********** BEGIN CUBIT INCLUDES **********
@@ -76,6 +69,7 @@
// ********** END MACRO DEFINITIONS **********
bool ATTRIB_CUBIT_OWNER::copyingAttribs = true;
+bool ATTRIB_CUBIT_OWNER::splitCopy = false;
// make a cubit_owner attribute
ATTRIB_CUBIT_OWNER::ATTRIB_CUBIT_OWNER(ENTITY* owner,
@@ -217,24 +211,25 @@
ATTRIB_SNL_TYPE,
ATTRIB_CUBIT_OWNER_TYPE);
- // If the attribute is found, remove it. In the following code
- // block, a do-while structure is used to ensure that all such
- // attributes are removed. At present, at most 1 CUBIT_OWNER
- // attribute is allowed, per ACIS ENTITY.
+ //collect all the attributes..
+ DLIList<ATTRIB_CUBIT_OWNER*> owner_attribs;
while (ATTRIB_ptr != NULL)
{
- // "unhook" this attribute from the ENTITY (i.e., remove it from
- // the list of attributes associated with this ENTITY
- API_BEGIN;
- ATTRIB_ptr->unhook();
- API_END;
-
- // Find the next CUBIT_OWNER attribute attached to this ENTITY
- ATTRIB_ptr =
- (ATTRIB_CUBIT_OWNER *) find_attrib(ENTITY_ptr,
- ATTRIB_SNL_TYPE,
- ATTRIB_CUBIT_OWNER_TYPE);
+ owner_attribs.append( ATTRIB_ptr );
+
+ ATTRIB_ptr =
+ (ATTRIB_CUBIT_OWNER *) find_next_attrib( ATTRIB_ptr,
+ ATTRIB_SNL_TYPE,
+ ATTRIB_CUBIT_OWNER_TYPE);
}
+
+ //now unhook them
+ while( owner_attribs.size() )
+ {
+ API_BEGIN;
+ owner_attribs.pop()->unhook();
+ API_END;
+ }
}
}
@@ -244,20 +239,21 @@
// a FACE is copied without also copying a LUMP to attach it to.
void ATTRIB_CUBIT_OWNER::split_owner(ENTITY *entity)
{
-// PRINT_INFO("split_owner called for attrib_cubit_owner on ");
+ //PRINT_INFO("split_owner called for attrib_cubit_owner on ");
// must get simple attributes for new entity from CubitAttribUser
if (!cubitOwnerData)
return;
TopologyBridge* tb = CAST_TO(cubitOwnerData, TopologyBridge);
-// CubitEntity* cep = CAST_TO(tb->topology_entity(), CubitEntity);
-// if (cep)
-// PRINT_INFO("%s %d\n",
-// cep->class_name(),
-// cep->id());
-// else
-// PRINT_INFO("unknown ENTITY.\n");
+ //CubitEntity* cep = CAST_TO(tb->topology_entity(), CubitEntity);
+ // if (cep)
+ // PRINT_INFO("%s %d\n",
+ // cep->class_name(),
+ // cep->id());
+ // else
+ // PRINT_INFO("unknown ENTITY.\n");
+
CubitAttribUser *cau = CAST_TO(tb->topology_entity(), CubitAttribUser);
if (cau != NULL && cau->num_cubit_attrib() != 0)
@@ -275,13 +271,26 @@
API_BEGIN;
new ATTRIB_SNL_SIMPLE ( entity, csa_ptr );
API_END;
+ delete csa_ptr;
}
}
}
-
+
+ if( splitCopy )
+ {
+ // Copy to the new entity. In some operations, such as a fillet, chamfer
+ // or multi-tweak, entities are split then one of the resultant entities is
+ // thrown away. We want to keep the cubit owner on the kept entity to
+ // preserve ids, so this special circumstance was created. This is
+ // analogous to a SplitCopy in the ACIS ATTRIB class.
+ ATTRIB_CUBIT_OWNER::set_cubit_owner( entity, cubitOwnerData );
+ }
+ else
+ {
// in the case of a split, lose this attribute
- unhook();
- lose();
+ unhook();
+ lose();
+ }
}
void ATTRIB_CUBIT_OWNER::set_copyable( bool copying_attribs )
@@ -295,13 +304,24 @@
return copyingAttribs;
}
+bool ATTRIB_CUBIT_OWNER::get_split_copy()
+{
+ return splitCopy;
+}
+bool ATTRIB_CUBIT_OWNER::set_split_copy( bool split_copy )
+{
+ bool old_splitCopy = splitCopy;
+ splitCopy = split_copy;
+ return old_splitCopy;
+}
+
// Virtual function called when two entities are to be merged,
// as may happen with 'unite'
void ATTRIB_CUBIT_OWNER::merge_owner(ENTITY *other_entity,
logical delete_this)
{
-// PRINT_INFO("merge_owner called for attrib_cubit_owner.\n");
+ //PRINT_INFO("merge_owner called for attrib_cubit_owner.\n");
// Handle merging via the survivor
if (delete_this)
return;
@@ -310,6 +330,12 @@
if (!cubitOwnerData)
return;
TopologyBridge* tb = CAST_TO(cubitOwnerData, TopologyBridge);
+ if(tb)
+ {
+ TopologyBridge *tb_owner;
+ while((tb_owner = dynamic_cast<TopologyBridge*>(tb->owner())))
+ tb = tb_owner;
+ }
CubitAttribUser *cau =
(tb ? CAST_TO(tb->topology_entity(), CubitAttribUser) :
NULL);
@@ -324,8 +350,15 @@
RefEntity *ref_entity = NULL;
if (other_owner_att && other_owner_att->cubit_owner()) {
tb = CAST_TO(other_owner_att->cubit_owner(), TopologyBridge);
+ if(tb)
+ {
+ TopologyBridge *tb_owner;
+ while((tb_owner = dynamic_cast<TopologyBridge*>(tb->owner())))
+ tb = tb_owner;
+ }
ref_entity = CAST_TO(tb->topology_entity(), RefEntity);
- assert(ref_entity != NULL);
+
+ //assert(ref_entity != NULL);
}
cau->merge_owner(ref_entity);
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_cubit_owner.hpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_cubit_owner.hpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_cubit_owner.hpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -74,12 +74,21 @@
virtual void to_tolerant_owner( ENTITY *tol_ent );
static void set_copyable( bool copying_attribs );
+
+ static bool get_split_copy();
+ static bool set_split_copy( bool split_copy );
+ //- Methods to get and set the split_owner behavior for the cubit owner
+ //- attribute. If true, the cubit owner attribute is copied to the new
+ //- entity during a split operation, otherwise it is lost. The set method
+ //- returns the previous value of the flag. Default is false (the cubit
+ //- owner attribute is lost when an entity is split).
ATTRIB_FUNCTIONS(ATTRIB_CUBIT_OWNER, NONE)
private:
AcisBridge *cubitOwnerData;
static bool copyingAttribs;
+ static bool splitCopy;
};
#endif
Copied: cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_history.cpp (from rev 3491, cgm/branches/cubit/geom/ACIS_SRC/attrib_history.cpp)
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_history.cpp (rev 0)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_history.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -0,0 +1,402 @@
+
+#include "attrib_history.hpp"
+#include "CubitMessage.hpp"
+#include "AcisHistory.hpp"
+
+// ********** BEGIN ACIS INCLUDES **********
+#include "api.hxx"
+#include "datamsc.hxx"
+#include "transfrm.hxx"
+#include "bulletin.hxx"
+#include "acistype.hxx"
+// ********** END ACIS INCLUDES **********
+
+// ********** BEGIN MACRO DEFINITIONS **********
+#define THIS() ATTRIB_HISTORY
+#define THIS_LIB NONE
+#define PARENT() ATTRIB_SNL
+#define PARENT_LIB NONE
+
+#define ATTRIB_HISTORY_NAME "history"
+
+//ATTRIB_DEF("history_attribute")
+
+int ATTRIB_HISTORY::num_attribs = 0;
+bool ATTRIB_HISTORY::addOrRemoveFromList = true;
+std::set<ATTRIB_HISTORY*> ATTRIB_HISTORY::allHistoryAttribs;
+
+//When acis backs up this attribute, it gets to this macro right after exiting
+//the constructor. Here we remove the backed-up history attribute from our list
+//since Acis takes care of destroying all backed-up attributes.
+ATTCOPY_DEF("history_attribute")
+ ATTRIB_HISTORY *history_attrib = const_cast<ATTRIB_HISTORY*>(rollback);
+ std::set<ATTRIB_HISTORY*>::iterator iter;
+ iter = allHistoryAttribs.find( history_attrib );
+ if( iter != allHistoryAttribs.end() )
+ allHistoryAttribs.erase( iter );
+
+LOSE_DEF
+
+DTOR_DEF
+ num_attribs--;
+ std::set<ATTRIB_HISTORY*>::iterator iter;
+ if( addOrRemoveFromList )
+ {
+ iter = allHistoryAttribs.find( this );
+ if( iter != allHistoryAttribs.end() )
+ allHistoryAttribs.erase( iter );
+ }
+ if( num_attribs == 0 )
+ PRINT_INFO("num_attribs = %d\n", num_attribs );
+
+DEBUG_DEF
+
+
+SAVE_DEF
+// Don't save
+
+RESTORE_DEF
+// Don't restore
+
+COPY_DEF
+ //This attribute is being copied from ENTITY "from". At this point
+ //it would be nice to be able to map the original ENTITY (from->owner())
+ //to the copy (this->owner()) but you can't since all the copying isn't
+ //complete. So right now we just get the 'from' attribute. Later in
+ //FIX_POINTER_DEF after everything is hooked up correctly, we can get
+ //the this->owner().
+ fromHistoryAttrib = (ATTRIB_HISTORY*)from;
+ //get the index of the copy in the array in fix_pointer_def
+ //index = (ENTITY*) INTEXTEND list.lookup( from->owner() );
+
+SCAN_DEF
+
+FIX_POINTER_DEF
+ //change from index to actual value
+ //ENTITY *thisENTITY = ( ENTITY* ) read_array( array, index );
+
+ //we get in here in the last step of the copy...at this point
+ //everything should be hooked up nicely so that we can determine
+ //the entity from which this attribute's owner was copied
+ //AcisHistory::AcisEvent event;
+ //event.eventType = AcisHistory::COPY;
+ //append the original entity to the first list
+ //int unique_id = fromHistoryAttrib->get_unique_id();
+ //event.entities.push_back( unique_id );
+
+ this->add_acis_history( fromHistoryAttrib->acisHistory );
+ this->trackingIds = fromHistoryAttrib->trackingIds;
+
+ //Append the copied ENTITY to the 'other' list
+ //event.other_entities.push_back( this->get_unique_id() );
+
+ //add the event
+ //fromHistoryAttrib->acisHistory->add_event( event );
+
+TERMINATE_DEF
+// Don't do anything special
+// ********** END MACRO DEFINITIONS **********
+
+//bool ATTRIB_CUBIT_OWNER::copyingAttribs = true;
+//bool ATTRIB_CUBIT_OWNER::splitCopy = false;
+
+
+
+ATTRIB_HISTORY::ATTRIB_HISTORY( ENTITY *entity, AcisHistory *acis_history )
+ : ATTRIB_SNL( entity )
+{
+ acisHistory = NULL;
+ num_attribs++;
+ if( acis_history )
+ add_acis_history( acis_history );
+
+ if( addOrRemoveFromList )
+ allHistoryAttribs.insert( this );
+}
+
+void ATTRIB_HISTORY::add_acis_history( AcisHistory *acis_history )
+{
+ acisHistory = acis_history;
+}
+
+std::set<int> ATTRIB_HISTORY::get_tracking_ids()
+{
+ return trackingIds;
+}
+
+void ATTRIB_HISTORY::split_owner( ENTITY *entity)
+{
+ /*
+ PRINT_INFO("I'm in split_owner!!!!\n");
+ if( is_BODY( this->entity() ))
+ PRINT_INFO(" It's a body\n");
+ if( is_LUMP( this->entity() ))
+ PRINT_INFO(" It's a volume\n");
+ if( is_FACE( this->entity() ))
+ PRINT_INFO(" It's a surface\n");
+ if( is_EDGE( this->entity() ))
+ PRINT_INFO(" It's an edge\n");
+ if( is_VERTEX( this->entity() ))
+ PRINT_INFO(" It's a vertex\n"); */
+
+ //add an ATTRIB_HISTORY to the new entity
+ ATTRIB_HISTORY *other_history_attrib = get_history_attrib( entity, true, acisHistory );
+ other_history_attrib->trackingIds = this->trackingIds;
+
+ if( trackingIds.size() > 1 )
+ return;
+ //Create an AcisEvent of type CUT
+ AcisHistory::AcisEvent event;
+ event.eventType = CGMHistory::CUT;
+
+ event.entities.push_back( *(trackingIds.begin()) );
+
+ assert( acisHistory );
+
+ //add the event to the history object
+ acisHistory->add_event( event );
+
+ //Create an AcisEvent of type Subdivision
+ //AcisHistory::AcisEvent event;
+ //event.eventType = AcisHistory::SUBDIVISION;
+ //event.entities.push_back( this->get_unique_id() );
+
+ //event.other_entities.push_back( other_history_attrib->get_unique_id() );
+ //event.other_entities.push_back( this->get_unique_id() );
+
+ //assert( acisHistory );
+
+ //add the event to the history object
+ //acisHistory->add_event( event );
+}
+
+void ATTRIB_HISTORY::merge_owner( ENTITY *entity, logical delete_this)
+{
+ if( delete_this )
+ return;
+/*
+ PRINT_INFO("I'm in merge owner!!!!\n");
+ if( is_BODY( this->entity() ))
+ PRINT_INFO(" It's a body\n");
+ if( is_LUMP( this->entity() ))
+ PRINT_INFO(" It's a volume\n");
+ if( is_FACE( this->entity() ))
+ PRINT_INFO(" It's a surface\n");
+ if( is_EDGE( this->entity() ))
+ PRINT_INFO(" It's an edge\n");
+ if( is_VERTEX( this->entity() ))
+ PRINT_INFO(" It's a vertex\n");
+ */
+
+ //if the entity we're merging this's->owner() with doesn't have
+ //a history attrib on it, we don't care about this
+ ATTRIB_HISTORY *other_history_attrib = get_history_attrib( entity, false );
+ if( !other_history_attrib )
+ return;
+
+ //Create an AcisEvent of type Subdivision
+ //AcisHistory::AcisEvent event;
+ //event.eventType = AcisHistory::ABSORPTION;
+
+ //'entity' got absorbed into 'this->entity()'
+ //event.entities.push_back( other_history_attrib->get_unique_id() );
+ //event.entities.push_back( this->get_unique_id() );
+ //event.other_entities.push_back( this->get_unique_id() );
+
+ std::set<int> other_tracking_ids = other_history_attrib->trackingIds;
+ std::set<int>::iterator iter;
+ for(iter = other_tracking_ids.begin(); iter != other_tracking_ids.end(); iter++ )
+ trackingIds.insert( *iter );
+
+ assert( acisHistory );
+
+ //add the event to the history object
+// acisHistory->add_event( event );
+}
+
+void ATTRIB_HISTORY::trans_owner( SPAtransf const& )
+{
+}
+void ATTRIB_HISTORY::to_tolerant_owner( ENTITY *tol_ent )
+{
+}
+
+void ATTRIB_HISTORY::copy_owner( ENTITY *copy_ent )
+{
+
+ ATTRIB_HISTORY *other_history_attrib = get_history_attrib( copy_ent, true, acisHistory );
+ other_history_attrib->trackingIds = this->trackingIds;
+}
+
+void ATTRIB_HISTORY::replace_owner( ENTITY *other_entity, logical replace_owner )
+{
+ if( replace_owner )
+ return;
+/*
+ PRINT_INFO("I'm in replace owner!!!!\n");
+ if( is_BODY( this->entity() ))
+ PRINT_INFO(" It's a body\n");
+ if( is_LUMP( this->entity() ))
+ PRINT_INFO(" It's a volume\n");
+ if( is_FACE( this->entity() ))
+ PRINT_INFO(" It's a surface\n");
+ if( is_EDGE( this->entity() ))
+ PRINT_INFO(" It's an edge\n");
+ if( is_VERTEX( this->entity() ))
+ PRINT_INFO(" It's a vertex\n");
+*/
+ //if this has alrady been merged w/ something else, it will have
+ //2 tracking ids in it's list. I don't believe there's a need to
+ //track it then if it's already been merged
+
+ if( trackingIds.size() > 1 )
+ return;
+ //Create an AcisEvent of type geometry_changed
+ AcisHistory::AcisEvent event;
+ event.eventType = CGMHistory::GEOMETRY_CHANGED;
+
+ event.entities.push_back( *(trackingIds.begin()) );
+
+ assert( acisHistory );
+
+ //add the event to the history object
+ acisHistory->add_event( event );
+}
+
+void ATTRIB_HISTORY::lop_change_owner()
+{
+ /*
+ PRINT_INFO("I'm in lop_change_owner owner!!!!\n");
+ if( is_BODY( this->entity() ))
+ PRINT_INFO(" It's a body\n");
+ if( is_LUMP( this->entity() ))
+ PRINT_INFO(" It's a volume\n");
+ if( is_FACE( this->entity() ))
+ PRINT_INFO(" It's a surface\n");
+ if( is_EDGE( this->entity() ))
+ PRINT_INFO(" It's an edge\n");
+ if( is_VERTEX( this->entity() ))
+ PRINT_INFO(" It's a vertex\n");
+*/
+ //if this has alrady been merged w/ something else, it will have
+ //2 tracking ids in it's list. I don't believe there's a need to
+ //track it then if it's already been merged
+
+ if( trackingIds.size() > 1 )
+ return;
+
+ //Create an AcisEvent of type Subdivision
+ AcisHistory::AcisEvent event;
+ event.eventType = CGMHistory::GEOMETRY_CHANGED;
+
+ event.entities.push_back( *(trackingIds.begin()) );
+
+ assert( acisHistory );
+
+ //add the event to the history object
+ acisHistory->add_event( event );
+}
+
+void ATTRIB_HISTORY::replace_owner_geometry( ENTITY *new_geom )
+{
+ /*
+ PRINT_INFO("I'm in replace_owner_geometry !!!!\n");
+ if( is_BODY( this->entity() ))
+ PRINT_INFO(" It's a body\n");
+ if( is_LUMP( this->entity() ))
+ PRINT_INFO(" It's a volume\n");
+ if( is_FACE( this->entity() ))
+ PRINT_INFO(" It's a surface\n");
+ if( is_EDGE( this->entity() ))
+ PRINT_INFO(" It's an edge\n");
+ if( is_VERTEX( this->entity() ))
+ PRINT_INFO(" It's a vertex\n");
+*/
+ //if this has alrady been merged w/ something else, it will have
+ //2 tracking ids in it's list. I don't believe there's a need to
+ //track it then if it's already been merged
+
+ if( trackingIds.size() > 1 )
+ return;
+ //Create an AcisEvent of type Subdivision
+ AcisHistory::AcisEvent event;
+ event.eventType = CGMHistory::GEOMETRY_CHANGED;
+
+ event.entities.push_back( *(trackingIds.begin()) );
+
+ assert( acisHistory );
+
+ //add the event to the history object
+ acisHistory->add_event( event );
+}
+
+void ATTRIB_HISTORY::reverse_owner()
+{
+ PRINT_INFO("I'm in reverse_owner !!!!\n");
+}
+
+void ATTRIB_HISTORY::warp_owner( law *warp )
+{
+ PRINT_INFO("I'm in warp_owner !!!!\n");
+}
+
+ATTRIB_HISTORY* ATTRIB_HISTORY::get_history_attrib( ENTITY *acis_entity,
+ bool create_if_necessary,
+ AcisHistory *acis_history )
+{
+
+ if (acis_entity == NULL)
+ {
+ PRINT_ERROR("Trying to set a history attribute on a "
+ " NULL ACIS ENTITY.\n");
+ return NULL;
+ }
+
+ // Search for the attribute
+ ATTRIB_HISTORY *history_attribute =
+ (ATTRIB_HISTORY*)find_attrib(acis_entity,
+ ATTRIB_SNL_TYPE,
+ ATTRIB_HISTORY_TYPE);
+
+ //if we're not creating anything, return whatever we found
+ if( false == create_if_necessary )
+ return history_attribute;
+
+ // If found, reset it's value
+ if (history_attribute != NULL)
+ {
+
+ }
+ // Otherwise, create a new attribute for acis_entity
+ else
+ {
+ API_BEGIN;
+ history_attribute = new ATTRIB_HISTORY( acis_entity, acis_history );
+ API_END;
+ }
+
+ return history_attribute;
+}
+
+
+void ATTRIB_HISTORY::add_tracking_id( int id )
+{
+ trackingIds.insert( id );
+}
+
+void ATTRIB_HISTORY::remove_all_attribs()
+{
+ //prevents
+ //addOrRemoveFromList = false;
+
+ std::set<ATTRIB_HISTORY*>::iterator iter = allHistoryAttribs.begin();
+ for( ; iter != allHistoryAttribs.end(); iter++ )
+ {
+ ATTRIB_HISTORY *history_attrib = *iter;
+ history_attrib->unhook();
+ history_attrib->lose();
+ }
+
+ allHistoryAttribs.clear();
+ //addOrRemoveFromList = true;
+}
Copied: cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_history.hpp (from rev 3491, cgm/branches/cubit/geom/ACIS_SRC/attrib_history.hpp)
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_history.hpp (rev 0)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_history.hpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -0,0 +1,96 @@
+//-------------------------------------------------------------------------
+// Filename : attrib_history.hpp
+//
+// Purpose : Attributes needed to track subdivisions,
+// merges, copy, and geometry-changing events
+//
+// Creator : Corey Ernst
+//-------------------------------------------------------------------------
+
+#ifndef ATTRIB_HISTORY_HPP
+#define ATTRIB_HISTORY_HPP
+
+// ********** BEGIN ACIS INCLUDES **********
+// ********** END ACIS INCLUDES **********
+
+// ********** BEGIN CUBIT INCLUDES **********
+#include "attrib_snl.hpp"
+#include <set>
+//#include "AcisTypes.h"
+// ********** END CUBIT INCLUDES **********
+
+// ********** BEGIN MACRO DEFINITIONS **********
+extern int ATTRIB_HISTORY_TYPE;
+#define ATTRIB_HISTORY_LEVEL (ATTRIB_SNL_LEVEL + 1)
+// ********** END MACRO DEFINITIONS **********
+
+// ********** BEGIN FORWARD DECLARATIONS **********
+
+// ********** END FORWARD DECLARATIONS **********
+
+class AcisHistory;
+
+class ATTRIB_HISTORY: public ATTRIB_SNL
+{
+public:
+
+ ATTRIB_HISTORY( ENTITY* entity = NULL, AcisHistory* acis_history = NULL );
+
+ static ATTRIB_HISTORY* get_history_attrib( ENTITY *acis_entity,
+ bool create_if_necessary = false,
+ AcisHistory *acis_history = NULL );
+
+ // void set_history_object( AcisHistoryObject *history_object );
+ // AcisHistoryObject* get_history_object();
+
+ //-------------------------
+ virtual void split_owner( ENTITY *entity);
+
+ virtual void merge_owner( ENTITY *entity, logical delete_this);
+
+ virtual void trans_owner( SPAtransf const& );
+
+ virtual void to_tolerant_owner( ENTITY *tol_ent );
+
+ virtual void copy_owner( ENTITY *copy_ent );
+
+ virtual void replace_owner( ENTITY *other_entity, logical replace_owner );
+
+ virtual void lop_change_owner();
+
+ virtual void replace_owner_geometry( ENTITY *new_geom );
+
+ virtual void reverse_owner();
+
+ virtual void warp_owner( law *warp );
+ //-------------------------
+
+ std::set<int> get_tracking_ids();
+ void add_tracking_id( int id );
+ void add_acis_history( AcisHistory *acis_history );
+
+ static void remove_all_attribs();
+
+ ATTRIB_FUNCTIONS(ATTRIB_HISTORY, NONE)
+
+ private:
+ //the history object that is being added to
+ AcisHistory *acisHistory;
+
+ //when an entity gets copied, the resultant copy entity needs to know
+ //the entity from whence it was copied. This ATTRIB_HISTORY pointer
+ //facilitates mapping the original ENTITY to the resultant copied ENTITY
+ ATTRIB_HISTORY *fromHistoryAttrib;
+
+ std::set<int> trackingIds;
+ static std::set<ATTRIB_HISTORY*> allHistoryAttribs;
+
+ static int num_attribs;
+ static bool addOrRemoveFromList;
+ //static bool copyingAttribs;
+ //static bool splitCopy;
+};
+
+#endif
+
+
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_snl.cpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_snl.cpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_snl.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -26,15 +26,9 @@
#include <stdio.h>
// ACIS Includes
-#if CUBIT_ACIS_VERSION < 1100
-#include "kernel/dcl_kern.h"
-#include "kernel/kerndata/attrib/at_tsl.hxx"
-#include "kernel/kerndata/data/datamsc.hxx"
-#else
#include "dcl_kern.h"
#include "at_tsl.hxx"
#include "datamsc.hxx"
-#endif
#include "attrib_snl.hpp"
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_snl.hpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_snl.hpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_snl.hpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -33,11 +33,7 @@
// CUBIT Includes
#include "decl_none.h"
// ACIS Includes
-#if CUBIT_ACIS_VERSION < 1100
-#include "kernel/kerndata/attrib/attrib.hxx"
-#else
#include "attrib.hxx"
-#endif
// This attribute type is a derived class of ATTRIB.
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_snl_simple.cpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_snl_simple.cpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_snl_simple.cpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -10,17 +10,14 @@
#include <string.h>
// ACIS Includes
-#if CUBIT_ACIS_VERSION < 1100
-#include "kernel/kernapi/api/api.hxx"
-#include "kernel/kerndata/attrib/at_tsl.hxx"
-#include "kernel/kerndata/data/datamsc.hxx"
-#else
#include "api.hxx"
#include "at_tsl.hxx"
#include "datamsc.hxx"
#include "acistype.hxx"
#include "edge.hxx"
-#endif
+#include "kernapi.hxx"
+#include "vertex.hxx"
+#include "point.hxx"
#include "attrib_snl_simple.hpp"
#include "attrib_cubit_owner.hpp"
@@ -29,6 +26,7 @@
#include "CubitAttribUser.hpp"
#include "CastTo.hpp"
#include "TopologyEntity.hpp"
+#include "GeometryDefines.h"
// Buffer size
const int MAX_STRING_LENGTH = 256;
@@ -144,11 +142,89 @@
// ****DEFINED FUNCTIONS!!!!!!!!!!
void ATTRIB_SNL_SIMPLE::split_owner(ENTITY* new_ent)
{
+ // When performing real operations on geometry with
+ // virtual we need to try to maintain the virtual
+ // ids where possible. To do this we push an ENTITY_ID
+ // attribute onto the ACIS entities before the operation
+ // and then actuate them after the operation to get the
+ // id back. If we split an entity however we want
+ // to make sure the id attribute gets thrown away
+ // so that new ids will be generated correctly. We
+ // check the second string also here in case the ENTITY_ID
+ // was saved as part of a COMPOSITE_ATTRIB attribute (where
+ // "COMPOSITE_ATTRIB" is in the first position).
+ if(data->get_string(0) == "ENTITY_ID" ||
+ data->get_string(1) == "ENTITY_ID")
+ {
+ unhook();
+ lose();
+ return;
+ }
+
+ // If we are splitting a curve that is hidden in a
+ // composite surface put a composite attribute on the
+ // new vertices where the split took place. We don't
+ // want a new vertex there because the operation should
+ // behave as if the hidden curve was never there.
+ /* This can ceate cases that can't be composited (see bug_6402.jou in interop
+ test suite).
+ if(!strcmp(data->name().c_str(), "COMPOSITE_GEOM"))
+ {
+ if(is_EDGE(entity()) && is_EDGE(new_ent))
+ {
+ EDGE *e1 = (EDGE*)entity();
+ EDGE *e2 = (EDGE*)new_ent;
+ ENTITY_LIST edge1_verts;
+ api_get_vertices((ENTITY*)e1, edge1_verts);
+ edge1_verts.init();
+ VERTEX *e1v1 = (VERTEX*)edge1_verts.next();
+ VERTEX *e1v2 = (VERTEX*)edge1_verts.next();
+ ENTITY_LIST edge2_verts;
+ api_get_vertices((ENTITY*)e2, edge2_verts);
+ edge2_verts.init();
+ VERTEX *e2v1 = (VERTEX*)edge2_verts.next();
+ VERTEX *e2v2 = (VERTEX*)edge2_verts.next();
+ VERTEX *vert = NULL;
+ // The new entity should be a different length
+ // than the old entity. One of the vertices on
+ // the new entity will match one of the vertices
+ // on the old entity. Find the one that matches
+ // and then we will know that the other one on the
+ // new entity is the vertex where the split took place.
+ if(e2v1 == e1v1 || e2v1 == e1v2)
+ vert = e2v2;
+ else if(e2v2 == e1v1 || e2v2 == e1v2)
+ vert = e2v1;
+ else
+ {
+ double same_pt_tol = GEOMETRY_RESABS*GEOMETRY_RESABS;
+ if((e2v1->geometry()->coords() - e1v1->geometry()->coords()).len_sq() < same_pt_tol)
+ vert = e2v2;
+ else if((e2v1->geometry()->coords() - e1v2->geometry()->coords()).len_sq() < same_pt_tol)
+ vert = e2v2;
+ else if((e2v2->geometry()->coords() - e1v1->geometry()->coords()).len_sq() < same_pt_tol)
+ vert = e2v1;
+ else if((e2v2->geometry()->coords() - e1v2->geometry()->coords()).len_sq() < same_pt_tol)
+ vert = e2v1;
+ }
+ if(vert)
+ {
+ API_BEGIN;
+ new ATTRIB_SNL_SIMPLE(vert, *this);
+ API_END;
+ }
+ }
+ }
+ */
+
// If we have split an entity that is a hidden
// entity of a composite transfer the attribute
// to the new entity.
if(!strcmp(data->name().c_str(), "COMPOSITE_GEOM") ||
- !strcmp(data->name().c_str(), "IMPRINT_PREEXISTING"))
+ !strcmp(data->name().c_str(), "IMPRINT_PREEXISTING") ||
+ !strcmp(data->name().c_str(), "COMPOSITE_IGNORE") ||
+ !strcmp(data->name().c_str(), "IMPRINTER") ||
+ !strcmp(data->name().c_str(), "REMOVE_EDGE"))
{
API_BEGIN;
new ATTRIB_SNL_SIMPLE(new_ent, *this);
@@ -173,7 +249,9 @@
if(data &&
(!strcmp(data->name().c_str(), "ENTITY_NAME") ||
- !strcmp(data->name().c_str(), "CA_ASSEMBLY_DATA")))
+ !strcmp(data->name().c_str(), "CA_ASSEMBLY_DATA") ||
+ !strcmp(data->name().c_str(), "PROPERTY_BLOCK") ||
+ !strcmp(data->name().c_str(), "MATERIAL_BLOCK")))
{
API_BEGIN;
new ATTRIB_SNL_SIMPLE(new_ent, *this);
@@ -203,6 +281,9 @@
{
if(!strcmp(data->name().c_str(), "COMPOSITE_GEOM"))
{
+ int destroy = 0;
+ //if(is_VERTEX(entity()) && is_VERTEX(other_ent))
+ // destroy = 1;
if(is_EDGE(entity()) && is_EDGE(other_ent))
{
EDGE *this_edge = (EDGE*)entity();
@@ -212,15 +293,19 @@
(this_edge->start() == other_edge->end() &&
this_edge->end() == other_edge->start()))
{
- // If we get to this point we most likely have the
- // case where a geometric operation has cut this
- // body right along the hidden entity of a composite.
- // In this case we will just blow away the composite
- // by removing the attribute.
- unhook();
- lose();
+ destroy = 1;
}
}
+ if(destroy)
+ {
+ // If we get to this point we most likely have the
+ // case where a geometric operation has cut this
+ // body right along the hidden entity of a composite.
+ // In this case we will just blow away the composite
+ // by removing the attribute.
+ unhook();
+ lose();
+ }
return;
}
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_snl_simple.hpp
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_snl_simple.hpp 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/attrib_snl_simple.hpp 2010-01-27 02:15:23 UTC (rev 3496)
@@ -47,6 +47,9 @@
inline CubitString name() const
{ return numStrings ? stringData[0] : CubitString(); }
+
+ inline CubitString get_string(int index) const
+ { return (index > -1 && numStrings > index) ? stringData[index] : CubitString(); }
void save() const;
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/decl_none.h
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/decl_none.h 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/decl_none.h 2010-01-27 02:15:23 UTC (rev 3496)
@@ -18,10 +18,6 @@
#ifndef EXPORT_NONE
# ifdef NT
-#if CUBIT_ACIS_VERSION < 1100
-# pragma comment( lib, "kernel.lib") /* force link in VC++ */
-#endif
-
# endif
#endif
Property changes on: cgm/branches/merge-cubit12/geom/ACIS_SRC/gtcAttrib
___________________________________________________________________
Added: svn:mergeinfo
+
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/gtcAttrib/CMakeLists.txt
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/gtcAttrib/CMakeLists.txt 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/gtcAttrib/CMakeLists.txt 2010-01-27 02:15:23 UTC (rev 3496)
@@ -1,10 +1,103 @@
PROJECT(gtcAttrib)
+IF(IGTO_BUILD)
+
+SET(gtcAttrib_MAJOR_VERSION 1
+ CACHE STRING "gtcAttrib Major Library Version" FORCE)
+SET(gtcAttrib_MINOR_VERSION 0
+ CACHE STRING "gtcAttrib Minor Library Version" FORCE)
+SET(gtcAttrib_VERSION
+ "${gtcAttrib_MAJOR_VERSION}.${gtcAttrib_MINOR_VERSION}"
+ CACHE STRING "gtcAttrib Library Version" FORCE)
+#SET (gtcAttrib_VERSION 1.0 CACHE STRING "Library Version" FORCE)
# Disallow in-source build
STRING(COMPARE EQUAL "${gtcAttrib_SOURCE_DIR}"
"${gtcAttrib_BINARY_DIR}" INSOURCE)
IF(INSOURCE)
+ MESSAGE(SEND_ERROR "Build directory ${gtcAttrib_BINARY_DIR}")
+ MESSAGE(SEND_ERROR "Source directory ${gtcAttrib_SOURCE_DIR}")
+ MESSAGE(FATAL_ERROR "gtcAttrib requires an out of source Build. Please create a separate binary directory and run CMake there.")
+ENDIF(INSOURCE)
+
+# set our CMAKE_MODULE_PATH to include the one specific to this project
+SET (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMakeModules )
+
+SET (GTC_ATTRIB_SRCS
+ src/attrib_edge_parametric_length.C
+ src/attrib_gtc.C
+ src/attrib_mark.C
+ src/attrib_name.C
+ )
+
+# check to see if we have the standard namespace
+INCLUDE (TestForSTDNamespace)
+IF (CMAKE_STD_NAMESPACE)
+ ADD_DEFINITIONS(-DHAVE_STD)
+ENDIF (CMAKE_STD_NAMESPACE)
+
+# Find the acis libraries
+
+INCLUDE (FindACIS)
+FindACIS(17)
+
+IF (ACIS_FOUND)
+ # add acis includes to current project
+ INCLUDE_DIRECTORIES(${ACIS_INCLUDE_DIR} ${gtcAttrib_SOURCE_DIR}/incl)
+
+ #need to define ACIS_VER since it's used in the source here
+ ADD_DEFINITIONS(-DACIS_VER=${ACIS_VERSION})
+
+ ADD_DEFINITIONS(${ACIS_DEFINES})
+
+ LINK_DIRECTORIES(${ACIS_LIBRARY_DIR} ${ACIS_LIBRARY_DIR_DEBUG})
+ELSE (ACIS_FOUND)
+ MESSAGE(FATAL_ERROR "gtcAttrib requires ACIS libraries of version R16 or above.")
+ENDIF (ACIS_FOUND)
+
+
+IF(UNIX)
+ ADD_CUSTOM_TARGET(switch_acis ${CMAKE_MAKE_PROGRAM} clean)
+ELSE(UNIX)
+ ADD_DEFINITIONS(-DNT -DgtcAttrib_EXPORTS)
+# IF (MSVC60 OR MSVC70)
+# ADD_DEFINITIONS(-DNT_DLL)
+# ENDIF (MSVC60 OR MSVC70)
+# IF (MSVC71)
+# ADD_DEFINITIONS(-DNT_NET_DLL)
+# ENDIF (MSVC71)
+ SET (ARCHIVE_DESIGNATOR a)
+ SET (SHARED_DESIGNATOR s)
+ENDIF(UNIX)
+
+
+# build gtcAttrib library from sources
+ADD_LIBRARY(libgtcAttrib STATIC ${GTC_ATTRIB_SRCS})
+ADD_LIBRARY(libgtcAttrib_so SHARED ${GTC_ATTRIB_SRCS})
+SET_TARGET_PROPERTIES(libgtcAttrib PROPERTIES OUTPUT_NAME gtcAttrib${gtcAttrib_VERSION}${ARCHIVE_DESIGNATOR})
+SET_TARGET_PROPERTIES(libgtcAttrib_so PROPERTIES OUTPUT_NAME gtcAttrib${gtcAttrib_VERSION}${SHARED_DESIGNATOR})
+
+TARGET_LINK_LIBRARIES(libgtcAttrib ${ACIS_LIBRARIES})
+TARGET_LINK_LIBRARIES(libgtcAttrib_so ${ACIS_LIBRARIES})
+
+
+INSTALL_TARGETS(/${CMAKE_INSTALL_BINARY_DIR} libgtcAttrib libgtcAttrib_so)
+
+# GET_TARGET_PROPERTY(LIB_OUT_NAME2 libgtcAttrib OUTPUT_NAME)
+# MESSAGE("libgtcAttrib output name is ${LIB_OUT_NAME2}")
+
+# GET_TARGET_PROPERTY(LIBSO_OUT_NAME2 libgtcAttrib_so OUTPUT_NAME)
+# MESSAGE("libgtcAttrib_so output name is ${LIBSO_OUT_NAME2}")
+
+# this keeps the build of the shared lib from erasing the archive lib and v/v
+SET_TARGET_PROPERTIES(libgtcAttrib libgtcAttrib_so PROPERTIES CLEAN_DIRECT_OUTPUT 1)
+
+ELSE(IGTO_BUILD)
+
+# Disallow in-source build
+STRING(COMPARE EQUAL "${gtcAttrib_SOURCE_DIR}"
+ "${gtcAttrib_BINARY_DIR}" INSOURCE)
+IF(INSOURCE)
MESSAGE(FATAL_ERROR "gtcAttrib requires an out of source Build. Please create a separate binary directory and run CMake there.")
ENDIF(INSOURCE)
@@ -22,15 +115,18 @@
ADD_DEFINITIONS(-DACIS_VER=${ACIS_VERSION})
# build cubit acis library from sources
-LINK_DIRECTORIES(${ACIS_LIBRARY_DIR} ${ACIS_LIBRARY_DIR_DEBUG})
ADD_LIBRARY(gtcAttrib SHARED ${GTC_ATTRIB_SRCS})
TARGET_LINK_LIBRARIES(gtcAttrib ${ACIS_LIBS})
+IF(CUBIT_LIBRARY_PROPERTIES)
+ SET_TARGET_PROPERTIES(gtcAttrib
+ PROPERTIES ${CUBIT_LIBRARY_PROPERTIES})
+ENDIF(CUBIT_LIBRARY_PROPERTIES)
-IF(UNIX)
-ADD_CUSTOM_TARGET(switch_acis ${CMAKE_MAKE_PROGRAM} clean)
-ENDIF(UNIX)
+INSTALL(TARGETS gtcAttrib
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINARY_DIR} COMPONENT Runtime
+ LIBRARY DESTINATION ${CMAKE_INSTALL_BINARY_DIR} COMPONENT Runtime
+ )
-INSTALL_TARGETS(/${CMAKE_INSTALL_BINARY_DIR} gtcAttrib)
-
+ENDIF(IGTO_BUILD)
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/gtcAttrib/Makefile
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/gtcAttrib/Makefile 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/gtcAttrib/Makefile 2010-01-27 02:15:23 UTC (rev 3496)
@@ -1,5 +1,5 @@
##---------------------------------------------------------------------------
-## $Id: Makefile,v 1.1 2006/06/09 13:38:52 rakerr Exp $
+## $Id: Makefile,v 1.1 2006-06-09 13:38:52 rakerr Exp $
##===========================================================================
SOURCE_DIR = ./src
@@ -130,10 +130,7 @@
include make.depend.$(MACHINE_TYPE)
##---------------------------------------------------------------------------
-## $Log: Makefile,v $
-## Revision 1.1 2006/06/09 13:38:52 rakerr
-## Adding gtcAttrib files.
-##
+## $Log: not supported by cvs2svn $
## Revision 1.2 2006/05/30 14:16:24 prwolfe
## New version numbners and added check for get_name not to return the generic
## names managed by the gto backpointer attribute.
Property changes on: cgm/branches/merge-cubit12/geom/ACIS_SRC/gtcAttrib/incl
___________________________________________________________________
Added: svn:mergeinfo
+
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/gtcAttrib/incl/attrib_gtc_export.h
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/gtcAttrib/incl/attrib_gtc_export.h 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/gtcAttrib/incl/attrib_gtc_export.h 2010-01-27 02:15:23 UTC (rev 3496)
@@ -3,14 +3,16 @@
#ifndef ATTRIB_GTC_EXPORT_H
#define ATTRIB_GTC_EXPORT_H
-#if defined( _WIN32)
+#if defined( _WIN32) && !defined(CAT)
#if defined(gtcAttrib_EXPORTS)
-#define DECL_GTCATTRIB __declspec(dllexport)
+# define DECL_GTCATTRIB __declspec(dllexport)
#else
-#define DECL_GTCATTRIB __declspec(dllimport)
+# define DECL_GTCATTRIB __declspec(dllimport)
#endif
+#elif defined(__GNUC__) && __GNUC__ >= 4
+# define DECL_GTCATTRIB __attribute__ ((visibility("default")))
#else
-#define DECL_GTCATTRIB
+# define DECL_GTCATTRIB
#endif
Property changes on: cgm/branches/merge-cubit12/geom/ACIS_SRC/gtcAttrib/src
___________________________________________________________________
Added: svn:mergeinfo
+
Modified: cgm/branches/merge-cubit12/geom/ACIS_SRC/gtcAttrib/src/attrib_gtc.C
===================================================================
--- cgm/branches/merge-cubit12/geom/ACIS_SRC/gtcAttrib/src/attrib_gtc.C 2010-01-27 01:06:43 UTC (rev 3495)
+++ cgm/branches/merge-cubit12/geom/ACIS_SRC/gtcAttrib/src/attrib_gtc.C 2010-01-27 02:15:23 UTC (rev 3496)
@@ -22,5 +22,5 @@
#define ATTRIB_GTC_NAME "gtc"
-MASTER_ATTRIB_DEFN( "gtc master attribute" )
+MASTER_ATTRIB_DEFN( "gtc master attribute" );
More information about the cgma-dev
mailing list