[cgma-dev] r3423 - in cgm/branches/cubit: . geom geom/Cholla geom/facet geom/facetbool geom/parallel geom/testing geom/testing/data geom/virtual util util/OtherFiles
kraftche at cae.wisc.edu
kraftche at cae.wisc.edu
Wed Jan 6 13:22:16 CST 2010
Author: kraftche
Date: 2010-01-06 13:22:14 -0600 (Wed, 06 Jan 2010)
New Revision: 3423
Added:
cgm/branches/cubit/geom/AutoMidsurfaceTool.cpp
cgm/branches/cubit/geom/AutoMidsurfaceTool.hpp
cgm/branches/cubit/geom/CGMHistory.cpp
cgm/branches/cubit/geom/CGMHistory.hpp
cgm/branches/cubit/geom/Cholla/ChollaVolume.cpp
cgm/branches/cubit/geom/Cholla/ChollaVolume.hpp
cgm/branches/cubit/geom/Cholla/FacetorUtil.cpp
cgm/branches/cubit/geom/Cholla/FacetorUtil.hpp
cgm/branches/cubit/geom/GfxPreview.cpp
cgm/branches/cubit/geom/GfxPreview.hpp
cgm/branches/cubit/geom/PeriodicParamTool.cpp
cgm/branches/cubit/geom/PeriodicParamTool.hpp
cgm/branches/cubit/geom/testing/
cgm/branches/cubit/geom/testing/AngleCalc.cpp
cgm/branches/cubit/geom/testing/CMakeLists.txt
cgm/branches/cubit/geom/testing/CreateGeometry.cpp
cgm/branches/cubit/geom/testing/GraphicsData.cpp
cgm/branches/cubit/geom/testing/Makefile.am
cgm/branches/cubit/geom/testing/ReadIgesFile.cpp
cgm/branches/cubit/geom/testing/TestConfig.h.in
cgm/branches/cubit/geom/testing/TestUtilities.cpp
cgm/branches/cubit/geom/testing/TestUtilities.hpp
cgm/branches/cubit/geom/testing/cgm_test.cpp
cgm/branches/cubit/geom/testing/cgm_test.hpp
cgm/branches/cubit/geom/testing/cgm_test_script
cgm/branches/cubit/geom/testing/data/
cgm/branches/cubit/geom/testing/data/brick.iges
cgm/branches/cubit/geom/virtual/SplitCompositeSurfaceTool.cpp
cgm/branches/cubit/geom/virtual/SplitCompositeSurfaceTool.hpp
cgm/branches/cubit/util/CommandFeedback.hpp
cgm/branches/cubit/util/CubitUndo.cpp
cgm/branches/cubit/util/CubitUndo.hpp
cgm/branches/cubit/util/ExternalCoordinateSystem.hpp
cgm/branches/cubit/util/GlobalCommandFeedback.cpp
cgm/branches/cubit/util/GlobalCommandFeedback.hpp
cgm/branches/cubit/util/ManagedPtrVector.hpp
cgm/branches/cubit/util/OrderedMap.hpp
cgm/branches/cubit/util/OrderedSet.hpp
Modified:
cgm/branches/cubit/configure.in
cgm/branches/cubit/geom/AnalyticGeometryTool.cpp
cgm/branches/cubit/geom/AnalyticGeometryTool.hpp
cgm/branches/cubit/geom/Body.cpp
cgm/branches/cubit/geom/Body.hpp
cgm/branches/cubit/geom/BoundingBoxTool.cpp
cgm/branches/cubit/geom/BoundingBoxTool.hpp
cgm/branches/cubit/geom/CADefines.hpp
cgm/branches/cubit/geom/CAEntityId.cpp
cgm/branches/cubit/geom/CAMergePartner.cpp
cgm/branches/cubit/geom/CGMApp.cpp
cgm/branches/cubit/geom/CGMApp.hpp
cgm/branches/cubit/geom/CGMEngineDynamicLoader.cpp
cgm/branches/cubit/geom/CMakeLists.txt
cgm/branches/cubit/geom/Cholla/CMakeLists.txt
cgm/branches/cubit/geom/Cholla/Cholla.cpp
cgm/branches/cubit/geom/Cholla/ChollaCurve.cpp
cgm/branches/cubit/geom/Cholla/ChollaCurve.hpp
cgm/branches/cubit/geom/Cholla/ChollaEngine.cpp
cgm/branches/cubit/geom/Cholla/ChollaEngine.hpp
cgm/branches/cubit/geom/Cholla/ChollaPoint.cpp
cgm/branches/cubit/geom/Cholla/ChollaPoint.hpp
cgm/branches/cubit/geom/Cholla/ChollaSurface.cpp
cgm/branches/cubit/geom/Cholla/ChollaSurface.hpp
cgm/branches/cubit/geom/Cholla/CubitFacet.cpp
cgm/branches/cubit/geom/Cholla/CubitFacet.hpp
cgm/branches/cubit/geom/Cholla/CubitFacetData.cpp
cgm/branches/cubit/geom/Cholla/CubitFacetData.hpp
cgm/branches/cubit/geom/Cholla/CubitFacetEdge.hpp
cgm/branches/cubit/geom/Cholla/CurveFacetEvalTool.cpp
cgm/branches/cubit/geom/Cholla/CurveFacetEvalTool.hpp
cgm/branches/cubit/geom/Cholla/FacetDataUtil.cpp
cgm/branches/cubit/geom/Cholla/FacetDataUtil.hpp
cgm/branches/cubit/geom/Cholla/FacetEvalTool.cpp
cgm/branches/cubit/geom/Cholla/FacetEvalTool.hpp
cgm/branches/cubit/geom/Cholla/FacetorTool.cpp
cgm/branches/cubit/geom/Cholla/FacetorTool.hpp
cgm/branches/cubit/geom/Cholla/LoopParamTool.cpp
cgm/branches/cubit/geom/Cholla/LoopParamTool.hpp
cgm/branches/cubit/geom/Cholla/Makefile.am
cgm/branches/cubit/geom/Cholla/TDGeomFacet.cpp
cgm/branches/cubit/geom/Cholla/TDGeomFacet.hpp
cgm/branches/cubit/geom/Cholla/debug.cpp
cgm/branches/cubit/geom/Cholla/debug.hpp
cgm/branches/cubit/geom/CubitAttrib.cpp
cgm/branches/cubit/geom/CubitAttribUser.cpp
cgm/branches/cubit/geom/CubitAttribUser.hpp
cgm/branches/cubit/geom/CubitGeomConfigure.h.in
cgm/branches/cubit/geom/Curve.cpp
cgm/branches/cubit/geom/CurveOverlapFacet.cpp
cgm/branches/cubit/geom/CurveOverlapFacet.hpp
cgm/branches/cubit/geom/DAG.hpp
cgm/branches/cubit/geom/DagDrawingTool.hpp
cgm/branches/cubit/geom/GSaveOpen.cpp
cgm/branches/cubit/geom/GSaveOpen.hpp
cgm/branches/cubit/geom/GeomMeasureTool.cpp
cgm/branches/cubit/geom/GeomMeasureTool.hpp
cgm/branches/cubit/geom/GeometryFeatureTool.hpp
cgm/branches/cubit/geom/GeometryHealerTool.cpp
cgm/branches/cubit/geom/GeometryHealerTool.hpp
cgm/branches/cubit/geom/GeometryModifyEngine.cpp
cgm/branches/cubit/geom/GeometryModifyEngine.hpp
cgm/branches/cubit/geom/GeometryModifyTool.cpp
cgm/branches/cubit/geom/GeometryModifyTool.hpp
cgm/branches/cubit/geom/GeometryQueryEngine.cpp
cgm/branches/cubit/geom/GeometryQueryEngine.hpp
cgm/branches/cubit/geom/GeometryQueryTool.cpp
cgm/branches/cubit/geom/GeometryQueryTool.hpp
cgm/branches/cubit/geom/GroupingEntity.cpp
cgm/branches/cubit/geom/IntermediateGeomEngine.hpp
cgm/branches/cubit/geom/Loop.cpp
cgm/branches/cubit/geom/Loop.hpp
cgm/branches/cubit/geom/LoopSM.hpp
cgm/branches/cubit/geom/Lump.hpp
cgm/branches/cubit/geom/Makefile.am
cgm/branches/cubit/geom/MergeTool.cpp
cgm/branches/cubit/geom/MergeTool.hpp
cgm/branches/cubit/geom/ModelQueryEngine.hpp
cgm/branches/cubit/geom/OffsetSplitTool.cpp
cgm/branches/cubit/geom/RefEdge.cpp
cgm/branches/cubit/geom/RefEdge.hpp
cgm/branches/cubit/geom/RefEntity.cpp
cgm/branches/cubit/geom/RefEntity.hpp
cgm/branches/cubit/geom/RefEntityFactory.cpp
cgm/branches/cubit/geom/RefEntityFactory.hpp
cgm/branches/cubit/geom/RefEntityName.cpp
cgm/branches/cubit/geom/RefEntityName.hpp
cgm/branches/cubit/geom/RefFace.cpp
cgm/branches/cubit/geom/RefFace.hpp
cgm/branches/cubit/geom/RefGroup.cpp
cgm/branches/cubit/geom/RefVertex.cpp
cgm/branches/cubit/geom/RefVolume.cpp
cgm/branches/cubit/geom/RefVolume.hpp
cgm/branches/cubit/geom/SenseEntity.hpp
cgm/branches/cubit/geom/SplitSurfaceTool.cpp
cgm/branches/cubit/geom/SplitSurfaceTool.hpp
cgm/branches/cubit/geom/SurfParamTool.cpp
cgm/branches/cubit/geom/SurfParamTool.hpp
cgm/branches/cubit/geom/Surface.hpp
cgm/branches/cubit/geom/SurfaceOverlapFacet.cpp
cgm/branches/cubit/geom/SurfaceOverlapFacet.hpp
cgm/branches/cubit/geom/SurfaceOverlapTool.cpp
cgm/branches/cubit/geom/SurfaceOverlapTool.hpp
cgm/branches/cubit/geom/TDSplitSurface.cpp
cgm/branches/cubit/geom/TDSplitSurface.hpp
cgm/branches/cubit/geom/TDUniqueId.cpp
cgm/branches/cubit/geom/TopologyBridge.cpp
cgm/branches/cubit/geom/TopologyBridge.hpp
cgm/branches/cubit/geom/facet/FacetCurve.cpp
cgm/branches/cubit/geom/facet/FacetLoop.cpp
cgm/branches/cubit/geom/facet/FacetLoop.hpp
cgm/branches/cubit/geom/facet/FacetModifyEngine.cpp
cgm/branches/cubit/geom/facet/FacetModifyEngine.hpp
cgm/branches/cubit/geom/facet/FacetParamTool.cpp
cgm/branches/cubit/geom/facet/FacetParamTool.hpp
cgm/branches/cubit/geom/facet/FacetQueryEngine.cpp
cgm/branches/cubit/geom/facet/FacetQueryEngine.hpp
cgm/branches/cubit/geom/facet/FacetboolInterface.cpp
cgm/branches/cubit/geom/facetbool/FBRetriangulate.cpp
cgm/branches/cubit/geom/parallel/Makefile.am
cgm/branches/cubit/geom/virtual/CMakeLists.txt
cgm/branches/cubit/geom/virtual/CollapseCurveTool.cpp
cgm/branches/cubit/geom/virtual/CollapseCurveTool.hpp
cgm/branches/cubit/geom/virtual/CompSurfFacets.cpp
cgm/branches/cubit/geom/virtual/CompositeEngine.cpp
cgm/branches/cubit/geom/virtual/CompositeEngine.hpp
cgm/branches/cubit/geom/virtual/CompositeGeom.cpp
cgm/branches/cubit/geom/virtual/CompositeGeom.hpp
cgm/branches/cubit/geom/virtual/CompositeLoop.cpp
cgm/branches/cubit/geom/virtual/CompositeLoop.hpp
cgm/branches/cubit/geom/virtual/CompositeSurface.cpp
cgm/branches/cubit/geom/virtual/CompositeSurface.hpp
cgm/branches/cubit/geom/virtual/CompositeTool.cpp
cgm/branches/cubit/geom/virtual/FacetProjectTool.cpp
cgm/branches/cubit/geom/virtual/FacetProjectTool.hpp
cgm/branches/cubit/geom/virtual/Faceter.cpp
cgm/branches/cubit/geom/virtual/ImprintBoundaryTool.cpp
cgm/branches/cubit/geom/virtual/Makefile.am
cgm/branches/cubit/geom/virtual/PST_Data.cpp
cgm/branches/cubit/geom/virtual/PartSurfFacetTool.cpp
cgm/branches/cubit/geom/virtual/PartitionEngine.cpp
cgm/branches/cubit/geom/virtual/PartitionEngine.hpp
cgm/branches/cubit/geom/virtual/PartitionLoop.cpp
cgm/branches/cubit/geom/virtual/PartitionLoop.hpp
cgm/branches/cubit/geom/virtual/PartitionSurface.cpp
cgm/branches/cubit/geom/virtual/PartitionTool.cpp
cgm/branches/cubit/geom/virtual/RemoveBlends.cpp
cgm/branches/cubit/geom/virtual/SimplifyTool.cpp
cgm/branches/cubit/geom/virtual/SimplifyTool.hpp
cgm/branches/cubit/geom/virtual/SubCurve.cpp
cgm/branches/cubit/geom/virtual/SubSurface.cpp
cgm/branches/cubit/geom/virtual/VGLoopTool.cpp
cgm/branches/cubit/geom/virtual/VirtualQueryEngine.cpp
cgm/branches/cubit/geom/virtual/VirtualQueryEngine.hpp
cgm/branches/cubit/util/AppUtil.cpp
cgm/branches/cubit/util/AppUtil.hpp
cgm/branches/cubit/util/ArrayBasedContainer.cpp
cgm/branches/cubit/util/CMakeLists.txt
cgm/branches/cubit/util/CastTo.hpp
cgm/branches/cubit/util/CpuTimer.cpp
cgm/branches/cubit/util/CpuTimer.hpp
cgm/branches/cubit/util/CubitBox.cpp
cgm/branches/cubit/util/CubitBox.hpp
cgm/branches/cubit/util/CubitColorConstants.hpp
cgm/branches/cubit/util/CubitCoordinateSystem.cpp
cgm/branches/cubit/util/CubitDefines.h
cgm/branches/cubit/util/CubitDynamicLoader.cpp
cgm/branches/cubit/util/CubitEntity.cpp
cgm/branches/cubit/util/CubitEventDefines.h
cgm/branches/cubit/util/CubitFile.cpp
cgm/branches/cubit/util/CubitFile.hpp
cgm/branches/cubit/util/CubitFileFEModel.cpp
cgm/branches/cubit/util/CubitFileFEModel.hpp
cgm/branches/cubit/util/CubitFileIOWrapper.cpp
cgm/branches/cubit/util/CubitFileIOWrapper.hpp
cgm/branches/cubit/util/CubitFileMetaData.cpp
cgm/branches/cubit/util/CubitFileUtil.cpp
cgm/branches/cubit/util/CubitInputFile.hpp
cgm/branches/cubit/util/CubitMatrix.cpp
cgm/branches/cubit/util/CubitMessage.cpp
cgm/branches/cubit/util/CubitMessage.hpp
cgm/branches/cubit/util/CubitPlane.cpp
cgm/branches/cubit/util/CubitPlane.hpp
cgm/branches/cubit/util/CubitStack.cpp
cgm/branches/cubit/util/CubitString.cpp
cgm/branches/cubit/util/CubitString.hpp
cgm/branches/cubit/util/CubitTransformMatrix.cpp
cgm/branches/cubit/util/CubitTransformMatrix.hpp
cgm/branches/cubit/util/CubitUtil.cpp
cgm/branches/cubit/util/CubitUtil.hpp
cgm/branches/cubit/util/CubitUtilConfigure.h.in
cgm/branches/cubit/util/CubitVector.cpp
cgm/branches/cubit/util/CubitVector.hpp
cgm/branches/cubit/util/DIntArray.cpp
cgm/branches/cubit/util/DLIList.cpp
cgm/branches/cubit/util/DLIList.hpp
cgm/branches/cubit/util/DLList.hpp
cgm/branches/cubit/util/DynamicArray.cpp
cgm/branches/cubit/util/DynamicArray.hpp
cgm/branches/cubit/util/ElementType.h
cgm/branches/cubit/util/GMem.cpp
cgm/branches/cubit/util/GeometryDefines.h
cgm/branches/cubit/util/GetLongOpt.hpp
cgm/branches/cubit/util/GfxDebug.cpp
cgm/branches/cubit/util/GfxDebug.hpp
cgm/branches/cubit/util/IntersectionTool.cpp
cgm/branches/cubit/util/IntersectionTool.hpp
cgm/branches/cubit/util/KDDTree.cpp
cgm/branches/cubit/util/Makefile.am
cgm/branches/cubit/util/MemoryBlock.hpp
cgm/branches/cubit/util/MemoryManager.cpp
cgm/branches/cubit/util/MemoryManager.hpp
cgm/branches/cubit/util/OctTree.cpp
cgm/branches/cubit/util/OtherFiles/make.client
cgm/branches/cubit/util/ParamTool.hpp
cgm/branches/cubit/util/PlanarParamTool.cpp
cgm/branches/cubit/util/PlanarParamTool.hpp
cgm/branches/cubit/util/PriorityQueue.cpp
cgm/branches/cubit/util/RTree.cpp
cgm/branches/cubit/util/RTree.hpp
cgm/branches/cubit/util/RandomMersenne.cpp
cgm/branches/cubit/util/SDLList.cpp
cgm/branches/cubit/util/SDLList.hpp
cgm/branches/cubit/util/SettingHandler.cpp
cgm/branches/cubit/util/SettingHandler.hpp
cgm/branches/cubit/util/TextProgressTool.cpp
cgm/branches/cubit/util/ToolData.cpp
cgm/branches/cubit/util/ToolData.hpp
cgm/branches/cubit/util/ToolDataUser.cpp
cgm/branches/cubit/util/ToolDataUser.hpp
cgm/branches/cubit/util/TtyProgressTool.cpp
Log:
CGM from Cubit 12.0 (w/out ACIS)
Modified: cgm/branches/cubit/configure.in
===================================================================
--- cgm/branches/cubit/configure.in 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/configure.in 2010-01-06 19:22:14 UTC (rev 3423)
@@ -12,7 +12,7 @@
AC_PROG_LIBTOOL
LIBS="-lm"
AC_PROG_LIBTOOL
-AC_C_BIGENDIAN( [LITTLE_ENDIAN=], [LITTLE_ENDIAN="-DLITTLE_ENDIAN=BYTE_ORDER"] )
+AC_C_BIGENDIAN( [LITTLE_ENDIAN=], [LITTLE_ENDIAN=-DLITTLE_ENDIAN] )
AC_SUBST(LITTLE_ENDIAN)
Modified: cgm/branches/cubit/geom/AnalyticGeometryTool.cpp
===================================================================
--- cgm/branches/cubit/geom/AnalyticGeometryTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/AnalyticGeometryTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -17,6 +17,8 @@
#include "DLIList.hpp"
#include <math.h>
#include "CastTo.hpp"
+#include "GfxPreview.hpp"
+#include "GMem.hpp"
#include <fstream>
using std::cout;
@@ -144,6 +146,7 @@
AnalyticGeometryTool::~AnalyticGeometryTool()
{
+ instance_ = NULL;
}
//***************************************************************************
@@ -1996,57 +1999,85 @@
double cubit2pln_mtx[4][4],
pln2cubit_mtx[4][4];
double pln_orig[3];
+ double box_tol = 1e-6;
+ // Adjust bounding box if it is zero in any direction
+ double abox_min[3], abox_max[3];
+ copy_pnt( box_min, abox_min );
+ copy_pnt( box_max, abox_max );
+
+ double x_range = fabs(box_max[0]-box_min[0]);
+ double y_range = fabs(box_max[1]-box_min[1]);
+ double z_range = fabs(box_max[2]-box_min[2]);
+
+ if( x_range < box_tol || y_range < box_tol || z_range < box_tol )
+ {
+ // Adjust zero length side(s) to maximum range
+ double adj = CUBIT_MAX((CUBIT_MAX((x_range),(y_range))),(z_range))/2.0;
+
+ // Arbitrarily expand box if it is zero in size
+ if( adj < box_tol )
+ adj = 5.0;
+
+ if( x_range < box_tol )
+ {
+ abox_min[0] -= adj;
+ abox_max[0] += adj;
+ }
+ if( y_range < box_tol )
+ {
+ abox_min[1] -= adj;
+ abox_max[1] += adj;
+ }
+ if( z_range < box_tol )
+ {
+ abox_min[2] -= adj;
+ abox_max[2] += adj;
+ }
+ }
+
+ // Get plane origin
double A = pln_norm[0];
double B = pln_norm[1];
double C = pln_norm[2];
double D = pln_coeff;
-
- //PRINT_INFO( "A=%0.4lf, B=%0.4lf, C=%0.4lf, D=%0.4lf\n", A, B, C, D );
-
get_pln_orig_norm( A, B, C, D, pln_orig );
-// PRINT_INFO( "Plane Orig = %0.4lf, %0.4lf, %0.4lf\n", pln_orig[0],
-// pln_orig[1], pln_orig[2] );
-
- // Find intersections of edges with plane. Add to unique
- // array. At most there are 6 intersections...
+ // Find intersections of edges with plane. Add to unique array. At most
+ // there are 6 intersections...
double int_array[6][3];
int num_int = 0;
- num_int = get_plane_bbox_intersections( box_min, box_max, pln_orig, pln_norm, int_array );
+ num_int = get_plane_bbox_intersections( abox_min, abox_max, pln_orig, pln_norm,
+ int_array );
- //attempt to adjust bounding box to x,y,z intercepts of plane
- if( num_int == 0 )
+ // Adjust so plane intercepts bounding box
+ if( num_int < 3 )
{
- //Stretch bounding box so that plane will fit, for sure
- //get x,y,z intercepts
- double x_intercept = 0;
- double y_intercept = 0;
- double z_intercept = 0;
- if( !dbl_eq( A, 0.0 ) )
- x_intercept = -D/A;
- if( !dbl_eq( B, 0.0 ) )
- y_intercept = -D/B;
- if( !dbl_eq( C, 0.0 ) )
- z_intercept = -D/C;
-
- //adjust box
- if( x_intercept < box_min[0] )
- box_min[0] = x_intercept;
- else if( x_intercept > box_max[0] )
- box_max[0] = x_intercept;
+ // Move the plane to the center of the bounding box
+ double box_cent[3];
+ box_cent[0] = (abox_min[0]+abox_max[0])/2.0;
+ box_cent[1] = (abox_min[1]+abox_max[1])/2.0;
+ box_cent[2] = (abox_min[2]+abox_max[2])/2.0;
- if( y_intercept < box_min[1] )
- box_min[1] = y_intercept;
- else if( y_intercept > box_max[1] )
- box_max[1] = y_intercept;
-
- if( z_intercept < box_min[2] )
- box_min[2] = z_intercept;
- else if( z_intercept > box_max[2] )
- box_max[2] = z_intercept;
+ // Get the intersections
+ num_int = get_plane_bbox_intersections( abox_min, abox_max, box_cent, pln_norm, int_array );
- num_int = get_plane_bbox_intersections( box_min, box_max, pln_orig, pln_norm, int_array );
+ // Project the points back to the original plane
+ switch (num_int)
+ {
+ case 6:
+ int_pnt_pln( int_array[5], pln_orig, pln_norm, int_array[5] );
+ case 5:
+ int_pnt_pln( int_array[4], pln_orig, pln_norm, int_array[4] );
+ case 4:
+ int_pnt_pln( int_array[3], pln_orig, pln_norm, int_array[3] );
+ case 3:
+ int_pnt_pln( int_array[2], pln_orig, pln_norm, int_array[2] );
+ case 2:
+ int_pnt_pln( int_array[1], pln_orig, pln_norm, int_array[1] );
+ case 1:
+ int_pnt_pln( int_array[0], pln_orig, pln_norm, int_array[0] );
+ }
}
if( num_int == 0 )
@@ -2152,12 +2183,11 @@
}
int AnalyticGeometryTool::get_plane_bbox_intersections( double box_min[3],
- double box_max[3],
- double pln_orig[3],
- double pln_norm[3],
- double int_array[6][3])
+ double box_max[3],
+ double pln_orig[3],
+ double pln_norm[3],
+ double int_array[6][3])
{
-
// Fill in an array with all 8 box corners
double corner[8][3];
get_box_corners( box_min, box_max, corner );
@@ -2211,7 +2241,7 @@
}
CubitStatus
-AnalyticGeometryTool::get_tight_bounding_box( DLIList<CubitVector*> &point_list,
+AnalyticGeometryTool::get_tight_bounding_box( DLIList<CubitVector*> &point_list,
CubitVector ¢er,
CubitVector axes[3],
CubitVector &extension )
@@ -2227,6 +2257,7 @@
for( i=0; i<num_pnts; i++ )
{
vec = point_list.get_and_step();
+ //GfxPreview::draw_point( vec, 3 );
pnt_arr[i].x = vec->x();
pnt_arr[i].y = vec->y();
@@ -3231,6 +3262,17 @@
double angle[3];
InitialGuess(N,pt,angle);
double oldVolume = Volume(N,pt,angle);
+
+ //if initial guess gives angles that are zero, the rest of this code
+ //can give bounding box that isn't tight. This probably
+ //isn't the best fix but it works. CDE 4-20-2009
+ if( angle[0] == 0 )
+ angle[0] = 0.5;
+ if( angle[1] == 0 )
+ angle[1] = 0.5;
+ if( angle[2] == 0 )
+ angle[2] = 0.5;
+
double saveAngle[3] = { angle[0], angle[1], angle[2] };
// Powell's direction set method
@@ -6111,7 +6153,7 @@
//---------------------------------------------------------------------------
double
-AnalyticGeometryTool::AreaIntersection( Triangle &tri1, Triangle &tri2 )
+AnalyticGeometryTool::AreaIntersection( Triangle &tri1, Triangle &tri2 )
{
AgtTriList* list = Intersection(&tri1,&tri2);
double area = Area(list);
@@ -6180,7 +6222,7 @@
}
double
-AnalyticGeometryTool::ProjectedOverlap( Triangle3& tri1, Triangle3& tri2 )
+AnalyticGeometryTool::ProjectedOverlap( Triangle3& tri1, Triangle3& tri2, bool draw_overlap )
{
// Transform both triangles into local coordinate system of tri1
// to eliminate z-coordinate.
@@ -6209,9 +6251,10 @@
origin[1] = tri1.b.y;
origin[2] = tri1.b.z;
+ double mtxTriOne2Global[4][4];
+ vecs_to_mtx( x, y, z, origin, mtxTriOne2Global ); // Really mtxTriOne2Global
double mtxGlobal2TriOne[4][4];
- vecs_to_mtx( x, y, z, origin, mtxGlobal2TriOne ); // Really mtxTriOne2Global
- inv_trans_mtx( mtxGlobal2TriOne, mtxGlobal2TriOne );
+ inv_trans_mtx( mtxTriOne2Global, mtxGlobal2TriOne );
double v0[3], v1[3], v2[3]; // Vertices of triangle
v0[0]=tri1.b.x; v0[1]=tri1.b.y; v0[2]=tri1.b.z;
@@ -6244,5 +6287,63 @@
T2.v[2].x = v2[0]; T2.v[2].y = v2[1];
// Now find area of overlap
- return AreaIntersection( T1, T2 );
+ if( draw_overlap )
+ {
+ AgtTriList* list = Intersection(&T1, &T2);
+ double overlap_area = Area(list);
+ while ( list )
+ {
+ Triangle *tmp_tri = list->tri;
+
+ v0[0]=tmp_tri->v[0].x;
+ v0[1]=tmp_tri->v[0].y;
+ v0[2]=0;
+
+ v1[0]=tmp_tri->v[1].x;
+ v1[1]=tmp_tri->v[1].y;
+ v1[2]=0;
+
+ v2[0]=tmp_tri->v[2].x;
+ v2[1]=tmp_tri->v[2].y;
+ v2[2]=0;
+
+ transform_pnt( mtxTriOne2Global, v0, v0 );
+ transform_pnt( mtxTriOne2Global, v1, v1 );
+ transform_pnt( mtxTriOne2Global, v2, v2 );
+
+ //Now Draw the thing
+ GMem g_mem;
+ g_mem.allocate_tri(1);
+ g_mem.pointListCount = 3;
+
+ g_mem.point_list()[0].x = v0[0];
+ g_mem.point_list()[0].y = v0[1];
+ g_mem.point_list()[0].z = v0[2];
+
+ g_mem.point_list()[1].x = v1[0];
+ g_mem.point_list()[1].y = v1[1];
+ g_mem.point_list()[1].z = v1[2];
+
+ g_mem.point_list()[2].x = v2[0];
+ g_mem.point_list()[2].y = v2[1];
+ g_mem.point_list()[2].z = v2[2];
+
+ g_mem.facet_list()[0] = 3;
+ g_mem.facet_list()[1] = 0;
+ g_mem.facet_list()[2] = 1;
+ g_mem.facet_list()[3] = 2;
+
+ g_mem.fListCount = 1;
+ GfxPreview::draw_polygon(g_mem.point_list(),3,4,4,true);
+
+ AgtTriList* save = list;
+ list = list->next;
+ delete save->tri;
+ delete save;
+ }
+ delete list;
+ return overlap_area;
+ }
+ else
+ return AreaIntersection( T1, T2 );
}
Modified: cgm/branches/cubit/geom/AnalyticGeometryTool.hpp
===================================================================
--- cgm/branches/cubit/geom/AnalyticGeometryTool.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/AnalyticGeometryTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -271,6 +271,7 @@
// END OF MAGIC SOFTWARE
///////////////////////////////////////////////////////////////////////////////
+//! Performs calculations on analytic geometry.
class CUBIT_GEOM_EXPORT AnalyticGeometryTool
{
public:
@@ -278,29 +279,41 @@
~AnalyticGeometryTool();
static AnalyticGeometryTool* instance();
+ static void delete_instance() { if( instance_ ) delete instance_; };
+
//*********************************************************
// Double numbers
//*********************************************************
+
+ /*! Check to see if double numbers are equal within epsilon.
+ Values are equal if fabs(val_1 - val_2) < epsilon.
+ Epsilon is determined by next two functions. */
CubitBoolean dbl_eq( double val_1, double val_2 );
- // Check to see if double numbers are equal within epsilon.
- // Values are equal if fabs(val_1 - val_2) < epsilon.
- // Epsilon is determined by next two functions.
+
+ //! Get epsilon used for double number comparisons.
+ //! Default value is 1e-6.
double get_epsilon();
+ //! Set epsilon used for double number comparisons.
+ //! Default value is 1e-6.
double set_epsilon( double new_epsilon );
- // Get/set epsilon used for double number comparisons.
- // Default value is 1e-6.
+
#ifdef BOYD14
+ //! Swap two double number memory locations.
void swap_dbl(double& dbl1,double& dbl2);
- // Swap two double number memory locations.
+
+ //! Find minimum array of double numbers.
+ //! Position in array is returned as well.
double min_array( const double *array, int len, int &pos );
+
+ //! Find maximum array of double numbers.
+ //! Position in array is returned as well.
double max_array( const double *array, int len, int &pos );
- // Find minimum or maximum of an array of double numbers.
- // Position in array is returned as well.
#endif
+
+ /*! Round value to either -1, 0, or 1 if within epsilon to
+ to one of these. Epsilon determined by get_epsilon/set_epsilon
+ functions. */
void round_near_val( double& val );
- // Round value to either -1, 0, or 1 if within epsilon to
- // to one of these. Epsilon determined by get_epsilon/set_epsilon
- // functions.
//**************************************************************************
// Matrices & Transforms
@@ -314,20 +327,27 @@
// | x3 y3 z3 0 |
// | ox oy oz 1 |
// - -
+ /*! This functions applies the transformation matrix to the specified
+ point and returns the new point coordinates through the call list.
+ Point in and point out can be the same memory address or different. */
void transform_pnt( double m[4][4], double pin[3], double pout[3] );
- // This functions applies the transformation matrix to the specified
- // point and returns the new point coordinates through the call list.
- // Point in and point out can be the same memory address or different.
+
#ifdef BOYD14
+ //! Transform a point array. Points can be transformed in place.
void transform_pnt_arr( double m[4][4], double pin_arr[][3],
size_t num_pnts, double pout_arr[][3] );
- // Transform a point array. Points can be transformed in place.
#endif
+
+ /*! This routine applies a transformation matrix to a specified vector
+ and returns the new vector orientation. Vector in and vector out can
+ be the same memory address or different. */
void transform_vec( double m3[3][3], double vin[3], double vout[3] );
+
+ /*! This routine applies a transformation matrix to a specified vector
+ and returns the new vector orientation. Vector in and vector out can
+ be the same memory address or different. */
void transform_vec( double m4[4][4], double vin[3], double vout[3] );
- // This routine applies a transformation matrix to a specified vector
- // and returns the new vector orientation. Vector in and vector out can
- // be the same memory address or different.
+
#ifdef BOYD14
double transform_dist( double m3[3][3], double distance, double v[3] );
double transform_dist( double m4[4][4], double distance, double v[3] );
@@ -339,47 +359,68 @@
// 6 units covers in the x-direction may not equal the distance 6 units
// covers in the y-direction - a rectangular system!).
#endif
+ /*! Transforms a line using the given transformation mtx. The mtx is typically
+ built using add_origin_to_rotation_mtx. */
void transform_line( double rot_mtx[4][4], double origin[3], double axis[3] );
+ /*! Transforms a line using the given transformation mtx. The mtx is typically
+ built using add_origin_to_rotation_mtx. */
void transform_line( double rot_mtx[4][4], CubitVector &origin, CubitVector &axis );
- // Transforms a line using the given transformation mtx. The mtx is typically
- // built using add_origin_to_rotation_mtx.
+
+
+ //@{
+ /*! This routine simply copies one matrix to another. If a NULL is passed in
+ for the from matrix, then the identity matrix is copied into the out matrix.
+ Last function allows you to specify 1st 3 doubles of row 4 (origin) of the
+ 4x4 matrix.*/
void copy_mtx( double from[3][3],double to[3][3] );
void copy_mtx( double from[4][4], double to[4][4] );
void copy_mtx( double from[4][4], double to[3][3] );
void copy_mtx(double from[3][3], double to[4][4], double *origin = NULL );
- // This routine simply copies one matrix to another. If a NULL is passed in
- // for the from matrix, then the identity matrix is copied into the out matrix.
- // Last function allows you to specify 1st 3 doubles of row 4 (origin) of the
- // 4x4 matrix.
+ //@}
+
+ //@{
+ //! This routine determines the tranformation matrix given the theta and
+ //! the vector to cross through.
void create_rotation_mtx( double theta, double v[3], double mtx3x3[3][3] );
void create_rotation_mtx( double theta, double v[3], double mtx4x4[4][4] );
- // This routine determines the tranformation matrix given the theta and
- // the vector to cross through.
+ //@}
+
+ /*! Adds origin to rotation matrix, so you can rotate points about a line.
+ Line is defined as original vector used in create_rotation_mtx and
+ the origin. */
void add_origin_to_rotation_mtx( double rot_mtx[4][4], double origin[3] );
- // Adds origin to rotation matrix, so you can rotate points about a line.
- // Line is defined as original vector used in create_rotation_mtx and
- // the origin.
+
+ //@{
+ //! \brief Simply sets the given matrix to the identity matrix.
void identity_mtx( double mtx3x3[3][3] );
void identity_mtx( double mtx4x4[4][4] );
- // Simply sets the given matrix to the identity matrix.
+ //@}
+
+ //@{
+ //! Gets rotation angles to rotate one system to another - returned rotation
+ //! angles are about global system.
+ //! To use the result from this function, align the unoriented object's origin
+ //! with the global origin, then apply the rotation angles returned from this
+ //! routine to the object in the order of ax,ay,az about the global origin.
+ //! The object will be oriented such that its xyz axes will point in the same
+ //! direction as the object whose transformation matrix was given. The object
+ //! can then be translated.
void mtx_to_angs( double mtx3x3[3][3], double &ax, double &ay, double &az );
void mtx_to_angs( double mtx4x4[4][4], double &ax, double &ay, double &az );
- // Gets rotation angles to rotate one system to another - returned rotation
- // angles are about global system.
- // To use the result from this function, align the unoriented object's origin
- // with the global origin, then apply the rotation angles returned from this
- // routine to the object in the order of ax,ay,az about the global origin.
- // The object will be oriented such that its xyz axes will point in the same
- // direction as the object whose transformation matrix was given. The object
- // can then be translated.
+ //@}
+
+
+ //@{
+ // This routine rotates a 3x3 system given a transformation matrix. The
+ // matrix can be rotated in place by sending same variable in & out, or a
+ // new matrix can be created. In the 4x4 case, the translation portion
+ // of the matrix is unchanged.
void rotate_system( double mtx[3][3], double sys_in[3][3],
double sys_out[3][3] );
void rotate_system( double mtx[4][4], double sys_in[4][4],
double sys_out[4][4] );
- // This routine rotates a 3x3 system given a transformation matrix. The
- // matrix can be rotated in place by sending same variable in & out, or a
- // new matrix can be created. In the 4x4 case, the translation portion
- // of the matrix is unchanged.
+ //@}
+
#ifdef BOYD14
double mtx_to_ratio( double m3[3][3] );
double mtx_to_ratio( double m4[4][4] );
@@ -387,324 +428,384 @@
// length in the first system. Multiply the length in system 1 by this
// ratio to get the length in system 2.
#endif
+
+ //! Find determinant of matrix.
double det_mtx( double m[3][3] );
- // Find determinant of matrix.
+
+ //@{
+ // Multiply matrices together. If any input is NULL, the identity
+ // matrix is used in its place.
void mult_mtx( double a[3][3],double b[3][3], double d[3][3] );
void mult_mtx( double a[4][4], double b[4][4], double d[4][4] );
- // Multiply matrices together. If any input is NULL, the identity
- // matrix is used in its place.
+ //@}
+
+ //!This routine inverts a 3x3 matrix using the adjoint method. If NULL
+ //! is sent in for first matrix, the second matrix is set to the identity
+ //! matrix. If the same memory address is passed in for both incoming and
+ //! outgoing matrices, the matrix is inverted in place. Returns CUBIT_FAILURE
+ //! if no inverse exists.
CubitStatus inv_mtx_adj( double mtx[3][3], double inv_mtx[3][3] );
- //This routine inverts a 3x3 matrix using the adjoint method. If NULL
- // is sent in for first matrix, the second matrix is set to the identity
- // matrix. If the same memory address is passed in for both incoming and
- // outgoing matrices, the matrix is inverted in place. Returns CUBIT_FAILURE
- // if no inverse exists.
+
+ //! This routine inverts a 4x4 transformation matrix. If NULL is sent in
+ //! for first matrix, the second matrix is set to the identity matrix. If
+ //! the same memory address is passed in for both incoming and outgoing matrices,
+ //! the matrix is inverted in place. Uses LU decomposition.
CubitStatus inv_trans_mtx( double transf[4][4], double inv_transf[4][4] );
- // This routine inverts a 4x4 transformation matrix. If NULL is sent in
- // for first matrix, the second matrix is set to the identity matrix. If
- // the same memory address is passed in for both incoming and outgoing matrices,
- // the matrix is inverted in place. Uses LU decomposition.
+
+ //@{
+ //! Creates a transformation matrix given three vectors (and origin
+ //! for 4x4 case).
void vecs_to_mtx( double xvec[3], double yvec[3], double zvec[3],
double matrix[3][3] );
void vecs_to_mtx( double xvec[3], double yvec[3], double zvec[3],
double origin[3], double matrix[4][4] );
- // Creates a transformation matrix given three vectors (and origin
- // for 4x4 case).
+ //@}
+
#ifdef BOYD14
+ //@{
+ //! Extract vectors from a matrix. NULL can be input for any of the
+ //! arguments and the routine will not extract that vector. NULL can
+ //! also be input for the matrix, in which case the function assumes
+ //! the identity matrix.
void mtx_to_vecs( double matrix[3][3], double xvec[3], double yvec[3],
double zvec[3] );
void mtx_to_vecs( double matrix[4][4], double xvec[3], double yvec[3],
double zvec[3], double origin[3] );
- // Extract vectors from a matrix. NULL can be input for any of the
- // arguments and the routine will not extract that vector. NULL can
- // also be input for the matrix, in which case the function assumes
- // the identity matrix.
+ //@}
#endif
-
+
+ //@{
+ //! Prints matrix values, for debugging.
void print_mtx( double mtx[3][3] );
void print_mtx( double mtx[4][4] );
- // Prints matrix values, for debugging.
+ //@}
//**************************************************************************
// 3D Points
//**************************************************************************
+ //! Copy one double[3] point to another double[3] point (uses memcpy).
+ //! If first point in NULL then second point is set to 0,0,0.
void copy_pnt( double pnt_in[3], double pnt_out[3] );
- // Copy one double[3] point to another double[3] point (uses memcpy).
- // If first point in NULL then second point is set to 0,0,0.
+
+ //@{
+ //! For going back and forth from CubitVectors
void copy_pnt( double pnt_in[3], CubitVector &cubit_vec );
void copy_pnt( CubitVector &cubit_vec, double pnt_out[3] );
- // For going back and forth from CubitVectors
+ //@}
+
+ //! Sets the value of pnt to x,y,z (inline function).
void set_pnt( double pnt[3], double x, double y, double z );
- // Sets the value of pnt to x,y,z (inline function).
+
#ifdef BOYD14
+ //! Swaps two double[3] points with each other.
void swap_pnt(double pnt1[3],double pnt2[3]);
- // Swaps two double[3] points with each other.
#endif
+
+ //! Compares two points to determine if they are equivalent. The
+ //! equivalence is based on epsilon (get_epsilon, set_epsilon).
+ //! If the distance between them is less than epsilon, the points
+ //! are considered equal.
CubitBoolean pnt_eq( double pnt1[3],double pnt2[3] );
- // Compares two points to determine if they are equivalent. The
- // equivalence is based on epsilon (get_epsilon, set_epsilon).
- // If the distance between them is less than epsilon, the points
- // are considered equal.
+
#ifdef BOYD14
+ //! Compares two point arrays or portions of two point arrays to
+ //! determine if they are equivalent within epsilon (get_epsilon,
+ //! set_epsilon). Checking will stop when either of the array ends
+ //! is encountered or num_to_check is exceeded. Note that he function
+ //! can return CUBIT_TRUE even if the arrays are of a different length.
CubitBoolean pnt_arr_eq( double **pnt_arr1, long num1, double **pnt_arr2,
long num2, long start_pos1 = 0, long start_pos2 = 0,
long num_to_check = -1 );
- // Compares two point arrays or portions of two point arrays to
- // determine if they are equivalent within epsilon (get_epsilon,
- // set_epsilon). Checking will stop when either of the array ends
- // is encountered or num_to_check is exceeded. Note that he function
- // can return CUBIT_TRUE even if the arrays are of a different length.
#endif
+
+ //! Function to mirror a point about a plane. The mirror point
+ //! is the same distance from the plane as the original, but on
+ //! the opposite side of the plane. Function returns CUBIT_FAILURE
+ //! if the point is on the plane - in which case the point is
+ //! just copied.
CubitStatus mirror_pnt( double pnt[3], double pln_orig[3],
double pln_norm[3], double m_pnt[3]);
- // Function to mirror a point about a plane. The mirror point
- // is the same distance from the plane as the original, but on
- // the opposite side of the plane. Function returns CUBIT_FAILURE
- // if the point is on the plane - in which case the point is
- // just copied.
#ifdef BOYD14
+ //! Mirrors an array of points about a plane. If mirror_arr is
+ //! non-NULL, function assumes it was allocated to correct lenght.
+ //! If NULL, function allocates the array.
double ** mirror_pnt_arr( double **pnt_arr, long num_pnts,
double pln_orig[3], double pln_norm[3],
double **mirror_arr );
- // Mirrors an array of points about a plane. If mirror_arr is
- // non-NULL, function assumes it was allocated to correct lenght.
- // If NULL, function allocates the array.
#endif
+
+ //! Given start pnt, vec dir and length find next point in space. The
+ //! vector direction is first unitized then the following formula is used:
+ //! new_point[] = start_point[] + (length * unit_vector[])
+ //! new_pnt can be the same as input point (overwrites old location).
CubitStatus next_pnt( double str_pnt[3], double vec_dir[3], double len,
double new_pnt[3]);
- // Given start pnt, vec dir and length find next point in space. The
- // vector direction is first unitized then the following formula is used:
- // new_point[] = start_point[] + (length * unit_vector[])
- // new_pnt can be the same as input point (overwrites old location).
+
#ifdef BOYD14
+
+ //! This routine creates a point between two other points, at a specified
+ //! distance between the two given points. The distance can be either
+ //! absolute (meaning an actual distance, ie. in mm), or a normalized distance
+ //! (ie., 50% or 0.5 between the other two points). The reference point for
+ //! the distance is always the first point.
+ //! - The normalized distance does not need to be between 0.0 & 1.0. For example,
+ //! a 1.25 normalized distance would result in a point 25% beyond the second
+ //! point (not actually "between" the two points).
+ //! - The distances can also be negative. For example, a -1.25 normalized
+ //! distance would result in a point 25% before the first point. A -50.0
+ //! absolute distance would extend 50.0 from the first point in the opposite
+ //! direction of the second point.
CubitStatus pnt_between2pnts( double pnt1[3], double pnt2[3],
AgtDistanceMethod dist_meth, double dist,
double out_pnt[3] );
- // This routine creates a point between two other points, at a specified
- // distance between the two given points. The distance can be either
- // absolute (meaning an actual distance, ie. in mm), or a normalized distance
- // (ie., 50% or 0.5 between the other two points). The reference point for
- // the distance is always the first point.
- // - The normalized distance does not need to be between 0.0 & 1.0. For example,
- // a 1.25 normalized distance would result in a point 25% beyond the second
- // point (not actually "between" the two points).
- // - The distances can also be negative. For example, a -1.25 normalized
- // distance would result in a point 25% before the first point. A -50.0
- // absolute distance would extend 50.0 from the first point in the opposite
- // direction of the second point.
#endif
//***************************************************************************
// 3D Vectors
//***************************************************************************
+ //! Finds unit vector of input vector (vout can equal vin - converts in place).
CubitStatus unit_vec( double vin[3], double vout[3] );
- // Finds unit vector of input vector (vout can equal vin - converts in place).
+
+ //! Dots two vectors. Property of dot product is:
+ //! angle between vectors acute if dot product > 0
+ //! angle between vectors obtuse if dot product < 0
+ //! angle between vectors 90 deg if dot product = 0
double dot_vec( double uval[3], double vval[3] );
- // Dots two vectors. Property of dot product is:
- // angle between vectors acute if dot product > 0
- // angle between vectors obtuse if dot product < 0
- // angle between vectors 90 deg if dot product = 0
+
+ //! Finds cross product of two vectors:
+ //! cross[0] = u[1] * v[2] - u[2] * v[1];
+ //! cross[1] = u[2] * v[0] - u[0] * v[2];
+ //! cross[2] = u[0] * v[1] - u[1] * v[0];
void cross_vec( double uval[3], double vval[3], double cross[3] );
- // Finds cross product of two vectors:
- // cross[0] = u[1] * v[2] - u[2] * v[1];
- // cross[1] = u[2] * v[0] - u[0] * v[2];
- // cross[2] = u[0] * v[1] - u[1] * v[0];
+
+ //! Finds unit vector that is cross product of two vectors.
void cross_vec_unit( double uval[3], double vval[3], double cross[3] );
- // Finds unit vector that is cross product of two vectors.
+
+ //! Finds 2 arbitrary orthoganal vectors to the first.
void orth_vecs( double uvect[3], double vvect[3], double wvect[3] );
- // Finds 2 arbitrary orthoganal vectors to the first.
+
+ //! Finds the magnitude of a vector:
+ //! magnitude = sqrt (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
double mag_vec( double vec[3] );
- // Finds the magnitude of a vector:
- // magnitude = sqrt (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
+
+ //! Finds a vector from str_pnt to stp_pnt.
+ //! Returns CUBIT_FAILURE if points are coincident.
CubitStatus get_vec ( double str_pnt[3], double stp_pnt[3],
double vector_out[3] );
- // Finds a vector from str_pnt to stp_pnt.
- // Returns CUBIT_FAILURE if points are coincident.
+
+ //! Finds a unit vector from str_pnt to stp_pnt.
+ //! Returns CUBIT_FAILURE if points are coincident.
CubitStatus get_vec_unit( double str_pnt[3], double stp_pnt[3],
double uv_out[3] );
- // Finds a unit vector from str_pnt to stp_pnt.
- // Returns CUBIT_FAILURE if points are coincident.
+
+ //! Multiples a vector by a constant (vec_out can equal vec).
void mult_vecxconst( double constant, double vec[3], double vec_out[3] );
- // Multiples a vector by a constant (vec_out can equal vec).
+
#ifdef BOYD14
+ //! Adds two vectors (vec_out can equal vec_1 or vec_2)
void add_vec_vec( double vec_1[3], double vec_2[3], double vec_out[3]);
- // Adds two vectors (vec_out can equal vec_1 or vec_2)
+
+ //! Subtracts two vectors (vec_out can equal vec_1 or vec_2).
void sub_vec_vec( double vec_1[3], double vec_2[3], double vec_out[3] );
- // Subtracts two vectors (vec_out can equal vec_1 or vec_2).
#endif
+
#ifdef BOYD14
+ //! Rotate a vector about another vector a given angle. v_out can equal
+ //! v1 (v_out replaces v1) or be a new vector.
void rotate_vec( double v1[3], double v2[3], double angle, double v_out[3] );
- // Rotate a vector about another vector a given angle. v_out can equal
- // v1 (v_out replaces v1) or be a new vector.
#endif
+
+ //! Multiples -1.0 by a vector (vout can equal vin).
void reverse_vec( double vin[3],double vout[3] );
- // Multiples -1.0 by a vector (vout can equal vin).
+
+ //! Finds angle in radians between two vectors. Angle will always be
+ //! between 0.0 and PI. For accuracy, the routine uses the cosine for large
+ //! angles and the sine for small angles.
double angle_vec_vec( double v1[3],double v2[3] );
- // Finds angle in radians between two vectors. Angle will always be
- // between 0.0 and PI. For accuracy, the routine uses the cosine for large
- // angles and the sine for small angles.
//***************************************************************************
// Distances
//***************************************************************************
+ //! Determines distance between two points in space.
double dist_pnt_pnt( double pnt1[3], double pnt2[3] );
- // Determines distance between two points in space.
+
#ifdef BOYD14
+ //! Determines shortest distance between two infinite lines. Optional
+ //! output also includes intersection points. The num_ints will be zero
+ //! if the lines are parallel, one if they physically cross and two if
+ //! they are non-parallel and non-crossing.
double dist_ln_ln( double ln_1_orig[3], double ln_1_vec[3],
double ln_2_orig[3], double ln_2_vec[3],
unsigned short *num_ints = NULL, double int_pnt1[3] = NULL,
double int_pnt2[3] = NULL );
- // Determines shortest distance between two infinite lines. Optional
- // output also includes intersection points. The num_ints will be zero
- // if the lines are parallel, one if they physically cross and two if
- // they are non-parallel and non-crossing.
+ //! This routine determines the shortest distance between a point and a
+ //! plane. This is the perpendicular distance from the point to the plane.
+ //! Optionally you can find which side of the plane the point is on and
+ //! the plane intersection with the point.
double dist_pnt_pln( double pnt[3], double pln_orig[3], double pln_norm[3],
AgtSide *side = NULL, double pln_int[3] = NULL );
- // This routine determines the shortest distance between a point and a
- // plane. This is the perpendicular distance from the point to the plane.
- // Optionally you can find which side of the plane the point is on and
- // the plane intersection with the point.
#endif
+ //! This routine determines the shortest distance between two planes. This
+ //! is the perpendicular distance between the two planes. Note that if the
+ //! two planes are not parallel, the returned distance is zero. The routine
+ //! can also be used to determine which side of the first plane the second
+ //! plane is on, and the orientation of the two planes to each other.
double dist_pln_pln( double pln_1_orig[3], double pln_1_norm[3],
double pln_2_orig[3], double pln_2_norm[3],
AgtSide *side = NULL, AgtOrientation *orien = NULL,
unsigned short *status = NULL );
- // This routine determines the shortest distance between two planes. This
- // is the perpendicular distance between the two planes. Note that if the
- // two planes are not parallel, the returned distance is zero. The routine
- // can also be used to determine which side of the first plane the second
- // plane is on, and the orientation of the two planes to each other.
#ifdef BOYD14
+ //! This routine determines the shortest distance between a line and a plane.
+ //! This is the perpendicular distance between the line and the plane. Note
+ //! that if the line is not parallel to the plane, the returned distance is
+ //! zero. You can also find which side of the plane the line is on and
+ //! the status (= 0 if line & plane not parallel).
double dist_ln_pln( double ln_orig[3], double ln_vec[3], double pln_orig[3],
double pln_norm[3], AgtSide *side = NULL,
unsigned short *status = NULL );
- // This routine determines the shortest distance between a line and a plane.
- // This is the perpendicular distance between the line and the plane. Note
- // that if the line is not parallel to the plane, the returned distance is
- // zero. You can also find which side of the plane the line is on and
- // the status (= 0 if line & plane not parallel).
+
+ //! This routine determines the shortest distance between a point and a line.
+ //! This is the perpendicular distance between the point and the line. You
+ //! can optionally get the intersection point of the point and line.
double dist_pnt_ln( double pnt[3], double ln_orig[3], double ln_vec[3],
double int_pnt[3] = NULL );
- // This routine determines the shortest distance between a point and a line.
- // This is the perpendicular distance between the point and the line. You
- // can optionally get the intersection point of the point and line.
#endif
//***************************************************************************
// Intersections
//***************************************************************************
+ //! This routine calculates the intersection point of a line and a plane.
+ //! Returns CUBIT_FAILURE if no intersection exists (line is parallel to the
+ //! plane).
CubitStatus int_ln_pln( double ln_orig[3], double ln_vec[3], double pln_orig[3],
double pln_norm[3], double int_pnt[3] );
- // This routine calculates the intersection point of a line and a plane.
- // Returns CUBIT_FAILURE if no intersection exists (line is parallel to the
- // plane).
+ //! This function finds the intersection of two lines. If the lines cross,
+ //! it finds the one unique point. If the lines do not cross (but are non-
+ //! parallel), it finds the nearest intersection points (a line drawn from
+ //! each of these intersections would be perpendicular to both lines).
+ //! Returns number of intersections found:
+ //! 0 intersections found, lines are parallel
+ //! 1 intersection found, lines physically intersect
+ //! 2 intersections found, lines do not intersect but nearest
+ //! intersections found
int int_ln_ln( double p1[3], double v1[3], double p2[3], double v2[3],
double int_pnt1[3], double int_pnt2[3] );
- // This function finds the intersection of two lines. If the lines cross,
- // it finds the one unique point. If the lines do not cross (but are non-
- // parallel), it finds the nearest intersection points (a line drawn from
- // each of these intersections would be perpendicular to both lines).
- // Returns number of intersections found:
- // 0 intersections found, lines are parallel
- // 1 intersection found, lines physically intersect
- // 2 intersections found, lines do not intersect but nearest
- // intersections found
+
+ //! This routine finds the perpendicular intersection of a point & line. This
+ //! point will lie on the line.
+ //! Returns 0 if point is not on the line, otherwise 1.
int int_pnt_ln( double pnt[3], double ln_orig[3], double ln_vec[3],
double int_pnt[3] );
- // This routine finds the perpendicular intersection of a point & line. This
- // point will lie on the line.
- // Returns 0 if point is not on the line, otherwise 1.
+
+ //! This routine determines the perpendicular intersection of a point and a
+ //! plane. This is the perpendicular intersection point on the plane.
+ //! Returns 0 if point is not on the plane, otherwise 1.
int int_pnt_pln( double pnt[3], double pln_orig[3], double pln_norm[3],
double pln_int[3] );
- // This routine determines the perpendicular intersection of a point and a
- // plane. This is the perpendicular intersection point on the plane.
- // Returns 0 if point is not on the plane, otherwise 1.
+
+ //! This routine finds intersection of two planes. This intersection results
+ //! in a line. Returns CUBIT_FAILURE if planes are parallel.
CubitStatus int_pln_pln( double pln_1_orig[3], double pln_1_norm[3],
double pln_2_orig[3], double pln_2_norm[3],
double ln_orig[3], double ln_vec[3] );
- // This routine finds intersection of two planes. This intersection results
- // in a line. Returns CUBIT_FAILURE if planes are parallel.
#ifdef BOYD14
+ //! This routine finds the intersection of three orthoganal planes. This
+ //! intersection is a point. Returns CUBIT_FAILURE if no point intersection
+ //! exists.
CubitStatus int_pln_pln_pln( double pln_1_orig[3], double pln_1_norm[3],
double pln_2_orig[3], double pln_2_norm[3],
double pln_3_orig[3], double pln_3_norm[3],
double int_pnt[3] );
- // This routine finds the intersection of three orthoganal planes. This
- // intersection is a point. Returns CUBIT_FAILURE if no point intersection
- // exists.
#endif
//**************************************************************************
// Comparison/Containment Tests
//**************************************************************************
+ //! This routine checks to see if two vectors are parallel. Two vectors
+ //! are considered parallel if they are pointing in the same direction or
+ //! opposite directions.
CubitBoolean is_vec_par( double vec_1[3], double vec_2[3] );
- // This routine checks to see if two vectors are parallel. Two vectors
- // are considered parallel if they are pointing in the same direction or
- // opposite directions.
+
+ //! This routine checks to see if two vectors are perpendicular. Two vectors
+ //! are considered perpendicular if they are PI/2 radians to each other.
CubitBoolean is_vec_perp( double vec_1[3],double vec_2[3]);
- // This routine checks to see if two vectors are perpendicular. Two vectors
- // are considered perpendicular if they are PI/2 radians to each other.
+
+ //! This routine checks to see if two vectors point in the same direction.
+ //! The vector magnitudes do not have to be equal for a successful return.
CubitBoolean is_vecs_same_dir( double vec_1[3], double vec_2[3] );
- // This routine checks to see if two vectors point in the same direction.
- // The vector magnitudes do not have to be equal for a successful return.
+
+ //! This routined determines if a specified point is on a given infinite line
+ //! defined by a point and a vector.
CubitBoolean is_pnt_on_ln( double pnt[3], double ln_orig[3], double ln_vec[3] );
- // This routined determines if a specified point is on a given infinite line
- // defined by a point and a vector.
+
+ //! This routine determines if a specified point is on a given line segment
+ //! defined by two endpoints. The point is on the line only if it lies on
+ //! the line between or on the two endpoints.
CubitBoolean is_pnt_on_ln_seg( double pnt1[3], double end1[3], double end2[3] );
- // This routine determines if a specified point is on a given line segment
- // defined by two endpoints. The point is on the line only if it lies on
- // the line between or on the two endpoints.
+
+ //! This routined determines if a specified point is on a given plane
+ //! which is defined by an origin and three vectors.
CubitBoolean is_pnt_on_pln( double pnt[3], double pln_orig[3], double pln_norm[3] );
- // This routined determines if a specified point is on a given plane
- // which is defined by an origin and three vectors.
+
+ //! This routine determines if a specified line (defined by a point and
+ //! a vector) is in a given plane (defined by the two vectors in the plane
+ //! and the normal to that plane).
CubitBoolean is_ln_on_pln( double ln_orig[3], double ln_vec[3],
double pln_orig[3], double pln_norm[3] );
- // This routine determines if a specified line (defined by a point and
- // a vector) is in a given plane (defined by the two vectors in the plane
- // and the normal to that plane).
+
+
#ifdef BOYD14
+ //! This routine checks to see if two rays converge or diverge towards each
+ //! other. A ray is a line that is not infinite (consists of an origin and
+ //! a vector direction). Rays are defined to converge if they intersect
+ //! within a common plane to each ray (ie., if the rays do not lie in a
+ //! common plane, one of the rays is temporarily translated into the common
+ //! plane for checking). If the rays are parallel, no one common plane exists,
+ //! so they are checked as-is. See the following examples for a clearer
+ //! picture of how this routine works. Assume that the rays in the first row
+ //! are in planes that are parallel to this document but not in planes that are
+ //! necessarily coincident. Assume that the rays in the second row are in the
+ //! same plane. Note that rays may converge even if they are not in the same
+ //! plane.
+ //!
+ //! Examples:
+ //!
+ //! *----> <----* <----*
+ //! ^ ^ ^ ^
+ //! | | | |
+ //! | | | |
+ //! * * * *---->
+ //!
+ //! converge diverge converge converge
+ //!
+ //!
+ //! *---> *---> *---> <---* *---> *--->
+ //! <---* *--->
+ //! converge converge diverge diverge
CubitBoolean do_rays_converge( double ray_1_orig[3], double ray_1_vec[3],
double ray_2_orig[3], double ray_2_vec[3] );
- // This routine checks to see if two rays converge or diverge towards each
- // other. A ray is a line that is not infinite (consists of an origin and
- // a vector direction). Rays are defined to converge if they intersect
- // within a common plane to each ray (ie., if the rays do not lie in a
- // common plane, one of the rays is temporarily translated into the common
- // plane for checking). If the rays are parallel, no one common plane exists,
- // so they are checked as-is. See the following examples for a clearer
- // picture of how this routine works. Assume that the rays in the first row
- // are in planes that are parallel to this document but not in planes that are
- // necessarily coincident. Assume that the rays in the second row are in the
- // same plane. Note that rays may converge even if they are not in the same
- // plane.
- //
- // Examples:
- //
- // *----> <----* <----*
- // ^ ^ ^ ^
- // | | | |
- // | | | |
- // * * * *---->
- //
- // converge diverge converge converge
- //
- //
- // *---> *---> *---> <---* *---> *--->
- // <---* *--->
- // converge converge diverge diverge
+
+ //! This routine checks to see if two lines are colinear. Two lines are
+ //! considered colinear if they are parallel and the origin of one line is on
+ //! the other line.
CubitBoolean is_ln_on_ln( double ln_orig1[3], double ln_vec1[3],
double ln_orig2[3], double ln_vec2[3] );
- // This routine checks to see if two lines are colinear. Two lines are
- // considered colinear if they are parallel and the origin of one line is on
- // the other line.
#endif
+
+ //! This routine checks to see if two infinite planes are coincident.
CubitBoolean is_pln_on_pln( double pln_orig1[3], double pln_norm1[3],
double pln_orig2[3], double pln_norm2[3] );
- // This routine checks to see if two infinite planes are coincident.
//**************************************************************************
// Arcs/Circles
//**************************************************************************
+
+ //@{
+ //! Functions to populate an arc structure. The arc is defined with two
+ //! orthogonal vectors in a plane, the arc origin, the beginning angle
+ //! in radians to rotate from the start vector (towards second vector), the
+ //! ending angle in radians to rotate from the start vector, and the radius
+ //! of the arc. The arc is parameterized from 0 to 1.
void setup_arc( double vec_1[3], double vec_2[3], double origin[3],
double start_angle, double end_angle, // Angles in radians
double radius, AGT_3D_Arc &arc );
@@ -712,35 +813,47 @@
CubitVector origin, double start_angle, // Angles in radians
double end_angle, double radius,
AGT_3D_Arc &arc );
- // Functions to populate an arc structure. The arc is defined with two
- // orthogonal vectors in a plane, the arc origin, the beginning angle
- // in radians to rotate from the start vector (towards second vector), the
- // ending angle in radians to rotate from the start vector, and the radius
- // of the arc. The arc is parameterized from 0 to 1.
+ //@}
+
+ //@{
+ //! Given a parameter value from 0 to 1 on the arc, return the xyz location.
+ //! Arc is assumed to be parameterized from 0 to 1.
void get_arc_xyz( AGT_3D_Arc &arc, double param, double pnt[3] );
void get_arc_xyz( AGT_3D_Arc &arc, double param, CubitVector& pnt );
- // Given a parameter value from 0 to 1 on the arc, return the xyz location.
- // Arc is assumed to be parameterized from 0 to 1.
+ //@}
+ //! Get number of tessellation points on the circle required to
+ //! approximate the length of the circle within len_tolerance. Can
+ //! be used to find the number of tessellations points to display a
+ //! circle - smaller circles will have fewer tessellation points, larger
+ //! circles will have more tessellation points with the same tolerance.
+ //! Minimum number of tessellations points returned is 8.
int get_num_circle_tess_pnts( double radius, double len_tolerance = 1e-4 );
- // Get number of tessellation points on the circle required to
- // approximate the length of the circle within len_tolerance. Can
- // be used to find the number of tessellations points to display a
- // circle - smaller circles will have fewer tessellation points, larger
- // circles will have more tessellation points with the same tolerance.
- // Minimum number of tessellations points returned is 8.
//**************************************************************************
// Miscellaneous
//**************************************************************************
+
+ //! Finds an origin-normal format plane from reduced form
+ //! A*x + B*y + C*z + D = 0
void get_pln_orig_norm( double A, double B, double C, double D,
double pln_orig[3], double pln_norm[3] = NULL );
- // Finds an origin-normal format plane from reduced form
- // A*x + B*y + C*z + D = 0
+ //! Find 8 corners of a box given minimum and maximum points. Box is
+ //! defined starting from left-bottom-front clockwise (at front of box),
+ //! then to the rear in same order.
void get_box_corners( double box_min[3],double box_max[3],double c[8][3] );
- // Find 8 corners of a box given minimum and maximum points. Box is
- // defined starting from left-bottom-front clockwise (at front of box),
- // then to the rear in same order.
+
+ //@{
+ //! Finds the 4 corner points of the input infinite plane that just
+ //! intersects the input box (defined by bottom-left and top-right corners,
+ //! axis aligned with the cubit coordinate system) - plane should have
+ //! minimal area. The resultant plane's corner points can be extended out
+ //! by a percentage of diagonal or absolute (making it bigger than the minimal
+ //! area plane). extension_type - 0=none, 1=percentage, 2=absolute
+ //! If silent is CUBIT_TRUE, no error messages are given. Note this returns
+ //! points even if the plane doesn't physically intersect the given box... it
+ //! does this by moving the plane to the center of the box, doing the
+ //! intersection, then projecting the points back to the original plane.
CubitStatus min_pln_box_int_corners( const CubitPlane& plane,
const CubitBox& box,
int extension_type, double extension,
@@ -761,26 +874,34 @@
double p1[3], double p2[3], // OUT
double p3[3], double p4[3], // OUT
CubitBoolean silent = CUBIT_FALSE);
- // Finds the 4 corner points of the input infinite plane that just
- // intersects the input box (defined by bottom-left and top-right corners,
- // axis aligned with the cubit coordinate system) - plane should have
- // minimal area. The resultant plane's corner points can be extended out
- // by a percentage of diagonal or absolute (making it bigger than the minimal
- // area plane). extension_type - 0=none, 1=percentage, 2=absolute
- // If silent is CUBIT_TRUE, no error messages are given.
+ //@}
+ //@{
+ //! Finds the minimum size bounding box that fits around the points. Box
+ //! will not necessarily be oriented in xyz directions.
CubitStatus get_tight_bounding_box( DLIList<CubitVector*> &point_list,
CubitVector& p1, CubitVector& p2,
CubitVector& p3, CubitVector& p4,
CubitVector& p5, CubitVector& p6,
CubitVector& p7, CubitVector& p8);
- CubitStatus get_tight_bounding_box( DLIList<CubitVector*> &point_list,
+ CubitStatus get_tight_bounding_box( DLIList<CubitVector*> &point_list,
CubitVector ¢er,
CubitVector axes[3],
CubitVector &extension );
- // Finds the minimum size bounding box that fits around the points. Box
- // will not necessarily be oriented in xyz directions.
+ //@}
+
+ //@{
+ //! Finds the start and end of a cylinder that just intersects the input
+ //! box (defined by bottom-left and top-right corners, axis aligned with
+ //! the cubit coordinate system). The resultant cylinder's start and end
+ //! points can be extended out by a percentage of cylinder's length or
+ //! absolute (making it longer in both directions).
+ //! extension_type - 0=none, 1=percentage, 2=absolute
+ //! The num_tess_pnts is the number of line points along the circle the
+ //! function projects to the box to calculate the minimum intersection
+ //! (more points could give a more accurate result for non-axis aligned
+ //! cylinders).
CubitStatus min_cyl_box_int( double radius, CubitVector& axis, CubitVector& center,
CubitBox& box,
int extension_type, double extension,
@@ -791,39 +912,32 @@
int extension_type, double extension,
double start[3], double end[3],
int num_tess_pnts = 2048 );
- // Finds the start and end of a cylinder that just intersects the input
- // box (defined by bottom-left and top-right corners, axis aligned with
- // the cubit coordinate system). The resultant cylinder's start and end
- // points can be extended out by a percentage of cylinder's length or
- // absolute (making it longer in both directions).
- // extension_type - 0=none, 1=percentage, 2=absolute
- // The num_tess_pnts is the number of line points along the circle the
- // function projects to the box to calculate the minimum intersection
- // (more points could give a more accurate result for non-axis aligned
- // cylinders).
+ //@}
- double MinTriangleTriangle (Triangle3& tri0, Triangle3& tri1, double& s, double& t, double& u, double& v);
- // Finds minimum distance between two triangles in 3D (MAGIC)
+ //! Finds minimum distance between two triangles in 3D (MAGIC)
+ double MinTriangleTriangle (Triangle3& tri0,
+ Triangle3& tri1,
+ double& s, double& t, double& u, double& v);
+ //! Finds area of intersection between two triangles (MAGIC)
double AreaIntersection (Triangle &tri1, Triangle &tri2 );
- // Finds area of intersection between two triangles (MAGIC)
+ //! Finds angle between normals of the two triangles (radians)
double Angle( Triangle3& tri1, Triangle3& tri2 );
- // Finds angle between normals of the two triangles (radians)
+ //! Finds minimum distance beween a triange and point in 3D (MAGIC)
double MinPointTriangle (const Point3& p, const Triangle3& tri, double& s, double& t);
- // Finds minimum distance beween a triange and point in 3D (MAGIC)
#ifdef BOYD14
void Center( Triangle3& tri, double center[3] );
// Finds center position of given triangle
#endif
+ //! Finds normal vector of given triangle
void Normal( Triangle3& tri, double normal[3] );
- // Finds normal vector of given triangle
- double ProjectedOverlap( Triangle3& tri1, Triangle3& tri2 );
- // Projects tri2 to the plane of tri1 and finds the overlap area
+ //! Projects tri2 to the plane of tri1 and finds the overlap area
+ double ProjectedOverlap( Triangle3& tri1, Triangle3& tri2, bool draw_overlap = false );
protected:
AnalyticGeometryTool();
Added: cgm/branches/cubit/geom/AutoMidsurfaceTool.cpp
===================================================================
--- cgm/branches/cubit/geom/AutoMidsurfaceTool.cpp (rev 0)
+++ cgm/branches/cubit/geom/AutoMidsurfaceTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,908 @@
+//-------------------------------------------------------------------------
+// Filename : AutoMidsurfaceTool.cpp
+//
+// Purpose :
+// Create a midsurface of a body/volume given a thickness range. If no thickness range is given
+// then make a educated guess at the thickness (using something like Volume/Surface Area).
+//
+// Create Midsurface Volume <id_list> auto [<min_thickness> <max_thickness>]
+//
+// Creator : Sam Showman
+//
+// Creation Date : 05/10/2008
+//-------------------------------------------------------------------------
+#include "AutoMidsurfaceTool.hpp"
+#include "GeometryModifyEngine.hpp"
+#include "GeometryQueryTool.hpp"
+#include "BodySM.hpp"
+#include "Body.hpp"
+#include "GeometryModifyTool.hpp"
+#include "RefFace.hpp"
+#include "Surface.hpp"
+#include "Curve.hpp"
+#include "RefEntity.hpp"
+#include "SurfaceOverlapTool.hpp"
+#include "CubitPlane.hpp"
+#include "GfxPreview.hpp"
+#include "GfxDebug.hpp"
+#include "RefVertex.hpp"
+#include "ProgressTool.hpp"
+#include "AppUtil.hpp"
+#include "BoundingBoxTool.hpp"
+#include "GeomMeasureTool.hpp"
+
+// Constructor - nothing going on here
+AutoMidsurfaceTool::AutoMidsurfaceTool()
+{
+}
+
+// The main midsurface function
+// lower_tol, upper_tol and preview are optional
+CubitStatus AutoMidsurfaceTool::midsurface(
+ DLIList<Body*> &body_list_in,
+ DLIList<BodySM*> &body_list_out,
+ DLIList<Body*> &old_bodies_midsurfaced,
+ DLIList<double> &thickness_out,
+ double lower_limit,
+ double upper_limit,
+ CubitBoolean delete_midsurfaced,
+ CubitBoolean preview)
+{
+ if(lower_limit == CUBIT_DBL_MAX)// no limit set
+ lower_limit = -CUBIT_DBL_MAX;
+ double lower_tol = CUBIT_DBL_MAX;
+ double upper_tol = CUBIT_DBL_MAX;
+ const double auto_thickness_margin = 0.05; // if the user wants to automatically find the search
+ // thickness then this var give the search margin around the
+ // guess
+ ProgressTool* prog_tool = 0;
+ if(body_list_in.size()>5)
+ prog_tool = AppUtil::instance()->progress_tool();
+
+ // At lease one body must be provided
+ if(body_list_in.size() < 1)
+ {
+ PRINT_ERROR( "No bodies given for midsurfacing\n" );
+ return CUBIT_FAILURE;
+ }
+
+ // The surfaceOverlapTool is persistent so we need to save the
+ // max_gap and such to restore them at the end or if we error out
+ // save current settings
+ double max_gap_save = SurfaceOverlapTool::instance()->get_gap_max();
+ double min_gap_save = SurfaceOverlapTool::instance()->get_gap_min();
+ int normal_type = SurfaceOverlapTool::instance()->get_normal_type();
+ CubitBoolean cubit_bool_save = SurfaceOverlapTool::instance()->get_check_within_bodies();
+ CubitBoolean skip_facing_surfaces = SurfaceOverlapTool::instance()->get_skip_facing_surfaces();
+
+ // we want to only find overlap within a body
+ SurfaceOverlapTool::instance()->set_check_within_bodies(CUBIT_TRUE);
+ // 1=any, 2=opposite, 3=same - we want to find only the overlaps that normals
+ // pointing in the opposite directions
+ SurfaceOverlapTool::instance()->set_normal_type(2);
+ // Don't pickup surfaces that face each other
+ SurfaceOverlapTool::instance()->set_skip_facing_surfaces(CUBIT_TRUE);
+
+ // list of bodies that fail to midsurface
+ DLIList<Body*> failing_bodies;
+
+ GeometryModifyEngine* gme = 0;
+ GeometryQueryEngine* gqe = 0;
+
+ // loop over every body and try to create midsurface(s)
+ int i = 0;
+ CubitStatus return_status = CUBIT_FAILURE;
+
+ if(prog_tool)
+ prog_tool->start(0,body_list_in.size());
+
+ for(i = body_list_in.size();i--;)
+ {
+ if(prog_tool)
+ prog_tool->step();
+
+ Body* cur_body = body_list_in[i];
+ if(!cur_body)
+ continue;
+
+ BodySM* body_sm = cur_body->get_body_sm_ptr();
+ if(!body_sm)
+ continue;
+
+ if(cur_body->is_sheet_body())
+ {
+ PRINT_INFO("Body %d is a sheet body.\n",cur_body->id());
+ continue;
+ }
+
+ // Grab the geometrymodify and geometryquery engines to use later
+ gqe = cur_body->get_geometry_query_engine();
+ gme = GeometryModifyTool::instance()->get_engine(body_sm);
+
+ if(!gqe || !gme)
+ continue;
+
+ // Here are the steps to finding/creating the midsurface
+ // 1. If the user did not give a thickness range to search then
+ // make an educated guess at the proper thickness range. The assumption
+ // is that the midsurface is a square and the thickness is constant.
+ // The resulting equation is a third order polynomial that is solved using
+ // a few newton iterations. The initial thickness guess is Volume/Area
+ // 2. Using the given search distances use the SurfaceOverlapTool to find
+ // surface pairs.
+ // 3. If there is only one surface pair then use the existing midsurface commands
+ // 4. Find if the surface pairs represent two surface patches
+ // 5. If there are only two surface patches try to offset one of the patches
+ // 6. (this step is commented out for now) - If 5 fails or there are more than
+ // two surface patches then try the following:
+ // - Use the manual midsurface creation function to create midsurfaces for each
+ // pair of surfaces.
+ // - Unite all of the created midsurfaces together
+ // - remove any surfaces that have a curve touching a surface pair
+ // - Regularize the resulting body
+ // 7. Done
+
+ {
+ PRINT_DEBUG_198("AUTOMATICALLY calculating search range\n");
+ DLIList<RefVolume*> vol_list;
+ cur_body->ref_volumes(vol_list);
+ double total_vol = 0;
+ double total_vol_bb = 0;
+ for(int vol_cnt = 0; vol_cnt < vol_list.size(); vol_cnt++)
+ {
+ CubitVector cg;
+ double temp_volume;
+ vol_list[vol_cnt]->mass_properties(cg,temp_volume);
+ CubitBox vol_bb = vol_list[vol_cnt]->bounding_box();
+ total_vol += temp_volume;
+ total_vol_bb += vol_bb.x_range()*vol_bb.y_range()*vol_bb.z_range();
+ }
+
+ if(total_vol<0 || total_vol > total_vol_bb)
+ {
+ PRINT_INFO("Could not midsurface Body %d - try healing the body.\n",cur_body->id());
+ failing_bodies.append(cur_body);
+ continue;
+ }
+
+ PRINT_DEBUG_198("Volume of %f\n",total_vol);
+
+ DLIList<RefFace*> face_list;
+ cur_body->ref_faces(face_list);
+ double total_surf = 0;
+ for(int surf_cnt = 0; surf_cnt < face_list.size(); surf_cnt++)
+ total_surf += face_list[surf_cnt]->area();
+ PRINT_DEBUG_198("Area of %f\n",total_surf);
+
+ double t_g = total_vol/(total_surf/2.0);
+ double initial_guess = t_g;
+ PRINT_DEBUG_198("Initial guess of thickness %f\n",t_g);
+ // use a newton solver to get a more accurate estimate the thickness of the volume
+ for(int n_i = 0;n_i<100;n_i++)
+ {
+ double tol_newton = GEOMETRY_RESABS;
+ double t_gn = t_g + tol_newton;
+ double f_prime = ((2.0*total_vol + sqrt(total_vol*t_g*t_g*t_g)*4.0 - total_surf*t_g)
+ -(2.0*total_vol + sqrt(total_vol*t_gn*t_gn*t_gn)*4.0 - total_surf*t_gn))/
+ (t_g-t_gn);
+
+ // avoid divide by zero
+ if(fabs(f_prime)<tol_newton)
+ break;
+
+ double t_old = t_g;
+ t_g = t_g - (2.0*total_vol + sqrt(total_vol*t_g*t_g*t_g)*4.0 - total_surf*t_g)/f_prime;
+
+ PRINT_DEBUG_198("Guess %d Thickness %f\n",n_i,t_g);
+ if(fabs(t_g-t_old)<tol_newton)
+ {
+ PRINT_DEBUG_198("Converged with thickness of %f in %d steps\n",t_g,n_i);
+ break;
+ }
+ if(t_g<0.0)
+ {
+ PRINT_DEBUG_198("thickness less than zero setting back to initial guess\n");
+ t_g = fabs(initial_guess);
+ break;
+ }
+ }
+ upper_tol = t_g + t_g*auto_thickness_margin;
+ lower_tol = t_g - t_g*auto_thickness_margin;
+ upper_tol = upper_tol <= upper_limit?upper_tol:upper_limit;
+ lower_tol = lower_tol >= lower_limit?lower_tol:lower_limit;
+
+ PRINT_DEBUG_198("Guessing a thickness of %f to %f\n",lower_tol,upper_tol);
+ }
+
+ // set the lower and upper search distances
+ SurfaceOverlapTool::instance()->set_gap_max(upper_tol);
+ SurfaceOverlapTool::instance()->set_gap_min(lower_tol);
+
+ DLIList<RefFace*> ref_face_list,list1,list2;
+ DLIList<RefEntity*> faces_to_draw;
+ cur_body->ref_faces(ref_face_list);
+ // find the surface pairs
+ SurfaceOverlapTool::instance()->find_overlapping_surfaces(ref_face_list,list1,list2,faces_to_draw);
+
+ int tweak_iters = 4;
+ for(int tweak = 0;tweak<tweak_iters;tweak++)
+ {
+ // if we didn't find anything then the part may be long and selender so grow the search thickness
+ if(list1.size()==0 && list2.size() == 0)
+ {
+ if(tweak == tweak_iters-1 && lower_limit != -CUBIT_DBL_MAX && upper_limit != CUBIT_DBL_MAX)
+ {
+ // on the last try use the user defined limits
+ lower_tol = lower_limit;
+ upper_tol = upper_limit;
+ }
+ else
+ {
+ lower_tol = (upper_tol + lower_tol)/2.0;
+ upper_tol += lower_tol*auto_thickness_margin*2;
+ upper_tol = upper_tol <= upper_limit?upper_tol:upper_limit;
+ lower_tol = lower_tol >= lower_limit?lower_tol:lower_limit;
+ }
+
+ PRINT_DEBUG_198("Guessing again with thickness of %f to %f\n",lower_tol,upper_tol);
+ SurfaceOverlapTool::instance()->set_gap_max(upper_tol);
+ SurfaceOverlapTool::instance()->set_gap_min(lower_tol);
+ SurfaceOverlapTool::instance()->find_overlapping_surfaces(ref_face_list,list1,list2,faces_to_draw);
+ }
+
+ DLIList<RefFace*> check_list;
+ check_list += list1;
+ check_list += list2;
+
+ if(check_list.size() == 0 )
+ continue;
+
+ // make sure the pairs will match the solid within 10% or so
+ if(!check_surf_pairs(lower_tol,upper_tol,check_list,cur_body))
+ {
+ list1.clean_out();
+ list2.clean_out();
+ continue;
+ }
+ break;
+ }
+
+ if(list1.size() != list2.size())
+ {
+ PRINT_INFO("Could not find workable surface pairs for Body %d - try using the Sheet Offset command. \n",cur_body->id());
+ failing_bodies.append(cur_body);
+ continue;
+ }
+ else if(list1.size() == 0 || list2.size() == 0)
+ {
+ PRINT_INFO("No surface pairs found for Body %d - try changing the search range\n",cur_body->id());
+ failing_bodies.append(cur_body);
+ continue;
+ }
+
+ // get the first pair and see if there are only two patches
+ DLIList<RefFace*> red_faces;
+ red_faces.append(list1[0]);
+ DLIList<RefFace*> yellow_faces;
+ yellow_faces.append(list2[0]);
+ DLIList<RefFace*> paired_faces;
+ paired_faces += list1;
+ paired_faces += list2;
+ paired_faces.uniquify_unordered();
+
+ // red surfaces
+ while(1)
+ {
+ int start_cnt = red_faces.size();
+ DLIList<RefEdge*> red_edges;
+ int j = 0;
+ for(j =0;j<red_faces.size();j++)
+ red_faces[j]->ref_edges(red_edges);
+ red_edges.uniquify_unordered();
+ for(j =0;j<red_edges.size();j++)
+ red_edges[j]->ref_faces(red_faces);
+ red_faces.uniquify_unordered();
+ red_faces.intersect_unordered(paired_faces);
+ if(start_cnt == red_faces.size())
+ break;
+ }
+
+ // yellow surfaces
+ while(1)
+ {
+ int start_cnt = yellow_faces.size();
+ DLIList<RefEdge*> yellow_edges;
+ int j = 0;
+ for(j =0;j<yellow_faces.size();j++)
+ yellow_faces[j]->ref_edges(yellow_edges);
+ yellow_edges.uniquify_unordered();
+ for(j =0;j<yellow_edges.size();j++)
+ yellow_edges[j]->ref_faces(yellow_faces);
+ yellow_faces.uniquify_unordered();
+ yellow_faces.intersect_unordered(paired_faces);
+ if(start_cnt == yellow_faces.size())
+ break;
+ }
+
+ DLIList<BodySM*> results;
+ bool midsurface_done = false;
+
+ if(DEBUG_FLAG(198))
+ {
+ int j = 0;
+ PRINT_INFO("Trying surface offset to create the mid_surface\n");
+ PRINT_INFO("Red surface ");
+ for(j = 0;j < red_faces.size();j++)
+ {
+ GfxDebug::draw_ref_face(red_faces[j],CUBIT_RED);
+ PRINT_INFO("%d ",red_faces[j]->id());
+ }
+
+ PRINT_INFO("\nYellow surface ");
+ for(j = 0;j < yellow_faces.size();j++)
+ {
+ GfxDebug::draw_ref_face(yellow_faces[j],CUBIT_YELLOW);
+ PRINT_INFO("%d ",yellow_faces[j]->id());
+ }
+
+ PRINT_INFO("\n");
+ }
+
+ // first check to see if we can use the simple midsurface functions
+ if(red_faces.size() == 1 && yellow_faces.size() == 1 &&
+ paired_faces.size() == red_faces.size() + yellow_faces.size())
+ {
+ RefFace* face_1 = red_faces[0];
+ RefFace* face_2 = yellow_faces[0];
+ midsurface_done = false;
+
+ if(face_1->geometry_type() == face_2->geometry_type())
+ {
+ Surface* surf_1 = face_1->get_surface_ptr();
+ Surface* surf_2 = face_2->get_surface_ptr();
+ BodySM* result_body;
+ // grab the distance between surfaces
+ CubitVector temp_vec0;
+ CubitVector temp_vec1;
+ double temp_dist = 0;
+ gqe->entity_entity_distance(
+ face_1->get_surface_ptr(),
+ face_2->get_surface_ptr(),
+ temp_vec0,temp_vec1,temp_dist);
+
+ switch(face_1->geometry_type())
+ {
+ case CONE_SURFACE_TYPE:
+ if(gme->get_conic_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
+ {
+ midsurface_done = true;
+ results.append(result_body);
+ thickness_out.append(fabs(temp_dist));
+ }
+ break;
+ case PLANE_SURFACE_TYPE:
+ if(get_planar_mid_surface(face_1,face_2,body_sm,result_body,gme) == CUBIT_SUCCESS)
+ {
+ midsurface_done = true;
+ results.append(result_body);
+ thickness_out.append(fabs(temp_dist));
+ }
+ break;
+ case SPHERE_SURFACE_TYPE:
+ if(gme->get_spheric_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
+ {
+ midsurface_done = true;
+ results.append(result_body);
+ thickness_out.append(fabs(temp_dist));
+ }
+ break;
+ case TORUS_SURFACE_TYPE:
+ if(gme->get_toric_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
+ {
+ midsurface_done = true;
+ results.append(result_body);
+ thickness_out.append(fabs(temp_dist));
+ }
+ break;
+ case CYLINDER_SURFACE_TYPE:
+ if(gme->get_conic_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
+ {
+ midsurface_done = true;
+ results.append(result_body);
+ thickness_out.append(fabs(temp_dist));
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if(!midsurface_done &&
+ paired_faces.size() == red_faces.size() + yellow_faces.size()) // just do the offset
+ {
+ int j = 0;
+ DLIList<double> offset_distances;
+ for(j = 0;j<list1.size();j++)
+ {
+ CubitVector temp_vec0;
+ CubitVector temp_vec1;
+ double temp_dist = 0;
+ if(!gqe->entity_entity_distance(
+ list1[j]->get_surface_ptr(),
+ list2[j]->get_surface_ptr(),
+ temp_vec0,temp_vec1,temp_dist))
+ {
+ break;
+ }
+ offset_distances.append(-temp_dist*.5);
+ }
+
+ DLIList<Surface*> red_surfs;
+ for(j = 0;j<red_faces.size();j++)
+ red_surfs.append(red_faces[j]->get_surface_ptr());
+
+ DLIList<Surface*> yellow_surfs;
+ for(j = 0;j<yellow_faces.size();j++)
+ yellow_surfs.append(yellow_faces[j]->get_surface_ptr());
+
+ // all of the surfaces are offset the same distance
+ double offset_distance = offset_distances[0];
+ bool old_error_flag = GET_ERROR_FLAG();
+ SET_ERROR_FLAG(false); // don't throw any gme errors
+ if( gme->create_offset_sheet(red_surfs,offset_distance,
+ NULL,NULL,results))
+ {
+ midsurface_done = true;
+ for(j = 0;j<results.size();j++) // for every body add a thickness
+ thickness_out.append(fabs(offset_distance*2.));
+ }
+ else if( gme->create_offset_sheet(yellow_surfs,offset_distance,
+ NULL,NULL,results)) // try the other direction
+ {
+ midsurface_done = true;
+ for(j = 0;j<results.size();j++) // for every body add a thickness
+ thickness_out.append(fabs(offset_distance*2.));
+ }
+ else
+ {
+ PRINT_INFO("Could not create midsurface for Body %d - try using the surface offset command\n",cur_body->id());
+ failing_bodies.append(cur_body);
+ }
+ SET_ERROR_FLAG(old_error_flag); // turn errors back on
+ }
+
+ if(!midsurface_done && paired_faces.size() != red_faces.size() + yellow_faces.size())
+ {
+ PRINT_INFO("Could not find workable surface pairs for Body %d - try changing the search range or \n"
+ " using the Sheet Offset command.\n",cur_body->id());
+ }
+
+ /*if(!midsurface_done)
+ {
+ if(DEBUG_FLAG(198))
+ PRINT_INFO("Trying the extend, unite, and trim method\n");
+
+ // okay now remove duplicate pairs and unsupported pairs
+ DLIList<Surface*> surf_list1;
+ DLIList<Surface*> surf_list2;
+ bool delete_and_exit = false;
+ for(int j = 0;j<list1.size();j++)
+ {
+ RefFace* face_1 = list1[j];
+ RefFace* face_2 = list2[j];
+
+ if(DEBUG_FLAG(198))
+ {
+ PRINT_INFO("Red surface ");
+ GfxDebug::draw_ref_face(face_1,CUBIT_RED);
+ PRINT_INFO("%d ",face_1->id());
+
+ PRINT_INFO("\nYellow surface ");
+ GfxDebug::draw_ref_face(face_2,CUBIT_YELLOW);
+ PRINT_INFO("%d ",face_2->id());
+
+ PRINT_INFO("\n");
+ }
+
+ if(face_1->geometry_type() != face_2->geometry_type())
+ continue;
+
+ Surface* surf_1 = face_1->get_surface_ptr();
+ surf_list1.append(surf_1);
+ Surface* surf_2 = face_2->get_surface_ptr();
+ surf_list2.append(surf_2);
+ BodySM* result_body;
+ switch(face_1->geometry_type())
+ {
+ case CONE_SURFACE_TYPE:
+ if(gme->get_conic_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
+ results.append(result_body);
+ else
+ delete_and_exit = true;
+ break;
+ case PLANE_SURFACE_TYPE:
+ if(get_planar_mid_surface(face_1,face_2,body_sm,result_body,gme) == CUBIT_SUCCESS)
+ results.append(result_body);
+ else
+ delete_and_exit = true;
+ break;
+ case SPHERE_SURFACE_TYPE:
+ if(gme->get_spheric_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
+ results.append(result_body);
+ else
+ delete_and_exit = true;
+ break;
+ case TORUS_SURFACE_TYPE:
+ if(gme->get_toric_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
+ results.append(result_body);
+ else
+ delete_and_exit = true;
+ break;
+ case CYLINDER_SURFACE_TYPE:
+ if(gme->get_conic_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
+ results.append(result_body);
+ else
+ delete_and_exit = true;
+ break;
+ default:
+ delete_and_exit = true;
+ break;
+ }
+
+ if(delete_and_exit)
+ {
+ PRINT_WARNING("Failed to pair surface %d with surface %d\n",face_1->id(),face_2->id());
+ break;
+ }
+ }
+
+ if(delete_and_exit)
+ {
+ failing_bodies.append(cur_body);
+ gqe->delete_solid_model_entities(results);
+ continue;
+ }
+
+ DLIList<BodySM*> unite_results;
+ if(results.size()>1)
+ {
+ bool reg_result = GeometryModifyTool::instance()->boolean_regularize();
+ GeometryModifyTool::instance()->boolean_regularize(true);
+ if(gme->unite(results,unite_results)== CUBIT_SUCCESS)
+ {
+ // if the unite works just add them to the result list
+ results = unite_results;
+ }
+ else
+ {
+ // clean up the created surfaces and move on to the next
+ // body
+ failing_bodies.append(cur_body);
+ gqe->delete_solid_model_entities(results);
+ GeometryModifyTool::instance()->boolean_regularize(reg_result);
+ continue;
+ }
+
+ GeometryModifyTool::instance()->boolean_regularize(reg_result);
+ }
+
+ // trim the hanging surfaces
+ DLIList<Surface*> paired_surfs;
+ paired_surfs += surf_list1;
+ paired_surfs += surf_list2;
+
+ DLIList<Curve*> all_curves;
+
+ int k = 0;
+ for(k = 0;k<results.size();k++)
+ results[k]->curves(all_curves);
+
+ all_curves.uniquify_unordered();
+
+ DLIList<Surface*> remove_surfs;
+ for(k = 0;k<all_curves.size();k++)
+ for(int m = 0;m<paired_surfs.size();m++)
+ if(curve_in_surface(all_curves[k],paired_surfs[m]))
+ all_curves[k]->surfaces(remove_surfs);
+
+ remove_surfs.uniquify_unordered();
+
+ body_list_out += results;
+ DLIList<BodySM*> tweak_results;
+ if(gme->tweak_remove(remove_surfs,tweak_results,CUBIT_FALSE))
+ {
+ results = tweak_results;
+ }
+ else
+ {
+ // clean up the created surfaces and move on to the next
+ // body
+ failing_bodies.append(cur_body);
+ gqe->delete_solid_model_entities(results);
+ continue;
+ }
+
+ DLIList<BodySM*> regularize_results;
+ // regularize the results
+ for(k = 0;k < results.size();k++)
+ {
+ BodySM* new_body = 0;
+ if(gme->regularize_body(results[k],new_body))
+ regularize_results.append(new_body);
+ else if(DEBUG_FLAG(198))
+ PRINT_INFO("Regularize failure\n");
+ }
+ results = regularize_results;
+ }*/
+
+ if(!midsurface_done)
+ {
+ failing_bodies.append(cur_body);
+ continue;
+ }
+
+ old_bodies_midsurfaced.append(cur_body);
+
+ if(delete_midsurfaced && !preview)
+ GeometryQueryTool::instance()->delete_Body(cur_body);
+
+ return_status = CUBIT_SUCCESS;
+ body_list_out += results;
+ }
+
+ if(prog_tool)
+ prog_tool->end();
+
+ PRINT_INFO("Successfully midsurface %d of %d bodies\n",body_list_out.size(),body_list_in.size());
+ if(preview)
+ {
+ for(int k = 0;k<body_list_out.size();k++)
+ {
+ DLIList<Surface*> preview_surfaces;
+ body_list_out[k]->surfaces(preview_surfaces);
+ for(int p = 0;p<preview_surfaces.size();p++)
+ GfxPreview::draw_surface_facets_shaded(preview_surfaces[p],CUBIT_BLUE);
+ }
+ GfxPreview::flush();
+ if(gqe)
+ gqe->delete_solid_model_entities(body_list_out);
+ body_list_out.clean_out();
+ }
+
+ if(failing_bodies.size() > 0)
+ {
+ PRINT_INFO("\n");
+ PRINT_INFO("Failed to midsurface Body ");
+ for(i = 0;i<failing_bodies.size();i++)
+ PRINT_INFO("%d ",failing_bodies[i]->id());
+ PRINT_INFO("\n");
+ }
+
+ if(DEBUG_FLAG(198))
+ GfxDebug::flush();
+
+ SurfaceOverlapTool::instance()->set_check_within_bodies(cubit_bool_save);
+ SurfaceOverlapTool::instance()->set_gap_max(max_gap_save);
+ SurfaceOverlapTool::instance()->set_normal_type(normal_type);
+ SurfaceOverlapTool::instance()->set_gap_min(min_gap_save);
+ SurfaceOverlapTool::instance()->set_skip_facing_surfaces(skip_facing_surfaces);
+
+ return return_status;
+}
+
+
+CubitStatus AutoMidsurfaceTool::get_planar_mid_surface( RefFace* ref_face1,
+ RefFace* ref_face2,
+ BodySM* body_sm_to_trim_to,
+ BodySM*& midsurface_body_sm,
+ GeometryModifyEngine *gme_ptr )
+{
+ CubitVector normal_1, normal_2, point_1, point_2, point_3;
+ CubitPlane plane_1, plane_2;
+ CubitVector p_mid, n_mid;
+
+ point_1 = ref_face1->center_point();
+ point_2 = ref_face2->center_point();
+
+ normal_1 = ref_face1->normal_at(point_1);
+ normal_2 = ref_face2->normal_at(point_2);
+
+ plane_1 = CubitPlane(normal_1,point_1);
+ plane_2 = CubitPlane(normal_2,point_2);
+
+ if(point_1 == point_2)
+ {
+ PRINT_ERROR( "In GeometryModifyTool:: get_planar_mid_surface\n"
+ " Since both surfaces share the same point, the midsurface is not well-defined\n");
+ return CUBIT_FAILURE;
+ }
+ else
+ {
+ CubitVector temp1 = point_2;
+ temp1 = plane_1.project(temp1);
+ temp1 -= point_2;
+ if ( temp1.length_squared() < GEOMETRY_RESABS*GEOMETRY_RESABS )
+ {
+ PRINT_ERROR("In GeometryModifyTool:: get_planar_mid_surface\n"
+ " Since both planes are the same, the midsurface is not well-defined.\n");
+ return CUBIT_FAILURE;
+ }
+ }
+
+ if ( ( normal_1.about_equal( normal_2 ) ) || ( (-normal_1).about_equal( normal_2 ) ) )
+ {
+ p_mid = (point_1+point_2)/2;
+ n_mid = plane_1.normal();
+ }
+ else
+ {
+ CubitVector direction_of_line;
+ plane_1.intersect(plane_2,p_mid,direction_of_line);
+ direction_of_line.normalize();
+
+ // Find if point_1 and point_2 are on the line of intersection
+ // If they are, then the mid-plane is not well-defined
+ CubitVector p1 = point_1-p_mid;
+ CubitVector p2 = point_2-p_mid;
+ p1.normalize();
+ p2.normalize();
+
+ if(p1==direction_of_line || p1==-direction_of_line)
+ {
+ PRINT_ERROR("In GeometryModifyTool:: get_planar_mid_surface\n"
+ " P1 is on the line of intersection.\n");
+ return CUBIT_FAILURE;
+ }
+
+ if(p2==direction_of_line || p2==-direction_of_line)
+ {
+ PRINT_ERROR("In GeometryModifyTool:: get_planar_mid_surface\n"
+ " P2 is on the line of intersection.\n");
+ return CUBIT_FAILURE;
+ }
+
+ CubitVector v1 = p1 - (p1%direction_of_line)*direction_of_line;
+ v1.normalize();
+
+ CubitVector v2 = p2 - (p2%direction_of_line)*direction_of_line;
+ v2.normalize();
+
+ n_mid = v1 - v2;
+ n_mid.normalize();
+ }
+
+ CubitPlane mid_plane(n_mid, p_mid);
+ point_1 = p_mid;
+
+ //find three points that will define the infinite plane from the
+ //mid plane.through the point in any direction just not along the
+ //normal direction
+ CubitVector Xdir(1,0,0), Ydir(0,1,0);
+ CubitVector direction1;
+
+ if ( ( ! n_mid.about_equal( Xdir ) ) && ( ! (-n_mid).about_equal( Xdir ) ) )
+ direction1 = Xdir + n_mid;
+ else
+ direction1 = Ydir + n_mid;
+
+ point_2 = p_mid + direction1;
+ point_2 = mid_plane.project(point_2);
+
+ direction1 = point_2-point_1;
+ CubitVector direction2 = direction1*n_mid;
+ point_3 = point_1 + direction2;
+
+ CubitStatus ret = gme_ptr->get_mid_plane(point_1, point_2, point_3,
+ body_sm_to_trim_to, midsurface_body_sm );
+ return ret;
+}
+
+CubitBoolean AutoMidsurfaceTool::curve_in_surface(Curve *curve_in, Surface *surf_in)
+{
+ CubitVector loc_0;
+ CubitVector loc_1;
+ CubitVector loc_2;
+
+ curve_in->position_from_fraction(0.1,loc_0);
+ curve_in->position_from_fraction(0.5,loc_1);
+ curve_in->position_from_fraction(0.9,loc_2);
+
+ GeometryQueryEngine* gqe = surf_in->get_geometry_query_engine();
+ double tol = gqe->get_sme_resabs_tolerance();
+ CubitVector cl_pnt_0;
+ CubitVector cl_pnt_1;
+ CubitVector cl_pnt_2;
+ surf_in->closest_point(loc_0,&cl_pnt_0);
+ surf_in->closest_point(loc_1,&cl_pnt_1);
+ surf_in->closest_point(loc_2,&cl_pnt_2);
+
+ if(cl_pnt_0.distance_between(loc_0)<tol &&
+ cl_pnt_1.distance_between(loc_1)<tol &&
+ cl_pnt_2.distance_between(loc_2)<tol)
+ {
+ return CUBIT_TRUE;
+ }
+
+ return CUBIT_FALSE;
+}
+
+CubitStatus AutoMidsurfaceTool::find_offset_pair_patches(
+ DLIList<RefFace*> pairs_list_0,
+ DLIList<RefFace*> pairs_list_1,
+ DLIList<RefFace*>& red_faces,
+ DLIList<RefFace*>& yellow_faces,
+ DLIList<double>& offset_distances)
+{
+ return CUBIT_FAILURE;
+}
+
+CubitStatus AutoMidsurfaceTool::random_loc_on_surface( Surface* face_ptr, CubitVector &loc )
+{
+ GMem g_mem;
+ GeometryQueryEngine* gqe = face_ptr->get_geometry_query_engine();
+ unsigned short norm_tol = 10;
+ double dist_tol = -1.0;
+ gqe->get_graphics( face_ptr, &g_mem, norm_tol, dist_tol );
+
+ if(g_mem.fListCount < 1)
+ {
+ // Decrease tolerance and try again (we can get this for small features)
+ norm_tol /= 2;
+ gqe->get_graphics( face_ptr, &g_mem, norm_tol, dist_tol);
+ }
+
+ if(g_mem.fListCount < 1)
+ {
+ // Lets give up
+ PRINT_ERROR( "Unable to find location on a surface\n" );
+ return CUBIT_FAILURE;
+ }
+
+ // Use the first triangle
+ GPoint p[3];
+ GPoint* plist = g_mem.point_list();
+ int* facet_list = g_mem.facet_list();
+ int c = 0;
+
+ p[0] = plist[facet_list[++c]];
+ p[2] = plist[facet_list[++c]];
+ p[1] = plist[facet_list[++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;
+
+ face_ptr->closest_point_trimmed(center,loc);
+
+ return CUBIT_SUCCESS;
+}
+
+CubitBoolean AutoMidsurfaceTool::check_surf_pairs(double min_thick, double max_thick,
+ DLIList<RefFace*> check_list, Body* body_in )
+{
+ double total_area = 0.0;
+ DLIList<RefVolume*> vol_list;
+ body_in->ref_volumes(vol_list);
+ double total_vol = 0;
+ for(int vol_cnt = 0; vol_cnt < vol_list.size(); vol_cnt++)
+ {
+ CubitVector cg;
+ double temp_volume;
+ vol_list[vol_cnt]->mass_properties(cg,temp_volume);
+ total_vol += temp_volume;
+ }
+
+ for(int i = 0;i<check_list.size();i++)
+ total_area += check_list[i]->area();
+
+ total_area/=2.0;
+
+ if(min_thick*total_area < total_vol && max_thick*total_area > total_vol)
+ return CUBIT_TRUE;
+
+ return CUBIT_FALSE;
+}
Added: cgm/branches/cubit/geom/AutoMidsurfaceTool.hpp
===================================================================
--- cgm/branches/cubit/geom/AutoMidsurfaceTool.hpp (rev 0)
+++ cgm/branches/cubit/geom/AutoMidsurfaceTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,79 @@
+//-------------------------------------------------------------------------
+// Filename : AutoMidsurfaceTool.cpp
+//
+// Purpose :
+// Create a midsurface of a body/volume given a thickness range. If no thickness range is given
+// then make a educated guess at the thickness (using something like Volume/Surface Area).
+//
+// Create Midsurface Volume <id_list> auto [<lower_tol> <upper_tol>]
+//
+// Creator : Sam Showman
+//
+// Creation Date : 05/10/2008
+//-------------------------------------------------------------------------
+#ifndef AutoMidsurfaceTool_HPP
+#define AutoMidsurfaceTool_HPP
+
+#include "CubitDefines.h"
+#include "CubitVector.hpp"
+#include "CubitPlane.hpp"
+
+class GeometryModifyEngine;
+class Body;
+class RefFace;
+class BodySM;
+class Surface;
+class Curve;
+class RefEdge;
+template <class X> class DLIList;
+
+class AutoMidsurfaceTool
+{
+public:
+
+ AutoMidsurfaceTool();
+ ~AutoMidsurfaceTool(){}
+
+ CubitStatus midsurface(
+ DLIList<Body*> &body_list_in,
+ DLIList<BodySM*> &body_list_out,
+ DLIList<Body*> &old_bodies_midsurfaced,
+ DLIList<double> &thickness_out,
+ double lower_tol = CUBIT_DBL_MAX,
+ double upper_tol = CUBIT_DBL_MAX,
+ CubitBoolean delete_midsurfaced = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE);
+ //- automatically midsurfaces a volume based on surface pairs and surface area
+ //- body_list_in - list of bodies to midsurface
+ //- body_list_out - result bodies
+ //- lower_tol - lower tolerance
+ //- upper_tol - upper tolerance
+ //- delete_midsurfaced - delete the midsurfaced solid
+ //- transp_midsurfaced - make the midsurfaced solid transparent
+ //- preview - preview the results
+
+private:
+ CubitBoolean curve_in_surface(Curve *curve_in, Surface *surf_in);
+
+ CubitStatus get_planar_mid_surface(
+ RefFace* ref_face1,
+ RefFace* ref_face2,
+ BodySM* body_sm_to_trim_to,
+ BodySM*& midsurface_body_sm,
+ GeometryModifyEngine *gme_ptr );
+
+ CubitStatus find_offset_pair_patches(
+ DLIList<RefFace*> pairs_list_0,
+ DLIList<RefFace*> pairs_list_1,
+ DLIList<RefFace*>& red_faces,
+ DLIList<RefFace*>& yellow_faces,
+ DLIList<double>& offset_distances);
+
+ CubitStatus random_loc_on_surface( Surface* face_ptr, CubitVector &loc );
+
+ CubitBoolean check_surf_pairs(double min_thick, double max_thick,
+ DLIList<RefFace*> check_list, Body* body_in );
+};
+
+#endif
+
Modified: cgm/branches/cubit/geom/Body.cpp
===================================================================
--- cgm/branches/cubit/geom/Body.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Body.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -33,6 +33,7 @@
#include "GeometryQueryEngine.hpp"
#include "CastTo.hpp"
+
//-------------------------------------------------------------------------
// Purpose : Default constructor.
//
@@ -73,8 +74,6 @@
// Set the Entity ID for this new Body
entityId = RefEntityFactory::instance()->next_body_id();
- copied_from_body_id = 0;
-
// read and initialize attributes
auto_read_cubit_attrib();
auto_actuate_cubit_attrib();
@@ -112,73 +111,6 @@
return dynamic_cast<BodySM*>(bridge);
}
-//* Method: copiedFromId
-//** Sets the Id of the body that this body was copied from
-//*==
-
-void Body::copiedFromId( int Id )
-{
- copied_from_body_id = Id;
-}
-
-//* Method: copiedFromId
-//** Returns the Id of the body that this body was copied from
-//*==
-
-int Body::copiedFromId ()
-{
- return copied_from_body_id;
-}
-
-/* This is wrong for misc. arrangements of non-manifold topology
- * -- j.kraftcheck
-
-CubitBoolean Body::is_sheet_body()
-{
- //This function just checks for bodies which have a single coedge
- // on a RefEdge, which would indicate an open sheet body. This
- // function will not find sheet bodies which are closed...
- DLIList<CoEdge*> co_edges;
- this->co_edges( co_edges );
- DLIList<RefEdge*> edge_list_1, edge_list_2;
- int i;
- for( i = co_edges.size(); i > 0; i-- )
- {
- CoEdge* this_co_edge = co_edges.get_and_step();
- RefEdge* this_ref_edge = this_co_edge->get_ref_edge_ptr();
- if( edge_list_1.is_in_list( this_ref_edge ) )
- {
- edge_list_2.append( this_ref_edge );
- }
- else
- {
- edge_list_1.append_unique( this_ref_edge );
- }
- }
-
- //subtract edge_list_2 from edge_list_1
- DLIList<RefEdge*> temp_list = edge_list_1;
- for( i = temp_list.size(); i > 0; i-- )
- {
- RefEdge* this_edge = temp_list.get_and_step();
- if( edge_list_2.is_in_list( this_edge ) )
- {
- edge_list_1.remove( this_edge );
- }
- }
-
- if( edge_list_1.size() > 0 )
- {
- for( i = edge_list_1.size(); i > 0; i-- )
- {
- if( edge_list_1.get_and_step()->geometry_type() != POINT_CURVE_TYPE )
- return CUBIT_TRUE;
- }
- }
- return CUBIT_FALSE;
-}
- */
-
//-------------------------------------------------------------------------
// Purpose : Check if this body contains only sheet volumes.
//
Modified: cgm/branches/cubit/geom/Body.hpp
===================================================================
--- cgm/branches/cubit/geom/Body.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Body.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -30,6 +30,7 @@
class CubitTransformMatrix;
+//! Body class.
class CUBIT_GEOM_EXPORT Body : public GroupingEntity,
public RefEntity
{
@@ -45,36 +46,44 @@
/* topology */
+ //! Gets the dag type.
DagType dag_type() const { return DagType::body_type(); }
+
+ //! Gets the type info.
const type_info& entity_type_info() const { return typeid(Body); }
+ //! Gets the class name: "Body".
static const char* get_class_name()
{
return "Body";
}
+
+ //! Gets the class name: "Body".
virtual const char* class_name() const
{
return get_class_name();
}
+ //! Gets the underlying BodySM pointer.
BodySM* get_body_sm_ptr() const;
+ //! Returns the bounding box of this body
virtual CubitBox bounding_box();
- /*- Returns the bounding box of this body
- */
+ //! Return a CubitVector set to the centroid of this body
virtual CubitVector center_point();
- /*- Return a CubitVector set to the centroid of this body
- */
+ //! Get certain mass props, cofg is center of gravity
CubitBoolean get_mass_props(CubitVector& cofg);
- /* Get certain mass props, cofg is center of gravity */
+ //! Determines whether a point is inside, outside, or on boundary
+ //! of a volume.
CubitPointContainment point_containment( CubitVector &point );
- //- Determines whether a point is inside, outside, or on boundary
- //- of a volume.
+ //! Returns the volume of this body.
virtual double measure();
+
+ //! Query to see if this is a sheet body.
CubitBoolean is_sheet_body();
#ifdef BOYD14
@@ -100,20 +109,15 @@
*/
#endif
+ //! Do a measure and api entity check.
virtual int validate();
- /*- do a measure and api entity check.
- */
+ //! Functions related to "measuring" the Body
virtual CubitString measure_label();
- /*- Functions related to "measuring" the Body
- */
- void copiedFromId( int Id );
- int copiedFromId ();
- /*- Sets/Gets the id of the body that it was copied from */
-
-
+ //! Sets the color.
virtual void color(int value);
+ //! Gets the color.
virtual int color() const;
protected:
@@ -139,8 +143,6 @@
*/
#endif
- int copied_from_body_id;
-
Body( const Body& );
void operator=( const Body& );
Modified: cgm/branches/cubit/geom/BoundingBoxTool.cpp
===================================================================
--- cgm/branches/cubit/geom/BoundingBoxTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/BoundingBoxTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -219,9 +219,9 @@
num_tri = num_facet / 4;
GPoint* point_list = g_mem->point_list();
- int num_pnts = g_mem->point_list_size();
+ //int num_pnts = g_mem->point_list_size();
int y;
- for( y=0; y<num_pnts; y++ )
+ for( y=0; y<num_pnt; y++ )
{
CubitVector* cubit_vector_ptr = new CubitVector(
point_list[y].x, point_list[y].y, point_list[y].z );
Modified: cgm/branches/cubit/geom/BoundingBoxTool.hpp
===================================================================
--- cgm/branches/cubit/geom/BoundingBoxTool.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/BoundingBoxTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -13,28 +13,30 @@
class CubitVector;
class RefEntity;
+//! Class for bounding boxes (primarily for "tight" bounding boxes).
class CUBIT_GEOM_EXPORT BoundingBoxTool
{
public :
+ //! Gets tightest box around the given entity list, using facets.
+ //! Box is defined as center point, vector axes (unit vectors), and
+ //! extension in each axis (x extension is 1/2 width of box, for example).
static CubitStatus get_tight_bounding_box( DLIList<RefEntity*> &ref_entity_list,
CubitVector ¢er,
CubitVector axes[3],
CubitVector &extension,
double ang_facet_tol,
double abs_facet_tol);
- //- Gets tightest box around the given entity list, using facets.
- //- Box is defined as center point, vector axes (unit vectors), and
- //- extension in each axis (x extension is 1/2 width of box, for example).
+ //! Convenience function to get an axis box in the same output format as
+ //! a tight box.
static CubitStatus get_axis_bounding_box( DLIList<RefEntity*> &ref_entity_list,
CubitVector ¢er,
CubitVector axes[3],
CubitVector &extension );
- //- Convenience function to get an axis box in the same output format as
- //- a tight box.
+ //! Using the center, axes and extension, gets the 8 corners of the box.
static CubitStatus get_corner_points( CubitVector ¢er,
CubitVector axes[3],
CubitVector &extension,
@@ -42,45 +44,47 @@
CubitVector& p3, CubitVector& p4,
CubitVector& p5, CubitVector& p6,
CubitVector& p7, CubitVector& p8);
- //- Using the center, axes and extension, gets the 8 corners of the box.
+ //! If triangles are used, surface facet points will be included in
+ //! the point list used to calculate the tight bounding box. This
+ //! will include vertices and points on the curves. This is the
+ //! default implementation.
static CubitBoolean get_use_triangles();
static void set_use_triangles( CubitBoolean val );
- //- If triangles are used, surface facet points will be included in
- //- the point list used to calculate the tight bounding box. This
- //- will include vertices and points on the curves. This is the
- //- default implementation.
+
static int get_use_triangles_setting();
static void set_use_triangles_setting( int val );
+ //! If curves are used, curve tesselation points will be included in
+ //! the point list used to calculate the tight bounding box. This
+ //! includes the vertices on the ends of the curves. One use for this
+ //! is to find a more accurate tight bounding box, since curve
+ //! tessellations are typically more fine than surface tessellations.
+ //! However, in practice, I would generally recommend just using surface
+ //! tessellations. One special case is if the user sends in a list of
+ //! curves as the criteria for the tight bounding box, the curve
+ //- tessellations are always used, even if this parameter is false.
static CubitBoolean get_use_curves();
static void set_use_curves( CubitBoolean val );
- //- If curves are used, curve tesselation points will be included in
- //- the point list used to calculate the tight bounding box. This
- //- includes the vertices on the ends of the curves. One use for this
- //- is to find a more accurate tight bounding box, since curve
- //- tessellations are typically more fine than surface tessellations.
- //- However, in practice, I would generally recommend just using surface
- //- tessellations. One special case is if the user sends in a list of
- //- curves as the criteria for the tight bounding box, the curve
- //- tessellations are always used, even if this parameter is false.
+
static int get_use_curves_setting();
static void set_use_curves_setting( int val );
+ //! If vertices are used, vertex points will be included in the point
+ //! list used to calculate the tight bounding box. In extremely large
+ //! models, it could be advantageous to just use vertices. So the user
+ //! would turn off both the surface and curve flags. One special case
+ //! is if the user sends in a list of curves as the criteria for the
+ //! tight bounding box, the curve tessellations are always used, even
+ //! if the curve parameter is false and this parameter is true.
static CubitBoolean get_use_vertices();
static void set_use_vertices( CubitBoolean val );
- //- If vertices are used, vertex points will be included in the point
- //- list used to calculate the tight bounding box. In extremely large
- //- models, it could be advantageous to just use vertices. So the user
- //- would turn off both the surface and curve flags. One special case
- //- is if the user sends in a list of curves as the criteria for the
- //- tight bounding box, the curve tessellations are always used, even
- //- if the curve parameter is false and this parameter is true.
+
static int get_use_vertices_setting();
static void set_use_vertices_setting( int val );
- //Initialize all settings in this class
+ //! Initialize all settings in this class
static void initialize_settings();
protected :
Modified: cgm/branches/cubit/geom/CADefines.hpp
===================================================================
--- cgm/branches/cubit/geom/CADefines.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/CADefines.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -52,6 +52,9 @@
CA_ASSEMBLY_DATA,
CA_SIZING_FUNCTION_SKELETON,
CA_SOURCE_FEATURE
+#ifdef CAT
+ ,CA_PRO_WELD
+#endif
};
#endif // __CADEFINES_H__
Modified: cgm/branches/cubit/geom/CAEntityId.cpp
===================================================================
--- cgm/branches/cubit/geom/CAEntityId.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/CAEntityId.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -19,6 +19,8 @@
#include "GeometryQueryTool.hpp"
#include "GSaveOpen.hpp"
#include "CADeferredAttrib.hpp"
+#include "BasicTopologyEntity.hpp"
+#include "GeometryEntity.hpp"
CubitAttrib* CAEntityId_creator(RefEntity* entity, CubitSimpleAttrib *p_csa)
{
@@ -130,6 +132,14 @@
RefEntity *other_entity =
GeometryQueryTool::instance()->get_ref_entity(attribOwnerEntity->class_name(),
entityId+id_inc);
+
+ // Check to make sure the other entity has a valid topology bridge. If
+ // it doesn't it may be a ref entity hanging around that still needs
+ // to be cleaned up so don't consider it in the checks below.
+ TopologyEntity *te = dynamic_cast<TopologyEntity*>(other_entity);
+ if(te && !te->bridge_manager()->topology_bridge())
+ other_entity = NULL;
+
// 2) already an entity with the new id;
if (other_entity) {
// 2a) if other entity has a CAMP attribute, this owner has one too,
@@ -225,7 +235,8 @@
other_entity->find_cubit_attrib_type(CA_ENTITY_ID, att_list);
CAEntityId *other_caeid = (att_list.size() ? CAST_TO(att_list.get(), CAEntityId)
: NULL);
- if ( other_caeid && other_caeid->id()+id_inc != entityId+id_inc) {
+ if (other_caeid && other_caeid->id()+id_inc != entityId+id_inc)
+ {
// need to reset owner entity id first, so that we don't have
// two identical ids active at the same time (messes up the
// graphics)
@@ -276,6 +287,9 @@
// ok, now set the id and return
attribOwnerEntity->set_id (entityId+id_inc, CUBIT_FALSE);
attribOwnerEntity->color(CUBIT_DEFAULT_COLOR);
+ BasicTopologyEntity *bte = CAST_TO( attribOwnerEntity, BasicTopologyEntity );
+ if( bte )
+ bte->get_geometry_entity_ptr()->set_saved_id(entityId+id_inc);
hasActuated = CUBIT_TRUE;
Modified: cgm/branches/cubit/geom/CAMergePartner.cpp
===================================================================
--- cgm/branches/cubit/geom/CAMergePartner.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/CAMergePartner.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -86,6 +86,12 @@
CubitStatus CAMergePartner::actuate()
{
+ hasActuated = CUBIT_TRUE;
+ return CUBIT_SUCCESS;
+ //We don't need to actuate this attribute here since the merging
+ //happens in GeometryQueryTool::check_mergeable_refentity.
+
+ /*
if (hasActuated == CUBIT_TRUE) return CUBIT_SUCCESS;
BasicTopologyEntity * bte_ptr = CAST_TO(attribOwnerEntity,BasicTopologyEntity);
@@ -93,7 +99,7 @@
return CUBIT_FAILURE;
DLIList<RefEntity*> merge_list;
- merge_prepare(merge_list);
+ //merge_prepare(merge_list);
merge_list.append_unique(attribOwnerEntity);
CubitStatus result = CUBIT_SUCCESS;
@@ -107,7 +113,7 @@
hasActuated = CUBIT_TRUE;
}
- return result;
+ return result; */
}
void CAMergePartner::merge_prepare(DLIList<RefEntity*> &merge_list)
@@ -132,9 +138,15 @@
}
// now put those entities into the merge_list
- for (i = td_list.size(); i > 0; i--) {
+ for (i = td_list.size(); i > 0; i--)
+ {
re_ptr = CAST_TO(td_list.get(), RefEntity);
- if (re_ptr) merge_list.append(re_ptr);
+ if (re_ptr)
+ {
+ CubitAttrib *tmp_attrib = re_ptr->get_cubit_attrib( CA_MERGE_PARTNER, CUBIT_FALSE );
+ if( tmp_attrib )
+ merge_list.append(re_ptr);
+ }
td_list.step();
}
Modified: cgm/branches/cubit/geom/CGMApp.cpp
===================================================================
--- cgm/branches/cubit/geom/CGMApp.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/CGMApp.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -17,6 +17,7 @@
#include "GeometryQueryTool.hpp"
#include "GeometryModifyTool.hpp"
+#include "GeometryFeatureTool.hpp"
#include "GeometryHealerTool.hpp"
#include "BoundingBoxTool.hpp"
#include "RefEntityName.hpp"
@@ -25,6 +26,7 @@
#include "TDUniqueId.hpp"
#include "MergeTool.hpp"
#include "OldUnmergeCode.hpp"
+#include "ModelQueryEngine.hpp"
// TODO - I'm not sure this is the place to include all the attributes
#include "CADefines.hpp"
@@ -37,6 +39,9 @@
#include "CAEntityColor.hpp"
#include "CAMergeStatus.hpp"
#include "CASourceFeature.hpp"
+#ifdef CAT
+#include "cat\CAProWeld.hpp"
+#endif
CGMApp* CGMApp::instance_ = NULL;
@@ -92,11 +97,17 @@
void CGMApp::shutdown()
{
- delete GeometryHealerTool::instance();
- delete GeometryModifyTool::instance();
- delete GeometryQueryTool::instance();
+ GeometryHealerTool::delete_instance();
+ GeometryModifyTool::delete_instance();
+ GeometryQueryTool::delete_instance();
+ GeometryFeatureTool::delete_instance();
+ AnalyticGeometryTool::delete_instance();
+ RefEntityName::delete_instance();
+ MergeTool::delete_instance();
+ ModelQueryEngine::delete_instance();
-mAppStarted = CUBIT_FALSE;
+ DAG::delete_instance();
+ mAppStarted = CUBIT_FALSE;
}
void CGMApp::initialize_settings()
@@ -169,6 +180,14 @@
CUBIT_TRUE, CUBIT_TRUE, CUBIT_TRUE,
CUBIT_TRUE, CUBIT_FALSE);
assert (CUBIT_SUCCESS == result);
+#ifdef CAT
+ result = CGMApp::instance()->attrib_manager()->register_attrib_type(
+ CA_PRO_WELD, "pro weld", "PRO_WELD",
+ CAProWeld_creator, CUBIT_TRUE,
+ CUBIT_TRUE, CUBIT_TRUE, CUBIT_TRUE,
+ CUBIT_TRUE, CUBIT_FALSE);
+ assert (CUBIT_SUCCESS == result);
+#endif
}
CubitAttribManager* CGMApp::attrib_manager()
Modified: cgm/branches/cubit/geom/CGMApp.hpp
===================================================================
--- cgm/branches/cubit/geom/CGMApp.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/CGMApp.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -40,6 +40,7 @@
#include "CubitDefines.h"
#include "CubitAttribManager.hpp"
#include "CubitGeomConfigure.h"
+#include "DAG.hpp"
class CUBIT_GEOM_EXPORT CGMApp
{
Modified: cgm/branches/cubit/geom/CGMEngineDynamicLoader.cpp
===================================================================
--- cgm/branches/cubit/geom/CGMEngineDynamicLoader.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/CGMEngineDynamicLoader.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -3,6 +3,7 @@
#include "CGMEngineDynamicLoader.hpp"
#include "CubitMessage.hpp"
+#include <string.h>
extern "C"
{
@@ -111,7 +112,17 @@
}
CubitStatus CGMEngineDynamicLoader::unload_engine()
-{
+{
+ return CUBIT_SUCCESS;
+
+ /*
+
+//don't unload cubitcatia.dll
+#ifdef CATIA
+ if( mEngineName == "CATIA")
+ return CUBIT_SUCCESS;
+#endif
+
if(mLibraryHandle != CubitDynamicLoader::InvalidLibraryHandle)
{
CubitDynamicLoader::unload_library(mLibraryHandle);
@@ -119,8 +130,9 @@
mLibraryHandle = CubitDynamicLoader::InvalidLibraryHandle;
mQueryEngine = NULL;
mModifyEngine = NULL;
- }
+ }
return CUBIT_SUCCESS;
+ */
}
@@ -154,7 +166,7 @@
GeometryQueryEngine* CGMEngineDynamicLoader::get_gqe()
{
if(mQueryEngine)
- return mQueryEngine;
+ return mQueryEngine;
if(mLoadAttempted == CUBIT_FALSE)
load_engine();
Added: cgm/branches/cubit/geom/CGMHistory.cpp
===================================================================
--- cgm/branches/cubit/geom/CGMHistory.cpp (rev 0)
+++ cgm/branches/cubit/geom/CGMHistory.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,157 @@
+
+#include "CGMHistory.hpp"
+#include "TopologyBridge.hpp"
+#include "CubitMessage.hpp"
+#include "RefEntity.hpp"
+
+const char* event_names[] =
+{
+ "TOP_LEVEL_ENTITY_CREATED",
+ "TOP_LEVEL_ENTITY_DELETED",
+ "ENTITY_CREATED",
+ "ENTITY_DELETED",
+ "TOPOLOGY_CHANGED",
+ "GEOMETRY_CHANGED",
+ "GEOMETRY_TRANSFORMED",
+ "ENTITY_ID_CHANGED",
+ "ENTITY_NAME_CHANGED",
+ "ENTITY_COLOR_CHANGED",
+ "SUBDIVISION",
+ "ABSORPTION",
+ "SUBDIVISION_ABSORPTION",
+ "MERGE",
+ "COPY",
+ "CUT"
+};
+
+CGMHistory::CGMHistory()
+{
+ mTracking = false;
+ //mTracking = true;
+}
+
+CGMHistory::~CGMHistory()
+{
+}
+
+CGMHistory::Event::Event(CGMHistory::EventType type, RefEntity* refentity)
+{
+ eventType = type;
+ entities.push_back(refentity);
+}
+
+CGMHistory::Event::Event(CGMHistory::EventType type, const std::vector<RefEntity*>& refentity_list)
+{
+ eventType = type;
+ entities = refentity_list;
+}
+
+CGMHistory::Event::~Event()
+{
+}
+
+CGMHistory::EventType CGMHistory::Event::get_event_type() const
+{
+ return eventType;
+}
+
+const std::vector<RefEntity*>& CGMHistory::Event::get_entities() const
+{
+ return entities;
+}
+
+void CGMHistory::start_tracking()
+{
+ mTracking = true;
+}
+
+void CGMHistory::end_tracking()
+{
+ mTracking = false;
+}
+
+bool CGMHistory::is_tracking() const
+{
+ return mTracking;
+}
+
+int CGMHistory::get_number_of_events() const
+{
+ return eventList.size();
+}
+
+const CGMHistory::Event* CGMHistory::get_event( int index ) const
+{
+ if(index < eventList.size())
+ return &eventList[index];
+ return NULL;
+}
+
+void CGMHistory::add_event( const CGMHistory::Event &event )
+{
+ if(mTracking)
+ eventList.push_back(event);
+}
+
+void CGMHistory::add_port_event( const CGMHistory::PortEvent &event )
+{
+ if(mTracking)
+ portEventList.push_back(event);
+}
+
+void CGMHistory::compress()
+{
+ // TODO
+}
+
+void CGMHistory::clear()
+{
+ eventList.clear();
+ portEventList.clear();
+}
+
+void CGMHistory::print_port_events()
+{
+
+ std::vector<PortEvent>::iterator iter = portEventList.begin();
+ for(; iter != portEventList.end(); iter++ )
+ {
+ PortEvent port_event = *iter;
+ PRINT_INFO("Event type = %s RefEntities ", event_names[ port_event.eventType ]);
+
+ int i;
+ for( i=0; i<port_event.RefEnts.size(); i++ )
+ {
+ RefEntity *ref_ent = port_event.RefEnts[i];
+ PRINT_INFO(" %s %d ", ref_ent->class_name(), ref_ent->id() );
+ }
+ PRINT_INFO(" ---> ");
+ for( i=0; i<port_event.TopologyBridges.size(); i++ )
+ {
+ TopologyBridge *tb = port_event.TopologyBridges[i];
+ PRINT_INFO(" %p", tb );
+ }
+ PRINT_INFO("\n");
+ }
+}
+
+CGMHistory::PortEvent::PortEvent(CGMHistory::EventType type )
+{
+ eventType = type;
+// if( eventType != GEOMETRY_TRANSFORMED )
+// TopologyBridges = new std::vector<TopologyBridge*>;
+// else
+// TopologyBridges = NULL;
+}
+
+CGMHistory::PortEvent::~PortEvent()
+{
+// if( TopologyBridges )
+// delete TopologyBridges;
+}
+
+CGMHistory::EventType CGMHistory::PortEvent::get_event_type() const
+{
+ return eventType;
+}
+
Added: cgm/branches/cubit/geom/CGMHistory.hpp
===================================================================
--- cgm/branches/cubit/geom/CGMHistory.hpp (rev 0)
+++ cgm/branches/cubit/geom/CGMHistory.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,187 @@
+
+
+#ifndef CGMHistory_hpp
+#define CGMHistory_hpp
+
+#include <vector>
+#include "CubitTransformMatrix.hpp"
+#include "CubitGeomConfigure.h"
+class RefEntity;
+class TopologyBridge;
+
+class CUBIT_GEOM_EXPORT CGMHistory
+{
+ public:
+ CGMHistory();
+ ~CGMHistory();
+
+ enum EventType
+ {
+ // Top level creation means an entity with no parent is created
+ // this could be bodies, surfaces, curves or vertices
+ TOP_LEVEL_ENTITY_CREATED,
+
+ // Top level deleted means an entity no longer has top level status
+ // it may have been deleted or it may have been consumed into a higher
+ // dimensional entity
+ TOP_LEVEL_ENTITY_DELETED,
+
+ // An entity has been created
+ ENTITY_CREATED,
+
+ // An entity has been deleted
+ ENTITY_DELETED,
+
+ // An entity's topology changes, meaning it has gained new child entities
+ // or lost old child entities. This can result from solid modeling
+ // operations or from operations within cgm such as merging.
+ TOPOLOGY_CHANGED,
+
+ // 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,
+
+ // A transformation happend to this entity, all child entities are
+ // transformed as well. In this case, a GEOMETRY_CHANGED does not occur.
+ GEOMETRY_TRANSFORMED,
+
+ // The id of an entity changes
+ ENTITY_ID_CHANGED,
+
+ // The name of an entity changes
+ ENTITY_NAME_CHANGED,
+
+ // The name of an entity changes
+ ENTITY_COLOR_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,
+
+ // 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,
+
+ // An entity is merged into another
+ // this is a supplemental event such that other events completely
+ // describe the topology changes, but this event specifies where the
+ // merge occurred
+ MERGE,
+
+ // 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,
+
+ // Cousin to SUBDIVISION. Think of it as a 1-to-n subdivision where
+ // only 1 of the n actually survives, so it's really and 1-to-1
+ // modification.
+ CUT
+ };
+
+ //Event is a record of a change that occurred during an operation
+ class CUBIT_GEOM_EXPORT Event
+ {
+ public:
+ Event(EventType type, RefEntity* refentity);
+ Event(EventType type, const std::vector<RefEntity*>& refentity_list);
+ ~Event();
+
+ EventType get_event_type() const;
+ const std::vector<RefEntity*>& get_entities() const;
+
+ private:
+
+ // the type of event this is
+ EventType eventType;
+ // the entities this event applies to
+ std::vector<RefEntity*> entities;
+
+ // extra data associated with event
+ union
+ {
+ std::vector<RefEntity*> *other_entities;
+ CubitTransformMatrix *matrix;
+ // TODO add data types for other events
+ };
+ };
+
+
+ class CUBIT_GEOM_EXPORT PortEvent
+ {
+ public:
+ PortEvent(EventType type, std::vector<RefEntity*> &source_entities,
+ std::vector<TopologyBridge*> &result_entities );
+ PortEvent( EventType type );
+ ~PortEvent();
+
+ EventType get_event_type() const;
+ const std::vector<RefEntity*>& get_entities() const;
+
+ EventType eventType;
+ // the entities this event applies to
+ std::vector<RefEntity*> RefEnts;
+ std::vector<TopologyBridge*> TopologyBridges;
+
+ // extra data associated with event
+ //union
+ // {
+ // std::vector<TopologyBridge*> *TopologyBridges;
+ // CubitTransformMatrix *matrix;
+ // TODO add data types for other events
+ // };
+ };
+
+
+
+ // get the number of events in this history
+ int get_number_of_events() const;
+ // get an event by index
+ const Event* get_event( int index ) const;
+
+ void print_port_events();
+
+ // add an event to this history
+ void add_event( const Event &new_event );
+ // compress the events in this history
+ // for example, if an event for volume 1 created and an event for volume 1
+ // deleted exists, both are removed
+
+ void add_port_event( const PortEvent &event );
+
+ void compress();
+
+ // cleans out the history
+ void clear();
+
+ // start tracking events
+ void start_tracking();
+ // stop tracking events
+ void end_tracking();
+ // ask if tracking
+ bool is_tracking() const;
+
+ private:
+ // the list of events
+ std::vector<Event> eventList;
+ std::vector<PortEvent> portEventList;
+ bool mTracking;
+};
+
+#endif
+
Modified: cgm/branches/cubit/geom/CMakeLists.txt
===================================================================
--- cgm/branches/cubit/geom/CMakeLists.txt 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/CMakeLists.txt 2010-01-06 19:22:14 UTC (rev 3423)
@@ -2,25 +2,52 @@
PROJECT(cubit_geom)
+OPTION(CGM_FACET "Build CGM with Facet support" ON)
+IF(CGM_FACET)
+SUBDIRS(Cholla facetbool facet)
+ENDIF(CGM_FACET)
-SUBDIRS(Cholla facetbool facet virtual)
+OPTION(CGM_VIRTUAL "Build CGM with Virtual support" ON)
+IF(CGM_VIRTUAL)
+SUBDIRS(virtual)
+ENDIF(CGM_VIRTUAL)
-# build cgm with acis support, default to on
-OPTION(CGM_ACIS "Build CGM with ACIS support" ON)
+# build cgm with acis support, default to off
+OPTION(CGM_ACIS "Build CGM with ACIS support" OFF)
IF(CGM_ACIS)
SUBDIRS(ACIS)
ENDIF(CGM_ACIS)
+
+OPTION(CGM_SMLIB "Build CGM with SMLIB support" OFF)
+IF(CGM_SMLIB)
+SUBDIRS(smlib)
+ENDIF(CGM_SMLIB)
+
+
# build cgm with granite support, default to off
OPTION(CGM_GRANITE "Build CGM with Granite support" OFF)
IF(CGM_GRANITE)
SUBDIRS(granite)
ENDIF(CGM_GRANITE)
+OPTION(CGM_CATIA "Build CGM with CATIA support" OFF)
+IF(CGM_CATIA)
+ SET(CGM_ACIS OFF CACHE BOOL "ACIS not supported with CATIA" FORCE)
+ SET(FEATURE_OPTION OFF CACHE BOOL "Feature option not allowed with CATIA" FORCE)
+ SET(TOLERANT_TRI OFF CACHE BOOL "Geometry-tolerant meshing option not allowed with CATIA" FORCE)
+ SET(ACIS_IGES OFF CACHE BOOL "ACIS_IGES not allowed with CATIA" FORCE)
+ SET(ACIS_STEP OFF CACHE BOOL "ACIS_STEP not allowed with CATIA" FORCE)
+ SET(CUBIT_GEOM_BUILD_SHARED_LIBS ON CACHE BOOL "GEOM_LIBS need to be shared when CATIA is used" FORCE)
+ SET(CUBIT_UTIL_BUILD_SHARED_LIBS ON CACHE BOOL "UTIL_LIBS need to be shared when CATIA is used" FORCE)
+
+ENDIF(CGM_CATIA)
+
INCLUDE(${cubit_geom_SOURCE_DIR}/../util/UseUtil.cmake)
SET(GEOM_SRCS
AnalyticGeometryTool.cpp
+ AutoMidsurfaceTool.cpp
BasicTopologyEntity.cpp
Body.cpp
BodySM.cpp
@@ -38,6 +65,7 @@
CAUniqueId.cpp
CGMApp.cpp
CGMEngineDynamicLoader.cpp
+ CGMHistory.cpp
Chain.cpp
CoEdge.cpp
CoEdgeSM.cpp
@@ -58,9 +86,7 @@
DagDrawingTool.cpp
GeomDataObserver.cpp
GeometryEntity.cpp
- GeometryFeatureEngine.cpp
GeometryFeatureTool.cpp
- GeometryHealerEngine.cpp
GeometryHealerTool.cpp
GeometryModifyEngine.cpp
GeometryModifyTool.cpp
@@ -68,6 +94,7 @@
GeometryQueryTool.cpp
GeometryUtil.cpp
GeomMeasureTool.cpp
+ GfxPreview.cpp
GroupingEntity.cpp
GSaveOpen.cpp
Loop.cpp
@@ -78,11 +105,11 @@
MedialTool3D.cpp
MergeToolAssistant.cpp
MergeTool.cpp
- MidPlaneTool.cpp
ModelEntity.cpp
ModelQueryEngine.cpp
OffsetSplitTool.cpp
OldUnmergeCode.cpp
+ PeriodicParamTool.cpp
Point.cpp
PointSM.cpp
RefCollection.cpp
@@ -158,44 +185,27 @@
IF(CUBIT_GEOM_BUILD_SHARED_LIBS)
ADD_LIBRARY(cubit_geom SHARED ${GEOM_SRCS} ${EXTRA_GEOM_SRCS} ${GEOM_HEADERS} ${TEMPLATE_SRCS})
-
- IF(CUBIT_COPY_DIR)
- # The cubit copy dir should only be set on windows.
- STRING(REGEX REPLACE "/" "\\\\" winbin "${CUBIT_COPY_DIR}")
- IF(${CMAKE_GENERATOR} MATCHES "Visual Studio")
- ADD_CUSTOM_COMMAND(TARGET cubit_geom POST_BUILD
- COMMAND ${CMAKE_COMMAND}
- ARGS -E copy
- $\(TargetPath\) ${winbin}\\$\(TargetName\).dll)
- ELSE(${CMAKE_GENERATOR} MATCHES "Visual Studio")
- STRING(REGEX REPLACE "/" "\\\\" winsrc "${LIBRARY_OUTPUT_PATH}")
- ADD_CUSTOM_COMMAND(TARGET cubit_geom POST_BUILD
- COMMAND ${CMAKE_COMMAND}
- ARGS -E copy
- ${winsrc}\\cubit_geom.dll
- ${winlib}\\cubit_geom.dll)
- ENDIF(${CMAKE_GENERATOR} MATCHES "Visual Studio")
- ENDIF(CUBIT_COPY_DIR)
ELSE(CUBIT_GEOM_BUILD_SHARED_LIBS)
ADD_LIBRARY(cubit_geom ${GEOM_SRCS} ${EXTRA_GEOM_SRCS} ${GEOM_HEADERS} ${TEMPLATE_SRCS})
ENDIF(CUBIT_GEOM_BUILD_SHARED_LIBS)
TARGET_LINK_LIBRARIES(cubit_geom cubit_util)
-IF(UNIX)
-ADD_CUSTOM_TARGET(switch_acis
- rm -f *Acis*.o &&
- rm -f attrib*.o &&
- rm -f *ACIS*.o &&
- rm -f GeometryCommands.o &&
- rm -f Feature*.o &&
- rm -f *App.o &&
- cd ACIS && ${CMAKE_MAKE_PROGRAM} switch_acis)
+IF(CUBIT_LIBRARY_PROPERTIES)
+ SET_TARGET_PROPERTIES(cubit_geom
+ PROPERTIES ${CUBIT_LIBRARY_PROPERTIES})
+ENDIF(CUBIT_LIBRARY_PROPERTIES)
-ENDIF(UNIX)
+SET(CMAKE_INSTALL_BINARY_DIR "bin" CACHE PATH "Install directory for binaries")
-SET(CMAKE_INSTALL_BINARY_DIR "bin" CACHE PATH "Install directory for binaries")
IF(CUBIT_GEOM_BUILD_SHARED_LIBS)
- INSTALL_TARGETS(/${CMAKE_INSTALL_BINARY_DIR} cubit_geom)
+ INSTALL(TARGETS cubit_geom
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINARY_DIR} COMPONENT Runtime
+ LIBRARY DESTINATION ${CMAKE_INSTALL_BINARY_DIR} COMPONENT Runtime
+ )
ENDIF(CUBIT_GEOM_BUILD_SHARED_LIBS)
+IF(BUILD_TESTING)
+ #ADD_SUBDIRECTORY(testing)
+ENDIF(BUILD_TESTING)
+
Modified: cgm/branches/cubit/geom/Cholla/CMakeLists.txt
===================================================================
--- cgm/branches/cubit/geom/Cholla/CMakeLists.txt 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/CMakeLists.txt 2010-01-06 19:22:14 UTC (rev 3423)
@@ -8,6 +8,7 @@
ChollaPoint.cpp
ChollaSkinTool.cpp
ChollaSurface.cpp
+ ChollaVolume.cpp
ChordalAxis.cpp
CubitFacet.cpp
CubitFacetData.cpp
@@ -42,6 +43,7 @@
IF(TEMPLATE_DEFS_INCLUDED)
SET(TEMPLATE_SRCS
FacetorTool.cpp
+ FacetorUtil.cpp
TetFacetorTool.cpp
TDDelaunay.cpp
)
Modified: cgm/branches/cubit/geom/Cholla/Cholla.cpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/Cholla.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/Cholla.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -1755,7 +1755,7 @@
static void time_stamp( FILE *fp )
{
struct tm *newtime;
- char am_pm[] = "AM";
+ char* am_pm = "AM";
time_t long_time;
time( &long_time ); /* Get time as long integer. */
Modified: cgm/branches/cubit/geom/Cholla/ChollaCurve.cpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/ChollaCurve.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/ChollaCurve.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -8,6 +8,7 @@
#include "CubitVector.hpp"
#include "ChollaCurve.hpp"
#include "ChollaSurface.hpp"
+#include "ChollaPoint.hpp"
#include "TDGeomFacet.hpp"
#include "CastTo.hpp"
#include "CubitFacet.hpp"
@@ -16,6 +17,8 @@
#include "CubitFacetEdgeData.hpp"
#include "debug.hpp"
#include "GfxDebug.hpp"
+#include "CurveFacetEvalTool.hpp"
+#include "ChollaEngine.hpp"
//===============================================================================
//Function: ChollaCurve (PUBLIC) (constructor)
@@ -29,7 +32,9 @@
startPoint = NULL;
endPoint = NULL;
blockID = block_id;
+ myLength = MYLENGTH_UNINITIALIZED;
}
+
//===============================================================================
//Function: ~ChollaCurve (PUBLIC) (destructor)
//===============================================================================
@@ -128,7 +133,6 @@
int periodic = 0;
int start_size = curveEdgeList.size();
int icount = 0;
- int mydebug = 0;
curveEdgeList.reset();
while( curveEdgeList.size() > 0)
@@ -160,92 +164,28 @@
int block_id = (td_gm_edge == NULL) ? -1 : td_gm_edge->get_block_id();
ChollaCurve *fcm_ptr = new ChollaCurve( block_id );
new_curve_list.append( fcm_ptr );
- fcm_ptr->set_start( start_point );
- start_point->set_as_feature();
-
- fcm_ptr->add_facet( start_edge_ptr );
- curveEdgeList.remove( start_edge_ptr );
- int iedgecount = 0;
- CubitFacetEdge *edge_ptr = start_edge_ptr;
- point0_ptr = start_point;
- CubitPoint *end_point = NULL;
- while(!end_point)
- {
- point1_ptr = edge_ptr->other_point( point0_ptr );
- if ((edge_ptr = next_edge( point1_ptr, edge_ptr )) == NULL)
- {
- end_point = point1_ptr;
- }
- else
- {
- iedgecount++;
- if (iedgecount > start_size)
- {
- PRINT_ERROR("ChollaCurve has start, but no end\n");
- return CUBIT_FAILURE;
- }
-
- fcm_ptr->add_facet( edge_ptr );
- curveEdgeList.remove( edge_ptr );
- if (periodic && point1_ptr == start_point)
- end_point = start_point;
- point0_ptr = point1_ptr;
- }
- }
- fcm_ptr->set_end( end_point );
- end_point->set_as_feature();
- start_size = curveEdgeList.size();
- icount = 0;
- periodic = 0;
-
- // make sure all the edges are oriented correctly
-
- int i;
+
+ // assign the edges to the new curve in the correct order and orientation
+
+ CubitStatus rv = fcm_ptr->build_curve_from_edges( start_point, periodic, start_size, start_edge_ptr, this );
+ if (rv != CUBIT_SUCCESS)
+ return rv;
+
+ // remove the edges in the new curve from this curve
+
+ int ii;
DLIList<FacetEntity *> flist = fcm_ptr->get_facet_list();
- flist.reset();
DLIList<CubitFacetEdge *> elist;
+ CubitFacetEdge *edge_ptr;
CAST_LIST( flist, elist, CubitFacetEdge );
- elist.reset();
- CubitPoint *cur_pt = start_point, *tmp_pt;
- for ( i = elist.size(); i > 0; i-- )
+ for ( ii = elist.size(); ii > 0; ii-- )
{
edge_ptr = elist.get_and_step();
- point0_ptr = edge_ptr->point(0);
- point1_ptr = edge_ptr->point(1);
- if (point0_ptr != cur_pt)
- {
- assert( cur_pt == point1_ptr );
- edge_ptr->flip();
- tmp_pt = point0_ptr;
- point0_ptr = point1_ptr;
- point1_ptr = tmp_pt;
- assert( point0_ptr == edge_ptr->point(0) &&
- point1_ptr == edge_ptr->point(1) );
- }
- cur_pt = point1_ptr;
+ curveEdgeList.remove( edge_ptr );
}
-
- if (mydebug)
- {
- int i;
- DLIList<FacetEntity *> flist = fcm_ptr->get_facet_list();
- flist.reset();
- DLIList<CubitFacetEdge *> elist;
- CAST_LIST( flist, elist, CubitFacetEdge );
- elist.reset();
- for ( i = elist.size(); i > 0; i-- ) {
- CubitFacetEdge *edge = elist.get_and_step();
- CubitVector pt0_v = edge->point(0)->coordinates();
- CubitVector pt1_v = edge->point(1)->coordinates();
- GfxDebug::draw_point(pt0_v, CUBIT_GREEN );
- GfxDebug::draw_point(pt1_v, CUBIT_RED );
- GfxDebug::draw_line( pt0_v, pt1_v, CUBIT_YELLOW );
- GfxDebug::flush();
- int view = 0;
- if (view)
- dview();
- }
- }
+ start_size = curveEdgeList.size();
+ icount = 0;
+ periodic = 0;
}
// if we have gone through all of the edges without finding an end,
@@ -305,8 +245,218 @@
return CUBIT_SUCCESS;
}
+//=============================================================================
+//Function: build_curve_from_edges
+//Description: insert the ordered and oriented edges into this cholla curve
+//Notes: traverses starting at start_point and gathers facet edges until it
+// runs into another curve.
+// start_point is an existing CubitPoint at either end of the curve
+// max_edges is the maximum number of edges on this curve. should be
+// known beforehand (used for error checking).
+//
+// ***this function used to be part of split_curve. ***
+//Author: sjowen
+//Return:
+//Date: 09/07/2009
+//=============================================================================
+CubitStatus ChollaCurve::build_curve_from_edges( CubitPoint *start_point,
+ int periodic,
+ int max_edges,
+ CubitFacetEdge *start_edge_ptr,
+ ChollaCurve *parent_curve )
+{
+
+ // find the first edge. Match the chollacurve owner with this curve
+ // do this only if the start_edge_ptr was not passed in
+
+ DLIList<CubitFacetEdge *> point_edge_list;
+ start_point->edges(point_edge_list);
+ CubitFacetEdge *edge_ptr;
+ if (start_edge_ptr == NULL)
+ {
+ for (int ii=0; ii<point_edge_list.size() && !start_edge_ptr; ii++)
+ {
+ edge_ptr = point_edge_list.get_and_step();
+ TDGeomFacet *td_geom = TDGeomFacet::get_geom_facet( edge_ptr );
+
+ // assumes that the TDGeomFacet info has already been set up for the edges
+ assert(td_geom != NULL);
+
+ DLIList<ChollaCurve *> cholla_curves;
+ td_geom->get_cholla_curves(cholla_curves);
+
+ // currently should be only one-to-one relationship
+ // could also be edge on surface in which case no curves associated
+ assert(cholla_curves.size() <= 1);
+ if (cholla_curves.size())
+ {
+ if (cholla_curves.get() == this)
+ start_edge_ptr = edge_ptr;
+ }
+ }
+ assert(start_edge_ptr != NULL); // didn't find an edge that marched this chollacurve
+ }
+
+ // create a new curve to hold the edge info
+
+ this->set_start( start_point );
+ start_point->set_as_feature();
+
+ this->add_facet( start_edge_ptr );
+ int iedgecount = 0;
+ edge_ptr = start_edge_ptr;
+ CubitPoint *point0_ptr = start_point, *point1_ptr;
+ CubitPoint *end_point = NULL;
+ while(!end_point)
+ {
+ point1_ptr = edge_ptr->other_point( point0_ptr );
+ if ((edge_ptr = parent_curve->next_edge( point1_ptr, edge_ptr )) == NULL)
+ {
+ end_point = point1_ptr;
+ }
+ else
+ {
+ iedgecount++;
+ if (iedgecount > max_edges)
+ {
+ PRINT_ERROR("ChollaCurve has start, but no end\n");
+ return CUBIT_FAILURE;
+ }
+
+ this->add_facet( edge_ptr );
+ if (periodic && point1_ptr == start_point)
+ end_point = start_point;
+ point0_ptr = point1_ptr;
+ }
+ }
+ this->set_end( end_point );
+ end_point->set_as_feature();
+
+ // make sure all the edges are oriented correctly
+
+ int i;
+ DLIList<FacetEntity *> flist = this->get_facet_list();
+ flist.reset();
+ DLIList<CubitFacetEdge *> elist;
+ CAST_LIST( flist, elist, CubitFacetEdge );
+ elist.reset();
+ CubitPoint *cur_pt = start_point, *tmp_pt;
+ for ( i = elist.size(); i > 0; i-- )
+ {
+ edge_ptr = elist.get_and_step();
+ point0_ptr = edge_ptr->point(0);
+ point1_ptr = edge_ptr->point(1);
+ if (point0_ptr != cur_pt)
+ {
+ assert( cur_pt == point1_ptr );
+ edge_ptr->flip();
+ tmp_pt = point0_ptr;
+ point0_ptr = point1_ptr;
+ point1_ptr = tmp_pt;
+ assert( point0_ptr == edge_ptr->point(0) &&
+ point1_ptr == edge_ptr->point(1) );
+ }
+ cur_pt = point1_ptr;
+ }
+
+ int mydebug = 0;
+ if (mydebug)
+ {
+ int i;
+ DLIList<FacetEntity *> flist = this->get_facet_list();
+ flist.reset();
+ DLIList<CubitFacetEdge *> elist;
+ CAST_LIST( flist, elist, CubitFacetEdge );
+ elist.reset();
+ for ( i = elist.size(); i > 0; i-- ) {
+ CubitFacetEdge *edge = elist.get_and_step();
+ CubitVector pt0_v = edge->point(0)->coordinates();
+ CubitVector pt1_v = edge->point(1)->coordinates();
+ GfxDebug::draw_point(pt0_v, CUBIT_GREEN );
+ GfxDebug::draw_point(pt1_v, CUBIT_RED );
+ GfxDebug::draw_line( pt0_v, pt1_v, CUBIT_YELLOW );
+ GfxDebug::flush();
+ int view = 0;
+ if (view)
+ dview();
+ }
+ }
+ return CUBIT_SUCCESS;
+}
//=============================================================================
+//Function: length
+//Description:
+//Author: sjowen
+//Date: 04/21/2009
+//============================================================================
+double ChollaCurve::length()
+{
+ if (myLength > MYLENGTH_UNINITIALIZED)
+ return myLength;
+
+ CubitFacetEdge *edge;
+ FacetEntity *fent;
+ myLength = 0.0;
+ for (int iedge=0; iedge<curveEdgeList.size(); iedge++)
+ {
+ fent = curveEdgeList.get_and_step();
+ edge = dynamic_cast<CubitFacetEdge *> (fent);
+ myLength += edge->length();
+ }
+
+ return myLength;
+}
+
+//=============================================================================
+//Function: find adjacent edges at a point that lie on the curve
+//Description: determine the next edge from a given edge - return NULL if at the end
+//Author: william roshan quadros
+//Return: returns false if no adj_edges can be found
+//Date: 04/21/2009
+//=============================================================================
+bool ChollaCurve::adj_facet_edges( CubitPoint *node_ptr, CubitFacetEdge *&adj_edge1, CubitFacetEdge *&adj_edge2 )
+{
+ // initialize adj_edge1 and adj_edge2
+ adj_edge1 = adj_edge2 = NULL;
+
+ DLIList<CubitFacetEdge*> edge_list;
+ node_ptr->edges( edge_list );
+ int jj, kk;
+ for (jj=0; jj<edge_list.size(); jj++)
+ {
+ CubitFacetEdge *node_edge_ptr = edge_list.get_and_step();
+ TDGeomFacet *td_gm_edge = TDGeomFacet::get_geom_facet(node_edge_ptr);
+ if (td_gm_edge != NULL)
+ {
+ DLIList<ChollaCurve*> fcurve_list;
+ td_gm_edge->get_cholla_curves( fcurve_list );
+ if (fcurve_list.size() > 0)
+ { // match the curve to the edge to find the next edge
+ for (kk=0; kk<fcurve_list.size(); kk++)
+ {
+ ChollaCurve *fcm_ptr = fcurve_list.get_and_step();
+ if (fcm_ptr == this)
+ {
+ if( NULL == adj_edge1 )
+ adj_edge1 = node_edge_ptr;
+ else
+ if( NULL == adj_edge2 )
+ adj_edge2 = node_edge_ptr;
+ else
+ assert( false ); // More than two adj_edges can't be incident on a curve
+ }
+ }
+ }
+ }
+ }
+ if( NULL == adj_edge1 )
+ return false;
+ else
+ return true;
+}
+
+//=============================================================================
//Function: next_edge (PRIVATE)
//Description: determine the next edge from a given edge - return NULL if at
// the end
@@ -591,5 +741,247 @@
fclose(fp);
}
+
+ // disassociate from cholla points
+CubitStatus ChollaCurve::disassociate_from_points( void )
+{
+
+ /*
+ if( startPoint )
+ {
+ startPoint->remove_curve( this );
+ startPoint = NULL;
+ }
+ if( endPoint )
+ {
+ endPoint->remove_curve( this );
+ endPoint = NULL;
+ }
+ */
+
+ int i;
+ for( i = 0; i < pointList.size(); i++ )
+ {
+ pointList.get_and_step()->remove_curve( this );
+ }
+ pointList.clean_out();
+
+ return CUBIT_SUCCESS;
+}
+
+ // disassociate from cholla surface
+CubitStatus ChollaCurve::disassociate_from_surfaces( void)
+{
+ int i;
+ for( i = 0; i < surfaceList.size(); i++ )
+ {
+ surfaceList.get_and_step()->remove_curve( this );
+ }
+ surfaceList.clean_out();
+ return CUBIT_SUCCESS;
+}
+
+
+CubitStatus ChollaCurve::replace_facet( FacetEntity *remove_edge, FacetEntity *replace_edge )
+{
+ curveEdgeList.move_to( remove_edge );
+ curveEdgeList.insert( replace_edge );
+ curveEdgeList.remove( remove_edge );
+ myLength = MYLENGTH_UNINITIALIZED;
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus ChollaCurve::build_curve_facet_eval_tool( void )
+{
+ //debug this function as point list is not valid
+
+ if( this->get_eval_tool() )
+ {
+ assert(false); //WARNING: Curve facet eval tool already exist!
+ }
+
+ CurveFacetEvalTool *curv_eval_tool_ptr = new CurveFacetEvalTool();
+
+ // Step 1: Initialize facet_edge_list and point_list
+ CubitStatus stat;
+ DLIList<CubitPoint *> point_list;
+ int i;
+ // insert start point of every facet_edge
+ curveEdgeList.reset();
+ for( i = 0; i < curveEdgeList.size(); i++ )
+ {
+ point_list.append( CAST_TO( curveEdgeList.get_and_step(), CubitFacetEdge )->point(0) );
+ }
+ // insert end point of last facet_edge
+ curveEdgeList.step( curveEdgeList.size() - 1 );
+ point_list.append( CAST_TO( curveEdgeList.get(), CubitFacetEdge )->point(1) );
+
+ DLIList<CubitFacetEdge *> edge_list;
+ CAST_LIST( curveEdgeList, edge_list, CubitFacetEdge );
+ stat = curv_eval_tool_ptr->initialize( edge_list, point_list );
+ if( stat != CUBIT_SUCCESS )
+ {
+ return stat;
+ }
+
+ /*
+ // Step 2: find sense of curve_facet_eval_tool /// this is done internally in next Step in initialize()
+ if( this->startPoint )
+ {
+ stat = curv_eval_tool_ptr->find_curv_sense( this->startPoint );
+ if( stat != CUBIT_SUCCESS )
+ {
+ return stat;
+ }
+ }
+*/
+ // Step 2: Initialize adj_surface_facet_eval_tool with orientation_wrt_surface
+ if( surfaceList.size() )
+ {
+ CubitSense orientation_wrt_surface;
+ if( CUBIT_SUCCESS == ChollaEngine::determine_curve_orientation( surfaceList.get(), this, orientation_wrt_surface ) )
+ {
+ if( this->startPoint && this->endPoint )
+ {
+ stat = curv_eval_tool_ptr->initialize( surfaceList.get()->get_eval_tool(),
+ this->startPoint,
+ this->endPoint,
+ orientation_wrt_surface);
+ }
+ }
+ else
+ {
+ assert(false);
+ }
+
+ if( stat != CUBIT_SUCCESS )
+ {
+ assert( false );
+ return stat;
+ }
+ }
+ else
+ {
+ assert(false); //WARNING: No adjacent cholla surface available
+ }
+
+ // Step 4: assign the new curv_eval_tool to cholla_curve
+ assign_eval_tool( curv_eval_tool_ptr );
+
+ return stat;
+}
+
+//=============================================================================
+//Function: is_in_volume (PUBLIC)
+//Description: return whether this curve is contained within the specified volume
+//Author: sjowen
+//Date: 9/11/2009
+//=============================================================================
+CubitBoolean ChollaCurve::is_in_volume( ChollaVolume *chvol_ptr )
+{
+ for (int ii=0; ii<surfaceList.size(); ii++)
+ {
+ ChollaSurface *chsurf_ptr = surfaceList.get_and_step();
+ DLIList<ChollaVolume *> chvol_list;
+ chsurf_ptr->get_volumes(chvol_list);
+ for (int jj=0; jj<chvol_list.size(); jj++)
+ {
+ ChollaVolume *mychvol_ptr = chvol_list.get_and_step();
+ if (mychvol_ptr == chvol_ptr)
+ return CUBIT_TRUE;
+ }
+ }
+ return CUBIT_FALSE;
+}
+
+//=============================================================================
+//Function: is_in_surface (PUBLIC)
+//Description: return whether this curve is contained within the specified surface
+//Author: sjowen
+//Date: 9/18/2009
+//=============================================================================
+CubitBoolean ChollaCurve::is_in_surface( ChollaSurface *chsurf_ptr )
+{
+ for (int ii=0; ii<surfaceList.size(); ii++)
+ {
+ ChollaSurface *mysurf_ptr = surfaceList.get_and_step();
+ if (mysurf_ptr == chsurf_ptr)
+ {
+ return CUBIT_TRUE;
+ }
+ }
+ return CUBIT_FALSE;
+}
+
+
+//=============================================================================
+//Function: get_facet_points (PUBLIC)
+//Description: return the list of facet points on this chollacurve
+//Notes: inclusive = true will return end points as well, otherwise only
+// interior points will be returned
+//Author: sjowen
+//Date: 9/11/2009
+//=============================================================================
+void ChollaCurve::get_facet_points( DLIList<CubitPoint *> &point_list, CubitBoolean inclusive)
+{
+ FacetEntity *fe_ptr;
+ CubitFacetEdge *edge_ptr;
+ CubitPoint *pts[2];
+ for (int ii=0; ii<curveEdgeList.size(); ii++)
+ {
+ fe_ptr = curveEdgeList.get_and_step();
+ edge_ptr = dynamic_cast<CubitFacetEdge *> (fe_ptr);
+ assert(edge_ptr != NULL);
+ for (int jj=0; jj<2; jj++)
+ {
+ pts[jj] = edge_ptr->point(jj);
+ if (inclusive)
+ {
+ point_list.append(pts[jj]);
+ }
+ else
+ {
+ if (pts[jj] != startPoint && pts[jj] != endPoint)
+ {
+ point_list.append(pts[jj]);
+ }
+ }
+ }
+ }
+ point_list.uniquify_ordered();
+}
+
+//=============================================================================
+//Function: has_point (PUBLIC)
+//Description: return whether the curve contains the gicen point
+//Notes:
+//=============================================================================
+CubitBoolean ChollaCurve::has_point( ChollaPoint *chpt )
+{
+ for(int ii=0; ii<pointList.size(); ii++)
+ {
+ ChollaPoint *pt = pointList.get_and_step();
+ if (pt == chpt)
+ return CUBIT_TRUE;
+ }
+ return CUBIT_FALSE;
+}
+
+//=============================================================================
+//Function: verify_points (PUBLIC)
+//Description: verify that all points on this curve have this curve as an adjacency
+//Notes:
+//=============================================================================
+CubitStatus ChollaCurve::verify_points()
+{
+ for(int ii=0; ii<pointList.size(); ii++)
+ {
+ ChollaPoint *pt = pointList.get_and_step();
+ if (!pt->is_in_curve(this))
+ return CUBIT_FAILURE;
+ }
+ return CUBIT_SUCCESS;
+}
+
//EOF
Modified: cgm/branches/cubit/geom/Cholla/ChollaCurve.hpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/ChollaCurve.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/ChollaCurve.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -10,6 +10,8 @@
#ifndef ChollaCurve_HPP
#define ChollaCurve_HPP
+#define MYLENGTH_UNINITIALIZED -1.0
+
#include "DLIList.hpp"
#include "ChollaEntity.hpp"
@@ -18,6 +20,7 @@
class CubitPoint;
class ChollaPoint;
class ChollaSurface;
+class ChollaVolume;
class FacetEntity;
class CurveFacetEvalTool;
@@ -35,15 +38,18 @@
int flag;
int blockID;
int id;
+ double myLength;
CubitStatus determine_ends();
//- determine the end nodes for the curve (once the curvEdgeList is full)
CubitFacetEdge *next_edge( CubitPoint *node_ptr, CubitFacetEdge *edge_ptr );
//- return the next edge on the curve (NULL if at end)
-
+
+
public:
+
ChollaCurve( int block_id );
//- default constructor
@@ -57,23 +63,43 @@
// delete the asociativity of this curve with all edge's tool datas
void add_facet(FacetEntity *exterior_edge)
- {curveEdgeList.append(exterior_edge);}
+ {myLength = MYLENGTH_UNINITIALIZED;
+ curveEdgeList.append(exterior_edge);}
//- add an edge to the curve
int add_facet_unique(FacetEntity *exterior_edge)
- {return curveEdgeList.append_unique(exterior_edge);}
+ {myLength = MYLENGTH_UNINITIALIZED;
+ return curveEdgeList.append_unique(exterior_edge);}
//- add an edge to this curve - check to see if it already there before adding
+ void remove_facet( FacetEntity *facet_edge )
+ {myLength = MYLENGTH_UNINITIALIZED;
+ curveEdgeList.remove( facet_edge ); }
+ //- remove a facet_edge from underlying backing
+
+ CubitStatus replace_facet( FacetEntity *remove_edge, FacetEntity *replace_edge );
+ //- replace a facet_edge from underlying backing
+
DLIList<FacetEntity*> &get_facet_list()
{return curveEdgeList;}
//- get the list of edges that make up this curve
DLIList<FacetEntity*> *get_facet_list_ptr()
{return &curveEdgeList;}
+
+ //- return the length of the curve
+ double length();
+
+ int num_edges() {return curveEdgeList.size();}
+ //- return the number of edges in the curve
void add_surface( ChollaSurface *fsm_ptr )
{surfaceList.append_unique( fsm_ptr );}
//- associate a surface with this curve
+ inline void remove_surface( ChollaSurface *fsm_ptr)
+ {surfaceList.remove(fsm_ptr);}
+ //- remove a suface from the curve
+
DLIList<ChollaSurface*> &get_surfaces()
{return surfaceList;}
void get_surfaces( DLIList<ChollaSurface *> &surf_list )
@@ -86,10 +112,23 @@
void add_point( ChollaPoint *fpm_ptr )
{pointList.append_unique( fpm_ptr );}
//- associate a point with this curve
+
+ inline void remove_point( ChollaPoint *fpm_ptr)
+ {pointList.remove(fpm_ptr);}
+ //- remove a point from the curve
DLIList<ChollaPoint*> &get_points()
{return pointList;}
//- get the list of points attached to this curve
+
+ void get_facet_points( DLIList<CubitPoint *> &point_list, CubitBoolean inclusive);
+ //- return the facet points on this chollacurve
+
+ CubitBoolean is_in_volume( ChollaVolume *chvol_ptr );
+ //- return whether this curve is contained within the specified volume
+
+ CubitBoolean is_in_surface( ChollaSurface *chsurf_ptr );
+ //- return whether this surface is contained within the specified surface
void assign_geometric_curve(void *curv)
{myCurve = curv;}
@@ -125,17 +164,44 @@
//- split this curve into multiple ChollaCurve where there are
//- discontinuous strings of edges. Define start end end points
//- for each curve while we are at it.
+
+ CubitStatus build_curve_from_edges(CubitPoint *start_point,
+ int periodic, int max_edges,
+ CubitFacetEdge *start_edge_ptr,
+ ChollaCurve *parent_curve);
CubitStatus feature_angle( double min_dot );
//- compute angles at nodes on the curve to see if we need to split
//- the curve. Mark the node tooldata hitflag if the node will
//- break the curve (this is refernced in next_edge)
+ // disassociate from cholla points
+ CubitStatus disassociate_from_points( void );
+
+ // disassociate from cholla surface
+ CubitStatus disassociate_from_surfaces( void);
+
+ // build a new curve_facet_eval_tool and assign it to ChollaCurve
+ CubitStatus build_curve_facet_eval_tool( void );
+
int get_flag( ) { return flag; }
void set_flag( int flg ) { flag = flg; }
int get_id() {return id;}
void debug_draw();
void print();
+
+ // find adjacent edges at a point that lie on the curve
+ bool adj_facet_edges( CubitPoint *cubit_pnt, CubitFacetEdge *&adj_edge1, CubitFacetEdge *&adj_edge2 );
+
+ // return whether the curve contains the point
+ CubitBoolean has_point( ChollaPoint *pt );
+
+ // verify that all points on this curve have this curve as an adjacency
+ CubitStatus verify_points();
+
+ // clear the edge list
+ void clean_out_edges(){curveEdgeList.clean_out();};
+
};
#endif
Modified: cgm/branches/cubit/geom/Cholla/ChollaEngine.cpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/ChollaEngine.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/ChollaEngine.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -3,12 +3,17 @@
//- Owner: Steven J. Owen
//- Checked by:
//- Version:
+//#include <list>
+#include <set>
+#include <map>
+#include <vector>
#include "CubitDefines.h"
#include "ChollaEngine.hpp"
#include "DLIList.hpp"
#include "TDGeomFacet.hpp"
#include "CastTo.hpp"
#include "ChollaSkinTool.hpp"
+#include "ChollaVolume.hpp"
#include "ChollaSurface.hpp"
#include "ChollaCurve.hpp"
#include "ChollaPoint.hpp"
@@ -20,6 +25,7 @@
#include "CubitPointData.hpp"
#include "FacetEntity.hpp"
#include "FacetEvalTool.hpp"
+#include "FacetDataUtil.hpp"
#include "debug.hpp"
#include "TDFacetBoundaryEdge.hpp"
#include "TDFacetBoundaryPoint.hpp"
@@ -77,6 +83,50 @@
}
//============================================================================
+//Function: ChollaEngine (PUBLIC) (constructor)
+//Notes: This case is used only when the cholla entities have been generated
+// directly rather than using create_geometry
+// Does not use the TDGeomFacet Tooldatas
+//============================================================================
+ChollaEngine::ChollaEngine(DLIList<CubitFacet*> &facet_list,
+ DLIList<CubitFacetEdge*> &edge_list,
+ DLIList<CubitPoint*> &point_list,
+ DLIList<ChollaVolume *> &cholla_volumes,
+ DLIList<ChollaSurface *> &cholla_surfaces,
+ DLIList<ChollaCurve *> &cholla_curves,
+ DLIList<ChollaPoint *> &cholla_points )
+{
+ CAST_LIST(facet_list, faceList, FacetEntity);
+ CAST_LIST(edge_list, edgeList, FacetEntity);
+ CAST_LIST(point_list, pointList, FacetEntity);
+ //set_up_tool_datas(); TDGeomFacet tooldatas should have already been added
+
+ hashCurveArray = NULL;
+ hashCurveSize = 0;
+ hashPointArray = NULL;
+ hashPointSize = 0;
+ doFlip = CUBIT_FALSE;
+
+ chollaVolumeList = cholla_volumes;
+ chollaSurfaceList = cholla_surfaces;
+ chollaCurveList = cholla_curves;
+ chollaPointList = cholla_points;
+
+ CubitBoolean use_feature_angle = CUBIT_FALSE;
+ double min_dot = 0.0;
+ int interp_order = 0;
+ CubitBoolean smooth_non_manifold = CUBIT_FALSE;
+ CubitBoolean split_surfaces = CUBIT_FALSE;
+
+ build_eval_tools(chollaSurfaceList,
+ chollaCurveList,
+ interp_order, use_feature_angle,
+ min_dot, smooth_non_manifold,
+ split_surfaces );
+}
+
+
+//============================================================================
//Function: set_up_tool_datas
//============================================================================
void ChollaEngine::set_up_tool_datas( )
@@ -368,7 +418,10 @@
}
// make a list of feature edges
-
+ rv = chsurf_ptr->add_preexisting_feature_edges( feature_edge_list );
+ if (rv != CUBIT_SUCCESS)
+ return rv;
+
if (use_feature_angle)
{
rv = chsurf_ptr->feature_angle( min_dot, feature_edge_list );
@@ -984,7 +1037,7 @@
CubitStatus stat = CUBIT_SUCCESS;
if (stat == CUBIT_SUCCESS)
- stat = build_surface_eval_tools( cholla_surface_list,
+ stat = build_surface_and_curve_eval_tools( cholla_surface_list,
interp_order, min_dot );
if (stat == CUBIT_SUCCESS)
stat = build_curve_eval_tools( cholla_curve_list, interp_order );
@@ -1051,10 +1104,11 @@
//Function: build_surface_eval_tools (PRIVATE)
//Description: From the facet surface list, create the FacetEvalTools
//===============================================================================
-CubitStatus ChollaEngine::build_surface_eval_tools(
+CubitStatus ChollaEngine::build_surface_and_curve_eval_tools(
DLIList<ChollaSurface*> &cholla_surface_list,
int interp_order,
- double min_dot )
+ double min_dot,
+ bool new_curv_tool)
{
CubitStatus stat = CUBIT_SUCCESS;
int ii, kk;
@@ -1069,6 +1123,7 @@
// now loop through surfaces and create them
+ int mydebug = 0;
for ( kk = cholla_surface_list.size(); kk > 0; kk-- )
{
ChollaSurface *chsurf_ptr = cholla_surface_list.get_and_step();
@@ -1090,7 +1145,7 @@
for (ii=0; ii<chcurv_list.size(); ii++)
{
ChollaCurve *chcurv_ptr = chcurv_list.get_and_step();
- if (chcurv_ptr->get_eval_tool() == NULL)
+ if (chcurv_ptr->get_eval_tool() == NULL || new_curv_tool)
{
CubitSense orientation_wrt_surface;
determine_curve_orientation( chsurf_ptr, chcurv_ptr, orientation_wrt_surface );
@@ -1123,6 +1178,7 @@
// orientation of the curve with respect to the surface
DLIList<FacetEntity*> facet_list = chcurv_ptr->get_facet_list();
+ facet_list.reset();
FacetEntity *facet_ptr = facet_list.get();
CubitFacetEdge *edge_ptr = CAST_TO( facet_ptr, CubitFacetEdge );
if (!edge_ptr)
@@ -1136,14 +1192,20 @@
int found = 0;int jj;
for ( jj = 0; jj < adj_face_list.size() && !found; jj++ )
{
- face_ptr = adj_face_list.get_and_step();
+ face_ptr = adj_face_list.get_and_step();
TDGeomFacet *td_gm_face = TDGeomFacet::get_geom_facet(face_ptr);
DLIList<ChollaSurface*> chsurf_list;
- td_gm_face->get_cholla_surfs( chsurf_list );
- ChollaSurface *face_chsurf_ptr = chsurf_list.get();
- if(face_chsurf_ptr == chsurf_ptr)
+ if(td_gm_face)
{
- found = 1;
+ td_gm_face->get_cholla_surfs( chsurf_list );
+ if (chsurf_list.size())
+ {
+ ChollaSurface *face_chsurf_ptr = chsurf_list.get();
+ if(face_chsurf_ptr == chsurf_ptr)
+ {
+ found = 1;
+ }
+ }
}
}
if (!found)
@@ -1154,8 +1216,10 @@
CubitPoint *start_ptr, *end_ptr;
chcurv_ptr->get_ends( start_ptr, end_ptr );
end_ptr = edge_ptr->other_point( start_ptr );
- if (end_ptr == NULL)
+ if (end_ptr == NULL)
+ {
return CUBIT_FAILURE; // the edge list may not be ordered correctly??
+ }
CubitPoint *points[3];
CubitFacet *tri_ptr = CAST_TO( face_ptr, CubitFacet );
tri_ptr->points( points[0], points[1], points[2] );
@@ -1604,6 +1668,13 @@
{
partner_point_ptr = partner_point_list.get_and_step();
td_partner = TDGeomFacet::get_geom_facet( partner_point_ptr );
+ //added mbrewer: the check for a pointer here shouldn't
+ // be necessary, but I have a case where it fails. I don't
+ // see where the logic is wrong.
+ if(!td_partner){
+ TDGeomFacet::add_geom_facet( partner_point_ptr , -1);
+ td_partner = TDGeomFacet::get_geom_facet( partner_point_ptr );
+ }
td_partner->add_partner_point( new_point_ptr );
td_new_point->add_partner_point( partner_point_ptr );
}
@@ -2532,7 +2603,7 @@
//Function: dump (PUBLIC)
//Description: debug
//===============================================================================
-void ChollaEngine::dump( char *filename, double angle )
+void ChollaEngine::dump( const char *filename, double angle )
{
int include_results = 0;
int num_face = faceList.size();
@@ -2611,14 +2682,12 @@
//===============================================================================
//Function: mark_features (PUBLIC)
-//Description: is subject to change, may be modified, placed somewhere else
-// added by Ved Vyas, 8-2003
+//Description: Calling this before ChollaEngine create geometry / topology
+// allows you to define features points. This can be used in conjunction
+// with the feature angle option or exclusively (original intention).
//===============================================================================
void ChollaEngine::mark_features (DLIList<CubitPoint*> &feature_points)
{
- // Calling this before ChollaEngine create geometry / topology
- // allows you to define features points. This can be used in conjunction
- // with the feature angle option or exclusively (original intention).
int ii;
TDGeomFacet *td_gm = NULL;
CubitPoint *curr_pt = NULL;
@@ -2635,6 +2704,28 @@
curr_pt->set_as_feature();
}
}
+
+//===============================================================================
+//Function: mark_features (PUBLIC)
+//Description: Calling this before ChollaEngine create geometry / topology
+// allows you to define features points. This can be used in conjunction
+// with the feature angle option or exclusively (original intention).
+//===============================================================================
+void ChollaEngine::mark_features (DLIList<CubitFacetEdge*> &feature_edges)
+{
+ int ii;
+ CubitFacetEdge *curr_edge = NULL;
+
+ // loop through supplied CubitFaceEdge*
+ // set the hit flag on each one
+
+ for (ii=0; ii < feature_edges.size(); ++ii)
+ {
+ curr_edge = feature_edges.get_and_step();
+ curr_edge->set_as_feature();
+ }
+}
+
static CubitStatus create_tri_facets(int *face_list,int current_position,
CubitPoint **point_list,
@@ -2709,9 +2800,16 @@
}
return CUBIT_SUCCESS;
}
-
+
+//===================================================================================
+// Description: given facets in the form of a GMem data structure create new
+// CubitFacet and CubitPoint classes and return in lists
+// Notes:
+// Author:
+// Date:
+//===================================================================================
CubitStatus ChollaEngine::get_facets(GMem& gMem, DLIList<CubitFacet*> &facet_list,
- DLIList<CubitPoint*> &dl_point_list)
+ DLIList<CubitPoint*> &dl_point_list)
{
if(gMem.fListCount == 0)
return CUBIT_FAILURE;
@@ -2782,5 +2880,1256 @@
return CUBIT_SUCCESS;
}
+//=============================================================================
+//Function: collapses a given curve to a given point_to_keep
+//
+//Description:
+//Note: the hashing and other data structures are not updated during collapse.
+//Author: william roshan quadros
+//Date: 12/15/08
+//=============================================================================
+CubitStatus ChollaEngine::collapse_curve( ChollaCurve *cholla_curve, ChollaPoint *point_to_keep )
+{
+ // Make sure there are no underlying facet edges connected with this curve
+ if( cholla_curve->get_facet_list().size() )
+ return CUBIT_FAILURE;
+
+ // Disassociate from cholla_surfaces
+ DLIList<ChollaSurface *> &ref_surfaces = cholla_curve->get_surfaces();
+ int i;
+ ChollaSurface *cholla_surface;
+ for( i = 0; i < ref_surfaces.size(); i++ )
+ {
+ cholla_surface = ref_surfaces.get_and_step();
+ cholla_surface->remove_curve( cholla_curve );
+ }
+ ref_surfaces.clean_out();
+ // Disassociate from cholla point_to_delete
+ // Make sure curve has at least one point
+ DLIList<ChollaPoint *> &cholla_pnts = cholla_curve->get_points();
+ if( 0 == cholla_pnts.size() )
+ return CUBIT_FAILURE;
+ // free eval tool
+ if( cholla_curve->get_eval_tool() )
+ {
+ delete cholla_curve->get_eval_tool();
+ }
+
+ // find the point to delete
+ ChollaPoint *first_pnt = cholla_pnts.get_and_step();
+ ChollaPoint *last_pnt = cholla_pnts.get();
+ ChollaPoint *point_to_del = NULL;
+ switch( cholla_pnts.size() )
+ {
+
+ case 2:
+ if( point_to_keep == last_pnt )
+ {
+ point_to_del = first_pnt;
+ }
+ else
+ {
+ if( point_to_keep == first_pnt )
+ {
+ point_to_del = last_pnt;
+ }
+ }
+
+ // disassociate end points from cholla_curve
+ if( point_to_del )
+ {
+ point_to_del->remove_curve( cholla_curve );
+ cholla_pnts.remove( point_to_del );
+ }
+ if( point_to_keep )
+ {
+ point_to_keep->remove_curve( cholla_curve );
+ cholla_pnts.remove( point_to_keep );
+ }
+
+ // Merge two points
+ merge_two_points( point_to_keep, point_to_del );
+
+ break;
+
+ case 1:
+ // disassociate end points from cholla_curve
+ point_to_del = first_pnt;
+ point_to_del->remove_curve( cholla_curve );
+ cholla_pnts.remove( point_to_del );
+
+ if( 0 == point_to_del->get_curve_list_ptr()->size() )
+ {
+ // remove point_to_del from ChollaEngine
+ remove_point( point_to_del );
+
+ // free point_to_del
+ delete point_to_del;
+ }
+ break;
+
+ default:
+ return CUBIT_FAILURE;
+ }
+
+
+ // Disassociate curve from chollaEngine
+ this->remove_curve( cholla_curve );
+
+ // free the cholla_curve
+ delete cholla_curve;
+
+ return CUBIT_SUCCESS;
+}
+
+ // Merge two points
+CubitStatus ChollaEngine::merge_two_points( ChollaPoint *point_to_keep, ChollaPoint *point_to_del )
+{
+ // move cholla curves from point_to_del to point_to_keep
+ DLIList<ChollaCurve *> &del_pnt_curves = point_to_del->get_curves();
+ int i;
+ ChollaCurve *cholla_curve;
+ for( i = 0; i < del_pnt_curves.size(); i++ )
+ {
+ cholla_curve = del_pnt_curves.get_and_step();
+
+ cholla_curve->remove_point( point_to_del );
+ cholla_curve->add_point( point_to_keep );
+ point_to_keep->add_curve( cholla_curve );
+ }
+ del_pnt_curves.clean_out();
+
+ // if point_to_keep facet is null use point_to_del's facet
+ if( NULL == point_to_keep->get_facets() && point_to_del->get_facets() )
+ {
+ point_to_keep->add_facet( point_to_del->get_facets() );
+ }
+
+ // what we should do with data member id? should we move if point_to_keep->get_id() != 0?
+
+ // remove point_to_del from ChollaEngine
+ remove_point( point_to_del );
+
+ // free point_to_del
+ delete point_to_del;
+
+ return CUBIT_SUCCESS;
+}
+
+
+
+CubitStatus ChollaEngine::disassociate_surface( ChollaSurface *cholla_surf )
+{
+ // remove surface from volume
+ DLIList<ChollaVolume *> cholla_volumes;
+ cholla_surf->get_volumes(cholla_volumes);
+ int i;
+ ChollaVolume *cholla_volume;
+ for (i=0; i<cholla_volumes.size(); i++)
+ {
+ cholla_volume = cholla_volumes.get_and_step();
+ cholla_volume->remove_surface( cholla_surf );
+ }
+
+ // Disassociate curves from suface
+ DLIList< ChollaCurve *> cholla_curves;
+ cholla_surf->get_curves( cholla_curves );
+
+ ChollaCurve *cholla_curve;
+ for( i = 0; i < cholla_curves.size(); i++ )
+ {
+ cholla_curve = cholla_curves.get_and_step();
+
+ cholla_curve->remove_surface( cholla_surf );
+ cholla_surf->remove_curve( cholla_curve );
+ }
+ cholla_curves.clean_out();
+
+ // Remove facet tool if available ?
+ if( cholla_surf->get_eval_tool() )
+ {
+#ifdef _DEBUG
+ PRINT_INFO("WARNING: delete ch_surf->facet_eval_tool safely \n");//
+#endif
+ //delete cholla_surf->get_eval_tool();
+ // set eval tool to NULL
+ }
+
+ // remove from ChollaEngine
+ remove_surface( cholla_surf );
+
+ return CUBIT_SUCCESS;
+
+}
+//=============================================================================
+//Function: collapses a given surface
+//Description: currently it disassociates surface with its curves and ChollaEngine
+//Note: make sure there are no underlying facets and model is automatically watertight when input cholla_surf is deleted
+//Author: william roshan quadros
+//Date: 12/15/08
+//=============================================================================
+
+CubitStatus ChollaEngine::collapse_surface( ChollaSurface *cholla_surf )
+{
+ // Make sure there are no facets
+ if( cholla_surf->get_facet_list().size() )
+ return CUBIT_FAILURE;
+
+ disassociate_surface( cholla_surf );
+
+ // free cholla surface
+ delete cholla_surf;
+
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus ChollaEngine::remove_facet_entity( CubitFacet *facet, ChollaSurface *cholla_surf )
+{
+ this->faceList.remove( facet );
+
+ if( cholla_surf )
+ cholla_surf->remove_facet( facet );
+
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus ChollaEngine::remove_facet_entity( CubitFacetEdge *facet_edge, ChollaCurve *cholla_curve )
+{
+ this->edgeList.remove( facet_edge );
+
+ if( cholla_curve )
+ cholla_curve->remove_facet( facet_edge );
+
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus ChollaEngine::remove_facet_entity( CubitPoint *facet_pnt, ChollaPoint *cholla_point )
+{
+ this->pointList.remove( facet_pnt );
+
+ if( cholla_point )
+ cholla_point->remove_facet(/* facet_pnt */);
+
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus ChollaEngine::remove_facet_entity( CubitFacet *facet, std::set<ChollaEntity *> &cholla_surfs )
+{
+ std::set<ChollaEntity *>::iterator set_it;
+ for( set_it = cholla_surfs.begin(); set_it != cholla_surfs.end(); set_it++ )
+ {
+ if( dynamic_cast< ChollaSurface *>(*set_it) )
+ {
+ static_cast<ChollaSurface *>(*set_it)->remove_facet( facet );
+ }
+ }
+
+ this->faceList.remove( facet );
+
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus ChollaEngine::remove_facet_entity( CubitFacetEdge *facet_edge, std::set<ChollaEntity *> &cholla_curves )
+{
+
+ std::set<ChollaEntity *>::iterator set_it;
+ ChollaEntity *ptr_entity;
+ ChollaCurve *ptr_curve;
+ for( set_it = cholla_curves.begin(); set_it != cholla_curves.end(); set_it++ )
+ {
+ ptr_entity = *set_it;
+ ptr_curve = dynamic_cast<ChollaCurve *>( ptr_entity );
+ if( dynamic_cast<ChollaCurve*>(*set_it) )
+ {
+ dynamic_cast<ChollaCurve*>(*set_it)->remove_facet( facet_edge );
+ }
+ }
+
+ this->edgeList.remove( facet_edge );
+
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus ChollaEngine::replace_facet_entity( CubitFacetEdge *remove_edge, CubitFacetEdge *replace_edge, std::set<ChollaEntity *> cholla_curves )
+{
+ std::set<ChollaEntity *>::iterator set_it;
+ for( set_it = cholla_curves.begin(); set_it != cholla_curves.end(); set_it++ )
+ {
+ if( dynamic_cast<ChollaCurve*>(*set_it) )
+ {
+ static_cast<ChollaCurve*>(*set_it)->replace_facet( remove_edge, replace_edge );
+ }
+ }
+
+ return CUBIT_SUCCESS;
+}
+
+
+CubitStatus ChollaEngine::remove_facet_entity( CubitPoint *facet_pnt, std::set<ChollaEntity *> &cholla_points )
+{
+ this->pointList.remove( facet_pnt );
+
+ std::set<ChollaEntity *>::iterator set_it;
+ for( set_it = cholla_points.begin(); set_it != cholla_points.end(); set_it++ )
+ {
+ if( dynamic_cast<ChollaPoint*>(*set_it) )
+ {
+ static_cast<ChollaPoint*>(*set_it)->remove_facet( facet_pnt );
+ }
+ }
+
+ return CUBIT_SUCCESS;
+}
+
+/*
+// disassoicate ch_entity from ch_points, ch_curve, ch_surf, and ch_engine
+CubitStatus ChollaEngine::disassociate_curve( ChollaCurve *ch_curve )
+{
+
+ // disassociate from cholla points
+ ch_curve->disassociate_from_points();
+
+ // disassociate from cholla surface
+ ch_curve->disassociate_from_surfaces();
+
+ // disassociate from cholla engine
+ remove_curve( ch_curve );
+
+ return CUBIT_SUCCESS;
+}
+*/
+
+CubitStatus ChollaEngine::create_surface( int block_id,
+ ChollaSurface *&new_ch_surf )
+{
+ new_ch_surf = new ChollaSurface( block_id );
+
+ // add it to cholla engine
+ chollaSurfaceList.append( new_ch_surf );
+
+ return CUBIT_SUCCESS;
+}
+
+ // Create new ch_curve and associate with end ch_points. Add ch_curve to chollaEngine
+CubitStatus ChollaEngine::create_curve(int block_id,
+ ChollaPoint *new_ch_pnt0,
+ ChollaPoint *new_ch_pnt1,
+ ChollaCurve *&new_ch_curve
+ )
+{
+
+
+ new_ch_curve = new ChollaCurve( block_id );
+
+ // associate with cholla points
+ new_ch_curve->add_point( new_ch_pnt0 );
+ new_ch_pnt0->add_curve( new_ch_curve );
+ new_ch_curve->add_point( new_ch_pnt1 );
+ new_ch_pnt1->add_curve( new_ch_curve );
+
+
+ // update start and end facet points
+ new_ch_curve->set_start( CAST_TO( new_ch_pnt0->get_facets(), CubitPointData) );
+ new_ch_curve->set_end( CAST_TO( new_ch_pnt1->get_facets(), CubitPointData) );
+
+ // add it to cholla engine
+ chollaCurveList.append( new_ch_curve );
+
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus ChollaEngine::create_point( CubitPoint *pnt, ChollaPoint * &new_ch_pnt )
+{
+ new_ch_pnt = new ChollaPoint();
+ new_ch_pnt->add_facet( pnt );
+ double *coordinate = new double[3];
+ CubitVector coord_vect = pnt->coordinates();
+ coordinate[0] = coord_vect[0];
+ coordinate[1] = coord_vect[1];
+ coordinate[2] = coord_vect[2];
+ new_ch_pnt->assign_geometric_point( (void*) coordinate );
+
+ return CUBIT_SUCCESS;
+}
+
+
+// disassoicate ch_curve from ch_points, ch_surfs, and ch_engine
+CubitStatus ChollaEngine::disassociate_curve( ChollaCurve *ch_curve, bool disassociate_with_vert, bool disassociate_with_surf, bool disassociate_with_model )
+{
+ // remove ch_curve from ch_point
+ int i;
+ if( disassociate_with_vert )
+ {
+ for( i = 0; i < ch_curve->get_points().size(); i++ )
+ {
+ ch_curve->get_points().get_and_step()->remove_curve( ch_curve );
+ }
+ // remove ch_points
+ ch_curve->get_points().clean_out();
+ }
+
+ if( disassociate_with_surf )
+ {
+ // remove ch_curve in ch_surface
+ ChollaSurface *ptr_ch_surf;
+ for( i = 0; i < ch_curve->get_surfaces().size(); i++ )
+ {
+ ptr_ch_surf = ch_curve->get_surfaces().get_and_step();
+ ptr_ch_surf->remove_curve( ch_curve );
+ }
+ // remove ch_surface
+ ch_curve->get_surfaces().clean_out();
+ }
+
+ if( disassociate_with_model )
+ {
+ // remove from ch_engie
+ this->remove_curve( ch_curve );
+ }
+
+ return CUBIT_SUCCESS;
+}
+
+//=============================================================================
+//Function: detach_volumes
+//Description: Create independent manifold volumes from the non-manifold set
+//Note:
+//Author:sjowen
+//Date: 09/10/09
+//=============================================================================
+CubitStatus ChollaEngine::detach_volumes()
+{
+ CubitStatus rv = CUBIT_SUCCESS;
+
+ // define maps between the original entities and their copies so we can
+ // use them for detaching the facets
+
+ std::map<ChollaSurface *, ChollaSurface *> surf_map;
+ std::map<ChollaCurve *, ChollaCurve *> curve_map;
+ std::map<ChollaPoint *, ChollaPoint *> point_map;
+
+ for (int isurf=0; isurf<chollaSurfaceList.size(); isurf++)
+ {
+ ChollaSurface *chsurf_ptr = chollaSurfaceList.get_and_step();
+
+ // look for any surfaces that are associated with exactly two volumes
+
+ if (chsurf_ptr->num_volumes() == 2)
+ {
+ rv = detach_surface( chsurf_ptr, surf_map, curve_map, point_map );
+ if (rv != CUBIT_SUCCESS)
+ return CUBIT_FAILURE;
+ }
+ }
+
+ // create the evaluation tools on the new entities
+
+ CubitBoolean use_feature_angle = CUBIT_FALSE;
+ double min_dot = 0.0;
+ int interp_order = 0;
+ CubitBoolean smooth_non_manifold = CUBIT_FALSE;
+ CubitBoolean split_surfaces = CUBIT_FALSE;
+ DLIList<ChollaSurface *> cholla_surfaces;
+ DLIList<ChollaCurve *> cholla_curves;
+
+ // get lists of new surfaces and curves from the maps
+
+ std::map<ChollaSurface *, ChollaSurface *>::iterator smap_it;
+ for (smap_it=surf_map.begin(); smap_it != surf_map.end(); smap_it++)
+ {
+ cholla_surfaces.append(smap_it->second);
+ }
+
+ std::map<ChollaCurve *, ChollaCurve *>::iterator cmap_it;
+ for (cmap_it=curve_map.begin(); cmap_it != curve_map.end(); cmap_it++)
+ {
+ cholla_curves.append(cmap_it->second);
+ }
+
+ // rebuild the new curves so the edges are oriented correctly
+
+ for (int ii=0; ii<cholla_curves.size(); ii++)
+ {
+ ChollaCurve *cholla_curve = cholla_curves.get_and_step();
+ DLIList<ChollaPoint *> cholla_points = cholla_curve->get_points();
+ int periodic = 0;
+ if (cholla_points.size() == 1)
+ periodic = 1;
+ else
+ assert(cholla_points.size() == 2); // assuming we have exactly two end points so far
+ CubitPoint *start_point, *end_point;
+ cholla_curve->get_ends(start_point, end_point);
+ int max_edges = cholla_curve->num_edges();
+ cholla_curve->clean_out_edges(); // edges will be added in build_curve_from_edges
+ rv = cholla_curve->build_curve_from_edges( start_point, periodic, max_edges, NULL, cholla_curve );
+ if (rv != CUBIT_SUCCESS)
+ return rv;
+ }
+
+ // replace the facets on the existing eval tools on the curves and surfaces bounding the interface.
+ // for simplicity, just replace them on all the existing eval tools on
+
+ for (int icurv = 0; icurv < chollaCurveList.size(); icurv++)
+ {
+ ChollaCurve *chcurv_ptr = chollaCurveList.get_and_step();
+ CurveFacetEvalTool *ceval = chcurv_ptr->get_eval_tool();
+ if (ceval != NULL)
+ {
+ DLIList<FacetEntity *> fedges = chcurv_ptr->get_facet_list();
+ DLIList<CubitFacetEdge *> edges;
+ CAST_LIST( fedges, edges, CubitFacetEdge );
+ ceval->replace_facets(edges);
+ }
+ }
+
+ for (int isurf=0; isurf<chollaSurfaceList.size(); isurf++)
+ {
+ ChollaSurface *chsurf_ptr = chollaSurfaceList.get_and_step();
+ FacetEvalTool *seval = chsurf_ptr->get_eval_tool();
+ if (seval != NULL)
+ {
+ DLIList<FacetEntity *> ffacets = chsurf_ptr->get_facet_list();
+ DLIList<CubitFacet *> facets;
+ CAST_LIST( ffacets, facets, CubitFacet );
+ seval->replace_facets(facets);
+ }
+ }
+
+ // build the eval tools
+
+ rv = build_eval_tools(cholla_surfaces,
+ cholla_curves,
+ interp_order, use_feature_angle,
+ min_dot, smooth_non_manifold,
+ split_surfaces );
+
+ return rv;
+}
+
+//=============================================================================
+//Function: detach_surface
+//Description: given a non-manifold surface in a cholla model, create a copy
+// and update child entities
+//Notes: assumes that chsurf_ptr has exactly 2 adjacent volumes
+//Author:sjowen
+//Date: 09/18/09
+//=============================================================================
+CubitStatus ChollaEngine::detach_surface(ChollaSurface *chsurf_ptr,
+ std::map<ChollaSurface *, ChollaSurface *> &surf_map,
+ std::map<ChollaCurve *, ChollaCurve *> &curve_map,
+ std::map<ChollaPoint *, ChollaPoint *> &point_map)
+{
+ CubitStatus rv = CUBIT_SUCCESS;
+ DLIList<ChollaVolume *> chvol_list;
+
+ // detach the surface from its volumes
+
+ chsurf_ptr->get_volumes(chvol_list);
+ ChollaVolume *chvol1_ptr = chvol_list.get_and_step();
+ assert(chvol1_ptr != NULL);
+ ChollaVolume *chvol2_ptr = chvol_list.get();
+ assert(chvol2_ptr != NULL);
+ assert(chvol1_ptr != chvol2_ptr);
+
+ // create a copy of the non-manifold surface and attach it to volume 2
+
+ ChollaSurface *newchsurf_ptr = new ChollaSurface( chsurf_ptr->get_block_id() );
+ chollaSurfaceList.append(newchsurf_ptr);
+ surf_map.insert(std::pair<ChollaSurface *, ChollaSurface *>(chsurf_ptr, newchsurf_ptr));
+
+ chvol2_ptr->remove_surface(chsurf_ptr);
+ chsurf_ptr->remove_volume(chvol2_ptr);
+ chvol2_ptr->add_surface(newchsurf_ptr);
+ newchsurf_ptr->add_volume(chvol2_ptr);
+
+ chsurf_ptr->set_merge_partner(newchsurf_ptr);
+ newchsurf_ptr->set_merge_partner(chsurf_ptr);
+
+ // detach the curves
+
+ DLIList<ChollaCurve *> chcurv_list;
+ chsurf_ptr->get_curves(chcurv_list);
+ for(int icurv = 0; icurv < chcurv_list.size(); icurv++)
+ {
+ ChollaCurve *chcurv_ptr = chcurv_list.get_and_step();
+ rv = detach_curve( chcurv_ptr, newchsurf_ptr, chvol2_ptr, curve_map );
+ if (rv != CUBIT_SUCCESS)
+ return rv;
+ }
+
+ // detach the chollapoints
+
+ DLIList<ChollaPoint *> chpt_list;
+ chsurf_ptr->get_vertices( chpt_list );
+ for (int ipt = 0; ipt < chpt_list.size(); ipt++)
+ {
+ ChollaPoint *chpt_ptr = chpt_list.get_and_step();
+
+ rv = detach_point( chpt_ptr, chvol2_ptr, curve_map, point_map );
+ if (rv != CUBIT_SUCCESS)
+ return rv;
+ }
+
+ // create new facets for the new surface and detach vol 1 facets from vol 2 facets
+
+ rv = detach_facets(chsurf_ptr, chvol2_ptr, surf_map, curve_map, point_map);
+ if (rv != CUBIT_SUCCESS)
+ return rv;
+
+ // set the cubitpoints at the correct start/end locations on the cholla curves
+
+ rv = set_curve_endpoints(chsurf_ptr, newchsurf_ptr, curve_map, point_map);
+ if (rv != CUBIT_SUCCESS)
+ return rv;
+
+ return rv;
+}
+
+//=============================================================================
+//Function: detach_curve
+//Description: given a non-manifold curve in a cholla model, create a copy
+// and update child entities. updates the curve_map
+//Author:sjowen
+//Date: 09/18/09
+//=============================================================================
+CubitStatus ChollaEngine::detach_curve(ChollaCurve *chcurv_ptr,
+ ChollaSurface *newchsurf_ptr,
+ ChollaVolume *chvol2_ptr,
+ std::map<ChollaCurve *, ChollaCurve *> &curve_map)
+{
+
+ // create a copy of the curve on the surface and add it to volume 2
+
+ ChollaCurve *newchcurv_ptr = new ChollaCurve( chcurv_ptr->get_block_id() );
+ chollaCurveList.append( newchcurv_ptr );
+ curve_map.insert(std::pair<ChollaCurve *, ChollaCurve *>(chcurv_ptr, newchcurv_ptr));
+ newchsurf_ptr->add_curve(newchcurv_ptr);
+ newchcurv_ptr->add_surface(newchsurf_ptr);
+
+ // any surfaces attached to this chcurv that are in vol2 are removed and the newchcurv is added
+
+ DLIList<ChollaSurface *> chcsurf_list = chcurv_ptr->get_surfaces();
+ for (int icsurf = 0; icsurf < chcsurf_list.size(); icsurf++)
+ {
+ ChollaSurface *chcsurf_ptr = chcsurf_list.get_and_step();
+ if (chcsurf_ptr->is_in_volume(chvol2_ptr))
+ {
+ chcurv_ptr->remove_surface(chcsurf_ptr);
+ chcsurf_ptr->remove_curve(chcurv_ptr);
+ newchcurv_ptr->add_surface(chcsurf_ptr);
+ chcsurf_ptr->add_curve(newchcurv_ptr);
+ }
+ }
+ return CUBIT_SUCCESS;
+}
+
+//=============================================================================
+//Function: detach_point
+//Description: given a non-manifold point in a cholla model, create a copy
+// and update connectivity. updates the point_map
+//Author:sjowen
+//Date: 09/18/09
+//=============================================================================
+CubitStatus ChollaEngine::detach_point(ChollaPoint *chpt_ptr,
+ ChollaVolume *chvol2_ptr,
+ std::map<ChollaCurve *, ChollaCurve *> &curve_map,
+ std::map<ChollaPoint *, ChollaPoint *> &point_map)
+{
+ // create a copy of the chollapoint on the interface surface
+
+ ChollaPoint *newchpt_ptr = new ChollaPoint ();
+ chollaPointList.append( newchpt_ptr );
+ point_map.insert(std::pair<ChollaPoint *, ChollaPoint *>(chpt_ptr, newchpt_ptr));
+
+ DLIList<ChollaCurve *> chptcurv_list = chpt_ptr->get_curves();
+ for (int iptcurv = 0; iptcurv < chptcurv_list.size(); iptcurv++)
+ {
+ ChollaCurve *chptcurv_ptr = chptcurv_list.get_and_step();
+
+ // for curves that were copied (on the interface), add the new chollapoint to the new curve
+
+ std::map<ChollaCurve *, ChollaCurve *>::iterator cmap_it;
+ cmap_it = curve_map.find(chptcurv_ptr);
+ if (cmap_it != curve_map.end())
+ {
+ ChollaCurve *newchcurv_ptr = cmap_it->second;
+ newchcurv_ptr->add_point(newchpt_ptr);
+ newchpt_ptr->add_curve(newchcurv_ptr);
+ }
+ else
+ {
+ // remove curve in vol 2 (not on interface) from the original point and add it to the new point
+
+ if (chptcurv_ptr->is_in_volume(chvol2_ptr))
+ {
+ chpt_ptr->remove_curve(chptcurv_ptr);
+ chptcurv_ptr->remove_point(chpt_ptr);
+ newchpt_ptr->add_curve(chptcurv_ptr);
+ chptcurv_ptr->add_point(newchpt_ptr);
+ }
+ }
+ }
+ return CUBIT_SUCCESS;
+}
+
+
+//=============================================================================
+//Function: detach_facets
+//Description: detach the individual facets to create a manifold representation
+//Note: makes a copy of the facets on the merged surface and its child entities
+// and reconnects them locally
+//Author:sjowen
+//Date: 09/10/09
+//=============================================================================
+CubitStatus ChollaEngine::detach_facets(ChollaSurface *chsurf_ptr, ChollaVolume *chvol_ptr,
+ std::map<ChollaSurface *, ChollaSurface *> &surf_map,
+ std::map<ChollaCurve *, ChollaCurve *> &curve_map,
+ std::map<ChollaPoint *, ChollaPoint *> &point_map)
+{
+
+ CubitStatus rv = CUBIT_SUCCESS;
+
+ std::vector<CubitPoint *> new_points;
+ std::vector<CubitFacetEdge *> new_edges;
+
+ rv = copy_facets_at_interface( chsurf_ptr, new_points, new_edges,
+ surf_map, curve_map, point_map );
+ if (rv != CUBIT_SUCCESS)
+ return rv;
+
+ rv = connect_facets_at_interface( chsurf_ptr, chvol_ptr, new_points, new_edges );
+ if (rv != CUBIT_SUCCESS)
+ return rv;
+
+ return rv;
+}
+
+//=============================================================================
+//Function: copy_facets_at_interface
+//Description:
+//Author:sjowen
+//Date: 09/18/09
+//=============================================================================
+CubitStatus ChollaEngine::copy_facets_at_interface(ChollaSurface *chsurf_ptr,
+ std::vector<CubitPoint *> &new_points,
+ std::vector<CubitFacetEdge *> &new_edges,
+ std::map<ChollaSurface *, ChollaSurface *> &surf_map,
+ std::map<ChollaCurve *, ChollaCurve *> &curve_map,
+ std::map<ChollaPoint *, ChollaPoint *> &point_map)
+
+{
+ CubitStatus rv = CUBIT_SUCCESS;
+
+ // first set the marked flags on all facets entities on this surface to -1
+
+ int ifacet;
+ DLIList<FacetEntity *> facet_list;
+ chsurf_ptr->get_facets( facet_list );
+ FacetDataUtil::mark_facets(facet_list, FACET_ENTITY_UNINITIALIZED);
+
+ // create a copy of each of the facet entities on the surface. The marked flag in the facet will
+ // keep track of the new entity created. It will be a location in the new_points or new_edges
+ // array. Once we are finished with creating points and edges, we can create the new facets
+ // given the references in the marked flags.
+
+ // create new points
+
+ rv = copy_points_at_interface(facet_list, new_points, surf_map, curve_map, point_map);
+ if (rv != CUBIT_SUCCESS)
+ return rv;
+
+ // create new edges
+
+ rv = copy_edges_at_interface(facet_list, new_points, new_edges, surf_map, curve_map, point_map);
+ if (rv != CUBIT_SUCCESS)
+ return rv;
+
+ // create new facets
+
+ DLIList<CubitFacet *> new_facets;
+ for (ifacet = 0; ifacet<facet_list.size(); ifacet++)
+ {
+ FacetEntity *facet_ptr = facet_list.get_and_step();
+ CubitFacet *cfacet_ptr = dynamic_cast<CubitFacet *> (facet_ptr);
+ CubitFacetEdge *fedge, *newfedges[3];
+ CubitFacet *newcfacet_ptr;
+ for (int ii=0; ii<3; ii++)
+ {
+ fedge = cfacet_ptr->edge(ii);
+ int idx = fedge->marked();
+ newfedges[ii] = new_edges[idx];
+ }
+ newcfacet_ptr = (CubitFacet *) new CubitFacetData(newfedges[0], newfedges[1], newfedges[2]);
+ new_facets.append( newcfacet_ptr );
+ FacetEntity *newfacet_ptr = dynamic_cast<FacetEntity *> (newcfacet_ptr);
+ set_new_facet_owners( 2, facet_ptr, newfacet_ptr, surf_map, curve_map, point_map );
+ }
+
+ // make sure facets are oriented consistently on new volume
+
+ CubitFacet *start_facet = new_facets.get();
+ CubitBoolean do_flip = CUBIT_TRUE;
+ int nfacets;
+ int mydebug = 0;
+ rv = check_facet_orientation(start_facet, do_flip, nfacets, mydebug );
+
+ return rv;
+}
+
+//=============================================================================
+//Function: copy_points_at_interface
+//Description: copy the points at the interface
+//Author:sjowen
+//Date: 09/18/09
+//=============================================================================
+CubitStatus ChollaEngine::copy_points_at_interface(DLIList<FacetEntity *> &facet_list,
+ std::vector<CubitPoint *> &new_points,
+ std::map<ChollaSurface *, ChollaSurface *> &surf_map,
+ std::map<ChollaCurve *, ChollaCurve *> &curve_map,
+ std::map<ChollaPoint *, ChollaPoint *> &point_map)
+{
+ int iploc = 0;
+
+ FacetEntity *fe_ptr, *newfe_ptr;
+ for (int ifacet = 0; ifacet<facet_list.size(); ifacet++)
+ {
+ FacetEntity *facet_ptr = facet_list.get_and_step();
+ CubitFacet *cfacet_ptr = dynamic_cast<CubitFacet *> (facet_ptr);
+ CubitPoint *point_ptr, *newpoint_ptr;
+ for (int ii=0; ii<3; ii++)
+ {
+ point_ptr = cfacet_ptr->point(ii);
+ if (point_ptr->marked() == FACET_ENTITY_UNINITIALIZED)
+ {
+ newpoint_ptr = (CubitPoint *) new CubitPointData( point_ptr->x(), point_ptr->y(), point_ptr->z() );
+ new_points.push_back(newpoint_ptr);
+ point_ptr->marked(iploc++);
+ fe_ptr = dynamic_cast<FacetEntity *> (point_ptr);
+ newfe_ptr = dynamic_cast<FacetEntity *> (newpoint_ptr);
+ set_new_facet_owners(0, fe_ptr, newfe_ptr, surf_map, curve_map, point_map );
+ }
+ }
+ }
+
+ return CUBIT_SUCCESS;
+}
+
+//=============================================================================
+//Function: copy_edges_at_interface
+//Description: copy the edges at the interface
+//Author:sjowen
+//Date: 09/18/09
+//=============================================================================
+CubitStatus ChollaEngine::copy_edges_at_interface(DLIList<FacetEntity *> &facet_list,
+ std::vector<CubitPoint *> &new_points,
+ std::vector<CubitFacetEdge *> &new_edges,
+ std::map<ChollaSurface *, ChollaSurface *> &surf_map,
+ std::map<ChollaCurve *, ChollaCurve *> &curve_map,
+ std::map<ChollaPoint *, ChollaPoint *> &point_map)
+{
+ int ieloc = 0;
+ for (int ifacet = 0; ifacet<facet_list.size(); ifacet++)
+ {
+ FacetEntity *facet_ptr = facet_list.get_and_step();
+ CubitFacet *cfacet_ptr = dynamic_cast<CubitFacet *> (facet_ptr);
+ CubitFacetEdge *edge_ptr, *newedge_ptr;
+ for (int ii=0; ii<3; ii++)
+ {
+ edge_ptr = cfacet_ptr->edge(ii);
+ if (edge_ptr->marked() == FACET_ENTITY_UNINITIALIZED)
+ {
+ CubitPoint *p0 = edge_ptr->point( 0 );
+ CubitPoint *p1 = edge_ptr->point( 1 );
+ int idx0 = p0->marked();
+ int idx1 = p1->marked();
+ CubitPoint *newp0 = new_points[idx0];
+ CubitPoint *newp1 = new_points[idx1];
+ newedge_ptr = (CubitFacetEdge *) new CubitFacetEdgeData( newp0, newp1 );
+ new_edges.push_back(newedge_ptr);
+ edge_ptr->marked(ieloc++);
+ FacetEntity *fe_ptr = dynamic_cast<FacetEntity *> (edge_ptr);
+ FacetEntity *newfe_ptr = dynamic_cast<FacetEntity *> (newedge_ptr);
+ set_new_facet_owners( 1, fe_ptr, newfe_ptr, surf_map, curve_map, point_map );
+ }
+ }
+ }
+ return CUBIT_SUCCESS;
+}
+
+//=============================================================================
+//Function: connect_facets_at_interface
+//Description: detach the facets from original points and edges and reattach to new copy
+//Author:sjowen
+//Date: 09/18/09
+//=============================================================================
+CubitStatus ChollaEngine::connect_facets_at_interface(ChollaSurface *chsurf_ptr,
+ ChollaVolume *chvol_ptr,
+ std::vector<CubitPoint *> &new_points,
+ std::vector<CubitFacetEdge *> &new_edges)
+{
+ CubitStatus rv = CUBIT_SUCCESS;
+
+ DLIList<ChollaCurve *> chcurv_list;
+ chsurf_ptr->get_curves(chcurv_list);
+ for (int icrv = 0; icrv < chcurv_list.size(); icrv++)
+ {
+ ChollaCurve *chcurv_ptr = chcurv_list.get_and_step();
+
+ rv = connect_points_at_interface( chcurv_ptr, chvol_ptr, new_points );
+ if (rv != CUBIT_SUCCESS)
+ return rv;
+
+ rv = connect_edges_at_interface( chcurv_ptr, chvol_ptr, new_edges );
+ if (rv != CUBIT_SUCCESS)
+ return rv;
+ }
+
+ return rv;
+}
+
+//=============================================================================
+//Function: connect_points_at_interface
+//Description: detach the facet points from original facets and reattach to new copy
+//Notes: chcurv_ptr is a curve at the interface on the original volume
+// chvol_ptr is the second volume (new (copied) entities belong to vol 2)
+// new_points is a list of new points on vol 2
+//Author:sjowen
+//Date: 09/18/09
+//=============================================================================
+CubitStatus ChollaEngine::connect_points_at_interface(ChollaCurve *chcurv_ptr,
+ ChollaVolume *chvol_ptr,
+ std::vector<CubitPoint *> &new_points)
+{
+ DLIList<CubitPoint *> cp_list;
+ chcurv_ptr->get_facet_points(cp_list, CUBIT_TRUE);
+ for (int ip = 0; ip<cp_list.size(); ip++)
+ {
+ CubitPoint *cp_ptr = cp_list.get_and_step();
+ CubitPoint *newcp_ptr = new_points[cp_ptr->marked()];
+
+ // set the point into edges that are on volume 2.
+ // Note that there is no direct reference from points to edges in our data structure
+ // so no need to add/remove the edge from the point
+
+ DLIList<CubitFacetEdge *> pedge_list;
+ cp_ptr->edges(pedge_list);
+ for (int iedge=0; iedge<pedge_list.size(); iedge++)
+ {
+ CubitFacetEdge *edge_ptr = pedge_list.get_and_step();
+ TDGeomFacet *td_geom = TDGeomFacet::get_geom_facet( edge_ptr );
+ if (td_geom->is_in_volume( chvol_ptr ))
+ {
+ CubitPoint *p0 = edge_ptr->point(0);
+ CubitPoint *p1 = edge_ptr->point(1);
+ CubitFacetEdgeData *cfed_ptr = dynamic_cast<CubitFacetEdgeData *> (edge_ptr);
+ if (p0 == cp_ptr)
+ cfed_ptr->set_point( newcp_ptr, 0 );
+ else if (p1 == cp_ptr)
+ cfed_ptr->set_point( newcp_ptr, 1 );
+ }
+ }
+
+ // remove facets in volume 2 from the point and add the to the new point
+ // update the point reference on the facet
+
+ DLIList<CubitFacet *> pfacet_list;
+ cp_ptr->facets(pfacet_list);
+ for (int ifacet = 0; ifacet < pfacet_list.size(); ifacet++)
+ {
+ CubitFacet *facet_ptr = pfacet_list.get_and_step();
+ TDGeomFacet *td_geom = TDGeomFacet::get_geom_facet( facet_ptr );
+ if (td_geom->is_in_volume( chvol_ptr ))
+ {
+ cp_ptr->remove_facet( facet_ptr );
+ newcp_ptr->add_facet( facet_ptr );
+ int ptidx = facet_ptr->point_index(cp_ptr);
+ CubitFacetData *cfd_ptr = dynamic_cast<CubitFacetData *> (facet_ptr);
+ cfd_ptr->set_point(newcp_ptr, ptidx);
+ }
+ }
+ }
+ return CUBIT_SUCCESS;
+}
+
+//=============================================================================
+//Function: connect_edges_at_interface
+//Description: detach the facet edges from original facets and reattach to new copy
+//Author:sjowen
+//Date: 09/18/09
+//=============================================================================
+CubitStatus ChollaEngine::connect_edges_at_interface(ChollaCurve *chcurv_ptr,
+ ChollaVolume *chvol_ptr,
+ std::vector<CubitFacetEdge *> &new_edges)
+{
+ DLIList<FacetEntity *> fe_list = chcurv_ptr->get_facet_list();
+ for (int ie=0; ie<fe_list.size(); ie++)
+ {
+ FacetEntity *fe_ptr = fe_list.get_and_step();
+ CubitFacetEdge *edge_ptr = dynamic_cast<CubitFacetEdge *> (fe_ptr);
+ assert(edge_ptr != NULL);
+ DLIList<CubitFacet *> efacet_list;
+ edge_ptr->facets(efacet_list);
+ for (int ifacet=0; ifacet<efacet_list.size(); ifacet++)
+ {
+ CubitFacet *facet_ptr = efacet_list.get_and_step();
+ TDGeomFacet *td_geom = TDGeomFacet::get_geom_facet( facet_ptr );
+ if (td_geom->is_in_volume( chvol_ptr ))
+ {
+ edge_ptr->remove_facet( facet_ptr );
+ CubitFacetEdge *newedge_ptr = new_edges[edge_ptr->marked()];
+ newedge_ptr->add_facet( facet_ptr );
+ int edidx = facet_ptr->edge_index(edge_ptr);
+ CubitFacetData *cfd_ptr = dynamic_cast<CubitFacetData *> (facet_ptr);
+ cfd_ptr->edge(newedge_ptr, edidx);
+ }
+ }
+ }
+ return CUBIT_SUCCESS;
+}
+
+//=============================================================================
+//Function: set_new_facet_owners
+//Description: update the ownenrship of the new detached facet entity based upon
+// the map set up in detach_volumes
+//
+//Author:sjowen
+//Date: 09/14/09
+//=============================================================================
+CubitStatus ChollaEngine::set_new_facet_owners(int type, //0, 1, or 2 based on dimension of facet entity
+ FacetEntity *fe_ptr, FacetEntity *newfe_ptr,
+ std::map<ChollaSurface *, ChollaSurface *> &surf_map,
+ std::map<ChollaCurve *, ChollaCurve *> &curve_map,
+ std::map<ChollaPoint *, ChollaPoint *> &point_map )
+{
+
+ // The tooldata on the original facet entity should tell us what cholla entity it belongs
+ // to. Using the map, we can then determine its new cholla entity partner. With the
+ // new merge partner, set the ownership of the new facet. Note that this manages one-to-many
+ // ownership cases where a facet lies on (or is owned by) any number of geometric entities
+
+ TDGeomFacet *td_geom = TDGeomFacet::get_geom_facet( fe_ptr );
+ TDGeomFacet::add_geom_facet(newfe_ptr, td_geom->get_block_id());
+
+ // the original facet entity is owned by one or more surfaces
+
+ DLIList<ChollaSurface *> surf_list;
+ td_geom->get_cholla_surfs( surf_list );
+ for (int jj=0; jj<surf_list.size(); jj++)
+ {
+ ChollaSurface *surf_ptr = surf_list.get_and_step();
+ std::map<ChollaSurface *, ChollaSurface *>::iterator map_it;
+ map_it = surf_map.find( surf_ptr );
+ assert(map_it != surf_map.end());
+ ChollaSurface *newsurf_ptr = map_it->second;
+ TDGeomFacet *newtdgeom = TDGeomFacet::get_geom_facet( newfe_ptr );
+ newtdgeom->add_cholla_surf( newsurf_ptr );
+
+ // add this facet entity to the cholla surface only if this is a facet
+
+ if (type == 2)
+ newsurf_ptr->add_facet(newfe_ptr);
+ }
+
+
+ // the original facet entity is owned by one or more curves
+
+ DLIList<ChollaCurve *> curv_list;
+ td_geom->get_cholla_curves( curv_list );
+ for (int jj=0; jj<curv_list.size(); jj++)
+ {
+ ChollaCurve *curv_ptr = curv_list.get_and_step();
+ std::map<ChollaCurve *, ChollaCurve *>::iterator map_it;
+ map_it = curve_map.find( curv_ptr );
+ assert(map_it != curve_map.end());
+ ChollaCurve *newcurv_ptr = map_it->second;
+ TDGeomFacet *newtdgeom = TDGeomFacet::get_geom_facet( newfe_ptr );
+ newtdgeom->add_cholla_curve( newcurv_ptr );
+
+ // add this facet entity to the cholla curve only if this is a facetedge
+
+ if (type == 1)
+ newcurv_ptr->add_facet(newfe_ptr);
+
+ }
+
+ // the original facet entity is owned by one or more points (vertices)
+
+ DLIList<ChollaPoint *> point_list;
+ td_geom->get_cholla_points( point_list );
+ for (int jj=0; jj<point_list.size(); jj++)
+ {
+ ChollaPoint *point_ptr = point_list.get_and_step();
+ std::map<ChollaPoint *, ChollaPoint *>::iterator map_it;
+ map_it = point_map.find( point_ptr );
+ assert(map_it != point_map.end());
+ ChollaPoint *newchpoint_ptr = map_it->second;
+ TDGeomFacet *newtdgeom = TDGeomFacet::get_geom_facet( newfe_ptr );
+ newtdgeom->add_cholla_point( newchpoint_ptr );
+
+ // add this facet entity to the cholla point only if this is a cubitpoint
+
+ if (type == 0)
+ newchpoint_ptr->add_facet(newfe_ptr);
+ }
+ return CUBIT_SUCCESS;
+
+}
+
+//=============================================================================
+//Function: verify_points_to_curves
+//Description: verify the connectivity between points and curves
+//Author:sjowen
+//Date: 09/16/09
+//=============================================================================
+CubitStatus ChollaEngine::verify_points_to_curves()
+{
+ for (int ii=0; ii<chollaPointList.size(); ii++)
+ {
+ ChollaPoint *chpt = chollaPointList.get_and_step();
+ if (!chpt->verify_curves())
+ {
+ PRINT_ERROR("ChollaPoint %d not associated with one of its curves.\n", chpt->get_id());
+ return CUBIT_FAILURE;
+ }
+ }
+ for (int ii=0; ii<chollaCurveList.size(); ii++)
+ {
+ ChollaCurve *chcrv = chollaCurveList.get_and_step();
+ if (!chcrv->verify_points())
+ {
+ PRINT_ERROR("ChollaCurve %d not associated with one of its points.\n", chcrv->get_id());
+ return CUBIT_FAILURE;
+ }
+ }
+ return CUBIT_SUCCESS;
+}
+
+//=============================================================================
+//Function: set_curve_endpoints
+//Description: set the end points of the curves that are adjacent to the interface surface
+//Author:sjowen
+//Date: 09/18/09
+//=============================================================================
+CubitStatus ChollaEngine::set_curve_endpoints(ChollaSurface *chsurf_ptr,
+ ChollaSurface *newchsurf_ptr,
+ std::map<ChollaCurve *, ChollaCurve *> &curve_map,
+ std::map<ChollaPoint *, ChollaPoint *> &point_map )
+{
+
+ // start with the curves on the interface surface.
+ // use the same orientation on the new curves as the original
+
+ DLIList<ChollaPoint *> chpt_list;
+ chsurf_ptr->get_vertices( chpt_list );
+ for (int ipt = 0; ipt < chpt_list.size(); ipt++)
+ {
+ ChollaPoint *chpt_ptr = chpt_list.get_and_step();
+ std::map<ChollaPoint *, ChollaPoint *>::iterator pmap_it;
+ pmap_it = point_map.find( chpt_ptr );
+ assert(pmap_it != point_map.end());
+ ChollaPoint *newchpt_ptr = pmap_it->second;
+ CubitPoint *newcp = dynamic_cast<CubitPoint *> (newchpt_ptr->get_facets());
+ DLIList<ChollaCurve *> chptcurv_list = chpt_ptr->get_curves();
+ for (int iptcurv = 0; iptcurv < chptcurv_list.size(); iptcurv++)
+ {
+ ChollaCurve *chptcurv_ptr = chptcurv_list.get_and_step();
+ std::map<ChollaCurve *, ChollaCurve *>::iterator cmap_it;
+ cmap_it = curve_map.find(chptcurv_ptr);
+ if (cmap_it == curve_map.end())
+ continue; // only visit curves at the interface
+
+ ChollaCurve *newchcurv_ptr = cmap_it->second;
+ CubitPoint *start, *end, *cp;
+ chptcurv_ptr->get_ends(start, end);
+ cp = dynamic_cast<CubitPoint *> (chpt_ptr->get_facets());
+ assert(cp != NULL);
+ assert(start!= NULL);
+ assert(end != NULL);
+
+ if ( cp == start )
+ {
+ newchcurv_ptr->set_start(newcp);
+ }
+ else if ( cp == end )
+ {
+ newchcurv_ptr->set_end(newcp);
+ }
+ else
+ {
+ assert (1);
+ }
+ }
+ }
+
+ // get the rest of the curves on volume 2 that contain one of the points at the interface
+
+ chpt_list.clean_out();
+ newchsurf_ptr->get_vertices( chpt_list );
+ for (int ipt = 0; ipt < chpt_list.size(); ipt++)
+ {
+ ChollaPoint *chpt_ptr = chpt_list.get_and_step();
+ DLIList<ChollaCurve *> chptcurv_list = chpt_ptr->get_curves();
+ for (int iptcurv = 0; iptcurv < chptcurv_list.size(); iptcurv++)
+ {
+ ChollaCurve *chptcurv_ptr = chptcurv_list.get_and_step();
+ if (!chptcurv_ptr->is_in_surface(newchsurf_ptr))
+ {
+ DLIList<ChollaPoint *> chpts_on_curve = chptcurv_ptr->get_points();
+
+ // one point on the curve assumes a periodic curve. set both ends the same
+
+ if (chpts_on_curve.size() == 1)
+ {
+ ChollaPoint *chpt_on_crv = chpts_on_curve.get();
+ CubitPoint *cp = dynamic_cast<CubitPoint *> (chpt_on_crv->get_facets());
+ chptcurv_ptr->set_start(cp);
+ chptcurv_ptr->set_end(cp);
+ }
+
+ // standard case. one point of curve is on the interface and one is not.
+ // In this case, one of the points has been replaced with a new point.
+ // so one of the end point pointers are out of date. Determine which one
+ // and then set it.
+
+ else if (chpts_on_curve.size() == 2)
+ {
+ ChollaPoint *chpt1_on_crv = chpts_on_curve.get_and_step();
+ ChollaPoint *chpt2_on_crv = chpts_on_curve.get();
+ CubitPoint *cp1 = dynamic_cast<CubitPoint *> (chpt1_on_crv->get_facets());
+ CubitPoint *cp2 = dynamic_cast<CubitPoint *> (chpt2_on_crv->get_facets());
+ CubitPoint *curstart, *curend;
+ chptcurv_ptr->get_ends(curstart, curend);
+ assert(curstart != NULL);
+ assert(curend != NULL);
+ assert(curstart != curend);
+ if (curstart == cp1)
+ {
+ chptcurv_ptr->set_end(cp2);
+ }
+ else if (curstart == cp2)
+ {
+ chptcurv_ptr->set_end(cp1);
+ }
+ else if (curend == cp2)
+ {
+ chptcurv_ptr->set_start(cp1);
+ }
+ else if (curend == cp1)
+ {
+ chptcurv_ptr->set_start(cp2);
+ }
+ else
+ {
+ assert(0);
+ }
+ }
+ else
+ assert(0);
+ }
+ }
+ }
+ return CUBIT_SUCCESS;
+}
+// EOF
Modified: cgm/branches/cubit/geom/Cholla/ChollaEngine.hpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/ChollaEngine.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/ChollaEngine.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -17,9 +17,15 @@
#ifndef CHOLLAENGINE_HPP
#define CHOLLAENGINE_HPP
+#include <set>
+#include <map>
+#include <vector>
#include "DLIList.hpp"
+#define FACET_ENTITY_UNINITIALIZED -1
+
class FacetEntity;
+class ChollaVolume;
class ChollaCurve;
class ChollaSurface;
class ChollaPoint;
@@ -27,6 +33,8 @@
class CubitFacetEdge;
class CubitFacet;
class GMem;
+class ChollaEntity;
+class FacetEvalTool;
class ChollaEngine
{
@@ -42,17 +50,28 @@
DLIList<CubitFacetEdge*> &edge_list,
DLIList<CubitPoint*> &point_list );
+ //! Constructor
+ ChollaEngine(DLIList<CubitFacet*> &facet_list,
+ DLIList<CubitFacetEdge*> &edge_list,
+ DLIList<CubitPoint*> &point_list,
+ DLIList<ChollaVolume *> &cholla_volumes,
+ DLIList<ChollaSurface *> &cholla_surfaces,
+ DLIList<ChollaCurve *> &cholla_curves,
+ DLIList<ChollaPoint *> &cholla_points );
+
//! Destructor
~ChollaEngine();
void delete_me();
//! Creates the geometry infrastructure based on the given mesh data.
- CubitStatus create_geometry(CubitBoolean use_feature_angle = CUBIT_TRUE,
+ CubitStatus create_geometry (CubitBoolean use_feature_angle = CUBIT_TRUE,
double angle = 135.0,
int interp_order = 0,
CubitBoolean smooth_non_manifold = CUBIT_TRUE,
CubitBoolean split_surfaces = CUBIT_FALSE);
+ void get_volumes( DLIList<ChollaVolume *> & cholla_volume_list )
+ { cholla_volume_list += chollaVolumeList; }
void get_surfaces( DLIList<ChollaSurface *> & cholla_surface_list )
{ cholla_surface_list += chollaSurfaceList; }
void get_curves( DLIList<ChollaCurve *> & cholla_curve_list )
@@ -65,6 +84,27 @@
void delete_eval_tools_but_not_facets();
+ // collapses a cholla curve
+ CubitStatus collapse_curve( ChollaCurve *cholla_curve, ChollaPoint *point_to_keep );
+
+ // disassociate cholla surface
+ CubitStatus disassociate_surface( ChollaSurface *cholla_surf );
+
+ // collase a cholla surface
+ CubitStatus collapse_surface( ChollaSurface *cholla_surface );
+
+ // remove functions to update facet entities
+ CubitStatus remove_facet_entity( CubitFacet *facet, ChollaSurface *cholla_surf = NULL );
+ CubitStatus remove_facet_entity( CubitFacetEdge *facet_edge, ChollaCurve *cholla_curve = NULL);
+ CubitStatus remove_facet_entity( CubitPoint *facet_pnt, ChollaPoint *cholla_point = NULL );
+ CubitStatus remove_facet_entity( CubitFacet *facet, std::set<ChollaEntity *> &cholla_surfs );
+ CubitStatus remove_facet_entity( CubitFacetEdge *facet_edge, std::set<ChollaEntity *> &cholla_curves );
+ CubitStatus remove_facet_entity( CubitPoint *facet_pnt, std::set<ChollaEntity *> &cholla_points );
+
+ // replace funcctions to update facet entities in cholla entities
+ CubitStatus replace_facet_entity( CubitFacetEdge *remove_edge, CubitFacetEdge *replace_edge, std::set<ChollaEntity *> cholla_curves );
+
+
//! Create the new features by cracking the facets at feature edges.
//! Creates new edges and points and updates connectivity
@@ -80,8 +120,9 @@
#endif
//! assumes that valid CubitPoint* are supplied
//! marks the CubitPoints as features to manually break up curves
- // added by Ved Vyas 8-2003
+ //! and surfaces
static void mark_features (DLIList<CubitPoint*> &feature_points);
+ static void mark_features (DLIList<CubitFacetEdge*> &feature_edges);
//! fix the control points so they are C-zero
static CubitStatus fix_geometry( CubitBoolean smooth_non_manifold,
@@ -105,19 +146,53 @@
//set the ChollaEngine to actually flip facets, or to just set a flag
// when facets need to be reoriented
- void set_flip_flag(CubitBoolean flip)
- {
- doFlip = flip;
- }
+ void set_flip_flag(CubitBoolean flip){ doFlip = flip; }
void print_me();
- void dump( char *filename, double angle );
+ void dump( const char *filename, double angle );
+
+ // create cholla curve
+ //CubitStatus create_curve( int block_id, ChollaPoint *new_ch_pnt0, ChollaPoint *new_ch_pnt1, ChollaCurve *&new_ch_curve );
+ CubitStatus create_curve( int block_id,
+ ChollaPoint *new_ch_pnt0,
+ ChollaPoint *new_ch_pnt1,
+ ChollaCurve *&new_ch_curve
+ );
+
+
+
+ CubitStatus create_point( CubitPoint *pnt, ChollaPoint *&new_ch_pnt );
+
+ CubitStatus create_surface( int block_id,
+ ChollaSurface *&new_ch_surf );
+
+ // disassoicate ch_curve from ch_points, ch_curve, ch_surf, and ch_engine
+ CubitStatus disassociate_curve( ChollaCurve *ch_curve,
+ bool disassociate_with_vert = true,
+ bool disassociate_with_surf = true,
+ bool disassociate_with_model = true );
+ // remove a cholla sub-entities
+ void remove_curve( ChollaCurve *ch_curve ){ chollaCurveList.remove( ch_curve ); }
+ void remove_surface( ChollaSurface *ch_surface ){ chollaSurfaceList.remove( ch_surface ); }
+ void remove_point( ChollaPoint *ch_pnt ){ chollaPointList.remove( ch_pnt ); }
+
+ // Create independent manifold volumes from the non-manifold set
+ CubitStatus detach_volumes();
+
+ //! From the facet surface list, create geometric surface,
+ //! loops and coedges for each surface in the list
+ CubitStatus build_surface_and_curve_eval_tools( DLIList<ChollaSurface*> &cholla_surface_list,
+ int interp_order, double min_dot, bool new_curve_eval_tool = false );
+
+ // verify the connectivity between points and curves
+ CubitStatus verify_points_to_curves();
private:
DLIList<FacetEntity*> faceList;
DLIList<FacetEntity*> edgeList;
DLIList<FacetEntity*> pointList;
+ DLIList<ChollaVolume*> chollaVolumeList;
DLIList<ChollaSurface*> chollaSurfaceList;
DLIList<ChollaCurve*> chollaCurveList;
DLIList<ChollaPoint*> chollaPointList;
@@ -177,11 +252,7 @@
CubitStatus build_curve_eval_tools( DLIList<ChollaCurve*> &cholla_curve_list,
int interp_order );
- //! From the facet surface list, create geometric surface,
- //! loops and coedges for each surface in the list
- CubitStatus build_surface_eval_tools( DLIList<ChollaSurface*> &cholla_surface_list,
- int interp_order, double min_dot );
-
+
//! functions for hashing curves - to speed up edge classification
CubitStatus init_hash_curves( );
void delete_hash_curves( );
@@ -245,6 +316,73 @@
//! set the normals on two points so they are the same
static CubitStatus merge_normals( CubitPoint *pt0, CubitPoint *pt1);
+ // merges two points
+ CubitStatus merge_two_points( ChollaPoint *point_to_keep, ChollaPoint *point_to_del );
+
+ // given a non-manifold surface in a cholla model, create a copy and update child entities
+ CubitStatus detach_surface(ChollaSurface *chsurf_ptr,
+ std::map<ChollaSurface *, ChollaSurface *> &surf_map,
+ std::map<ChollaCurve *, ChollaCurve *> &curve_map,
+ std::map<ChollaPoint *, ChollaPoint *> &point_map);
+ CubitStatus detach_curve(ChollaCurve *chcurv_ptr,
+ ChollaSurface *newchsurf_ptr,
+ ChollaVolume *chvol2_ptr,
+ std::map<ChollaCurve *, ChollaCurve *> &curve_map);
+ CubitStatus detach_point(ChollaPoint *chpt_ptr,
+ ChollaVolume *chvol2_ptr,
+ std::map<ChollaCurve *, ChollaCurve *> &curve_map,
+ std::map<ChollaPoint *, ChollaPoint *> &point_map);
+
+
+ // Create independent manifold volumes from the non-manifold set
+ CubitStatus detach_facets(ChollaSurface *chsurf_ptr, ChollaVolume *chvol_ptr,
+ std::map<ChollaSurface *, ChollaSurface *> &surf_map,
+ std::map<ChollaCurve *, ChollaCurve *> &curve_map,
+ std::map<ChollaPoint *, ChollaPoint *> &point_map);
+
+ CubitStatus copy_facets_at_interface(ChollaSurface *chsurf_ptr,
+ std::vector<CubitPoint *> &new_points,
+ std::vector<CubitFacetEdge *> &new_edges,
+ std::map<ChollaSurface *, ChollaSurface *> &surf_map,
+ std::map<ChollaCurve *, ChollaCurve *> &curve_map,
+ std::map<ChollaPoint *, ChollaPoint *> &point_map);
+ CubitStatus copy_points_at_interface(DLIList<FacetEntity *> &facet_list,
+ std::vector<CubitPoint *> &new_points,
+ std::map<ChollaSurface *, ChollaSurface *> &surf_map,
+ std::map<ChollaCurve *, ChollaCurve *> &curve_map,
+ std::map<ChollaPoint *, ChollaPoint *> &point_map);
+ CubitStatus copy_edges_at_interface(DLIList<FacetEntity *> &facet_list,
+ std::vector<CubitPoint *> &new_points,
+ std::vector<CubitFacetEdge *> &new_edges,
+ std::map<ChollaSurface *, ChollaSurface *> &surf_map,
+ std::map<ChollaCurve *, ChollaCurve *> &curve_map,
+ std::map<ChollaPoint *, ChollaPoint *> &point_map);
+
+ // detach the facets from original points and edges and reattach to new copy
+ CubitStatus connect_facets_at_interface(ChollaSurface *chsurf_ptr,
+ ChollaVolume *chvol_ptr,
+ std::vector<CubitPoint *> &new_points,
+ std::vector<CubitFacetEdge *> &new_edges);
+ CubitStatus connect_points_at_interface(ChollaCurve *chcurv_ptr,
+ ChollaVolume *chvol_ptr,
+ std::vector<CubitPoint *> &new_points);
+ CubitStatus connect_edges_at_interface(ChollaCurve *chcurv_ptr,
+ ChollaVolume *chvol_ptr,
+ std::vector<CubitFacetEdge *> &new_edges);
+
+ // update the ownenrship of the new detached facet entity based uponthe map set up in detach_volumes
+ CubitStatus set_new_facet_owners(int type, //0, 1, or 2 based on dimension of facet entity
+ FacetEntity *fe_ptr, FacetEntity *newfe_ptr,
+ std::map<ChollaSurface *, ChollaSurface *> &surf_map,
+ std::map<ChollaCurve *, ChollaCurve *> &curve_map,
+ std::map<ChollaPoint *, ChollaPoint *> &point_map );
+
+ // set the end points of the curves that are adjacent to the interface surface
+ CubitStatus set_curve_endpoints(ChollaSurface *chsurf_ptr,
+ ChollaSurface *newchsurf_ptr,
+ std::map<ChollaCurve *, ChollaCurve *> &curve_map,
+ std::map<ChollaPoint *, ChollaPoint *> &point_map );
+
};
#endif
Modified: cgm/branches/cubit/geom/Cholla/ChollaPoint.cpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/ChollaPoint.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/ChollaPoint.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -49,7 +49,35 @@
}
}
+//===============================================================================
+//Function: is_in_curve (PUBLIC)
+//===============================================================================
+CubitBoolean ChollaPoint::is_in_curve( ChollaCurve *chcurve )
+{
+ for (int ii=0; ii<curveList.size(); ii++)
+ {
+ ChollaCurve *curv = curveList.get_and_step();
+ if (curv == chcurve)
+ return CUBIT_TRUE;
+ }
+ return CUBIT_FALSE;
+}
+//=============================================================================
+//Function: verify_curves (PUBLIC)
+//Description: verify that all curves at this point have this point as an adjacency
+//Notes:
+//=============================================================================
+CubitStatus ChollaPoint::verify_curves()
+{
+ for(int ii=0; ii<curveList.size(); ii++)
+ {
+ ChollaCurve *crv = curveList.get_and_step();
+ if (!crv->has_point(this))
+ return CUBIT_FAILURE;
+ }
+ return CUBIT_SUCCESS;
+}
//EOF
Modified: cgm/branches/cubit/geom/Cholla/ChollaPoint.hpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/ChollaPoint.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/ChollaPoint.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -35,9 +35,18 @@
// destructor
void add_facet(FacetEntity *exterior_node)
- {myCubitPoint = exterior_node; }
+ { myCubitPoint = exterior_node; }
//- define the node associated with this point
+ void remove_facet( void )
+ {myCubitPoint = NULL;}
+ //- sets myCubitPoint to NULL
+
+ void remove_facet( FacetEntity *facet_pnt )
+ {if( myCubitPoint == facet_pnt ) myCubitPoint = NULL;}
+ //- sets myCubitPoint to NULL only if specified facet_pnt matches with myCubitPoint
+
+
FacetEntity *get_facets()
{return myCubitPoint;}
//- get the point
@@ -46,6 +55,10 @@
{curveList.append_unique( fcm_ptr );}
//- associate a curve with this point
+ inline void remove_curve( ChollaCurve *fcm_ptr )
+ { curveList.remove( fcm_ptr ); }
+ //- removes a curve attached with it
+
DLIList<ChollaCurve*> &get_curves()
{return curveList;}
//- get the list of curves attached to this point
@@ -66,6 +79,13 @@
void get_surfaces(DLIList<ChollaSurface *> &surf_list);
//- get list of associated cholla surfaces
+
+ CubitBoolean is_in_curve( ChollaCurve *chcurve );
+ // return whether this point is in the given curve
+
+ CubitStatus verify_curves();
+ //- verify that all curves at this point have this point as an adjacency
+
};
#endif
Modified: cgm/branches/cubit/geom/Cholla/ChollaSurface.cpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/ChollaSurface.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/ChollaSurface.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -19,6 +19,7 @@
#include "TDFacetBoundaryEdge.hpp"
#include "GfxDebug.hpp"
#include "FacetEvalTool.hpp"
+#include "FacetDataUtil.hpp"
//===============================================================================
//Function: ChollaSurface (PUBLIC) (constructor)
@@ -27,9 +28,11 @@
{
static int count = 100;
id = count++;
+ myFlag = CUBIT_FALSE;
mySurface = NULL;
myEvalTool = NULL;
blockId = block_id;
+ myMergePartner = NULL;
}
//===============================================================================
//Function: ~ChollaSurface (PUBLIC) (destructor)
@@ -58,7 +61,8 @@
//Date: 12/22/00
//=============================================================================
CubitStatus ChollaSurface::split_surface(
- DLIList<ChollaSurface*> &facet_surface_list )
+ DLIList<ChollaSurface*> &facet_surface_list
+ )
{
DLIList<ChollaSurface*> new_surface_list;
CubitStatus stat = CUBIT_SUCCESS;
@@ -134,6 +138,7 @@
return CUBIT_SUCCESS;
}
+
#if 0
//=============================================================================
//Function: get_adj_facets (PRIVATE)
@@ -215,7 +220,9 @@
CubitStatus ChollaSurface::get_adj_facets(
FacetEntity *start_face_ptr,
DLIList<FacetEntity*> &face_list,
- int mydebug)
+ int mydebug,
+ bool bound_check,
+ bool feature_edge_check)
{
//int found = 0;
int ii;
@@ -269,7 +276,7 @@
// of a feature angle. Don't traverse past a feature angle edge
TDGeomFacet *td_gm_edge = TDGeomFacet::get_geom_facet(edge_ptr);
- if (td_gm_edge == NULL)
+ if (td_gm_edge == NULL || !feature_edge_check )
{
adj_face_list.clean_out();
edge_ptr->get_parents( adj_face_list );
@@ -277,21 +284,31 @@
// keep traversing only if there are two adjacent faces to this edge,
// otherwise, this is a boundary
- if (adj_face_list.size() == 2)
+ if (adj_face_list.size() != 2)
{
- adj_face_ptr = adj_face_list.get_and_step();
- if (adj_face_ptr == face_ptr)
- adj_face_ptr = adj_face_list.get();
+ continue;
+ }
- // go to its neighbor if it is part of the surface
+ if( bound_check )
+ {
+ TDFacetBoundaryEdge *td_facet_bnd_edge = TDFacetBoundaryEdge::get_facet_boundary_edge( edge_ptr );
+ if( td_facet_bnd_edge )
+ continue;
+ }
+
+ adj_face_ptr = adj_face_list.get_and_step();
+ if (adj_face_ptr == face_ptr)
+ adj_face_ptr = adj_face_list.get();
- td_gm_face = TDGeomFacet::get_geom_facet(adj_face_ptr);
- if (td_gm_face->get_hit_flag() == id)
- {
- temp_list.append( adj_face_ptr );
- td_gm_face->set_hit_flag( 0 );
- }
+ // go to its neighbor if it is part of the surface
+
+ td_gm_face = TDGeomFacet::get_geom_facet(adj_face_ptr);
+ if (td_gm_face->get_hit_flag() == id)
+ {
+ temp_list.append( adj_face_ptr );
+ td_gm_face->set_hit_flag( 0 );
}
+
}
}
}
@@ -299,6 +316,8 @@
return stat;
}
+
+
//=============================================================================
//Function: feature_angle (PRIVATE)
//Description: mark all edges that exceed the specified feature angle
@@ -446,6 +465,32 @@
}
//=============================================================================
+//Function: add_preexisting_feature_edges (PRIVATE)
+//Description: edges that were marked previously in function ChollaEngine::mark_features
+// are added to the feature edge list
+//Author: sjowen
+//Date: 01/08
+//=============================================================================
+CubitStatus ChollaSurface::add_preexisting_feature_edges(
+ DLIList<CubitFacetEdge *> &feature_edge_list)
+{
+ DLIList<CubitFacetEdge *> edge_list;
+ DLIList<CubitFacet *> facet_list;
+ CAST_LIST( surfaceElemList, facet_list, CubitFacet );
+ FacetDataUtil::get_edges( facet_list, edge_list );
+ int iedge;
+ CubitFacetEdge *edge;
+ for (iedge=0; iedge < edge_list.size(); iedge++)
+ {
+ edge = edge_list.get_and_step();
+ if (edge->is_feature())
+ feature_edge_list.append(edge);
+ }
+ return CUBIT_SUCCESS;
+}
+
+
+//=============================================================================
//Function: non_manifold_edges (PRIVATE)
//Description: mark all edges that are non-manifold (have more than 2 adj
// facets)
@@ -717,5 +762,62 @@
dldraw(surfaceElemList);
}
+//=============================================================================
+//Function: flip_facets (PUBLIC)
+//Description: invert all facets on this surface
+//Author: sjowen
+//Date: 09/10/09
+//=============================================================================
+void ChollaSurface::flip_facets()
+{
+ FacetEntity *facet_entity;
+ CubitFacet *facet_ptr;
+ for (int ii=0; ii<surfaceElemList.size(); ii++)
+ {
+ facet_entity = surfaceElemList.get_and_step();
+ facet_ptr = dynamic_cast<CubitFacet *> (facet_entity);
+ assert( facet_ptr != NULL );
+ facet_ptr->flip();
+ }
+}
+
+//=============================================================================
+//Function: is_in_volume (PUBLIC)
+//Description: return whether this surface is in a particular volume
+//Author: sjowen
+//Date: 09/11/09
+//=============================================================================
+CubitBoolean ChollaSurface::is_in_volume( ChollaVolume *chvol_ptr )
+{
+ ChollaVolume *mychvol_ptr;
+ for (int ii=0; ii<volList.size(); ii++)
+ {
+ mychvol_ptr = volList.get_and_step();
+ if (mychvol_ptr == chvol_ptr)
+ return CUBIT_TRUE;
+ }
+ return CUBIT_FALSE;
+}
+
+//=============================================================================
+//Function: get_vertices (PUBLIC)
+//Description: get the list of ChollaPoints on this surface
+//Author: sjowen
+//Date: 09/11/09
+//=============================================================================
+void ChollaSurface::get_vertices( DLIList<ChollaPoint *> &chpt_list )
+{
+ chpt_list.clean_out();
+ ChollaCurve *chcurv_ptr;
+ for (int ii=0; ii<curveList.size(); ii++)
+ {
+ chcurv_ptr = curveList.get_and_step();
+ DLIList<ChollaPoint *> chc_pts = chcurv_ptr->get_points();
+ chpt_list += chc_pts;
+ }
+ chpt_list.uniquify_unordered();
+}
+
+
//EOF
Modified: cgm/branches/cubit/geom/Cholla/ChollaSurface.hpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/ChollaSurface.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/ChollaSurface.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -13,7 +13,9 @@
#include "DLIList.hpp"
#include "ChollaEntity.hpp"
+class ChollaVolume;
class ChollaCurve;
+class ChollaPoint;
class FacetEntity;
class CubitFacet;
class CubitPoint;
@@ -22,22 +24,17 @@
class ChollaSurface : public ChollaEntity
{
-private:
-
+private:
int id;
int blockId;
+ CubitBoolean myFlag;
DLIList<FacetEntity*> surfaceElemList;
DLIList<ChollaCurve*> curveList;
+ DLIList<ChollaVolume*> volList;
void *mySurface;
FacetEvalTool *myEvalTool;
-
- CubitStatus get_adj_facets( FacetEntity *start_face_ptr,
- DLIList<FacetEntity*> &face_list,
- int mydebug = 0);
- // recursive function that creates a list of all faces connected
- // the passed in face that are part of this surface (or shell)
-
+ ChollaSurface *myMergePartner;
void check_faceting();
public:
@@ -57,15 +54,28 @@
{myEvalTool = eval_tool_ptr;}
FacetEvalTool* get_eval_tool()
{return myEvalTool;}
+
+ ChollaSurface *merge_parter(){ return myMergePartner; }
+ void set_merge_partner( ChollaSurface *merge_partner )
+ { myMergePartner = merge_partner;}
+
+ CubitBoolean get_flag(){ return myFlag; }
+ void set_flag( CubitBoolean stat ){ myFlag = stat; }
void add_facet(FacetEntity *exterior_face)
{surfaceElemList.append(exterior_face);}
+
int add_mesh_unique(FacetEntity *exterior_face)
{return surfaceElemList.append_unique(exterior_face);}
+
+ void remove_facet( FacetEntity *facet )
+ {surfaceElemList.remove( facet );}
+
DLIList<FacetEntity*> &get_facet_list()
{return surfaceElemList;}
DLIList<FacetEntity*> *get_facet_list_ptr()
{return &surfaceElemList;}
+ void get_vertices( DLIList<ChollaPoint *> &chpt_list );
void get_curves( DLIList<ChollaCurve*> &bcm_list )
{bcm_list = curveList; }
void add_curve( ChollaCurve *bcm_ptr )
@@ -74,6 +84,17 @@
{curveList.append_unique(bcm_ptr);}
void remove_curve( ChollaCurve *bcm_ptr)
{curveList.remove(bcm_ptr);}
+ void get_volumes( DLIList<ChollaVolume*> &cholla_vol_list )
+ {cholla_vol_list = volList; }
+ void add_volume( ChollaVolume *cholla_vol_ptr )
+ {volList.append(cholla_vol_ptr);}
+ void add_volume_unique( ChollaVolume *cholla_vol_ptr )
+ {volList.append_unique(cholla_vol_ptr);}
+ void remove_volume( ChollaVolume *cholla_vol_ptr)
+ {volList.remove(cholla_vol_ptr);}
+ int num_volumes(){return volList.size();}
+ CubitBoolean is_in_volume( ChollaVolume *chvol_ptr );
+
int get_block_id()
{return blockId;}
void set_block_id(int flag)
@@ -81,6 +102,15 @@
int get_id(){return id;}
+ CubitStatus get_adj_facets( FacetEntity *start_face_ptr,
+ DLIList<FacetEntity*> &face_list,
+ int mydebug = 0,
+ bool bound_check = false,
+ bool feature_edge_check = true);
+ // recursive function that creates a list of all faces connected
+ // the passed in face that are part of this surface (or shell)
+
+
CubitStatus split_surface( DLIList<ChollaSurface*> &block_surface_list );
// split this surface into multiple ChollaSurface where there are
// discontinuous faces.
@@ -89,6 +119,10 @@
DLIList<CubitFacetEdge *> &feature_edge_list);
// mark all edges that exceed the specified feature angle
// min_dot is the minimum dot product between adjacent face normals
+
+ CubitStatus add_preexisting_feature_edges( DLIList<CubitFacetEdge *> &feature_edge_list);
+ // edges that were marked previously in function ChollaEngine::mark_features
+ // are added to the feature edge list
CubitStatus non_manifold_edges( DLIList<CubitFacetEdge *> &feature_edge_list );
// mark all edges that are non-manifold (have more than 2 adj facets
@@ -112,7 +146,10 @@
DLIList<DLIList<CubitFacetEdge *>*> *get_loop_edges( );
// return the ordered list of edges on the boundary of this surface
-
+
+ void flip_facets();
+ // invert all the facets on this surface
+
void debug_draw();
};
Added: cgm/branches/cubit/geom/Cholla/ChollaVolume.cpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/ChollaVolume.cpp (rev 0)
+++ cgm/branches/cubit/geom/Cholla/ChollaVolume.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,32 @@
+//- Class: ChollaVolume
+//- Description: Temporary class for constructing the facet-based geometry
+//-
+//- Owner: Steven J. Owen
+//- Checked by:
+//- Version:
+#include "ChollaVolume.hpp"
+#include "ChollaSurface.hpp"
+
+
+//===============================================================================
+//Function: ChollaVolume (PUBLIC) (constructor)
+//===============================================================================
+ChollaVolume::ChollaVolume(int block_id)
+{
+ static int count = 100;
+ id = count++;
+ myVolume = NULL;
+ blockId = block_id;
+}
+
+//===============================================================================
+//Function: ~ChollaVolume (PUBLIC) (destructor)
+//===============================================================================
+ChollaVolume::~ChollaVolume()
+{
+}
+
+
+
+//EOF
+
Added: cgm/branches/cubit/geom/Cholla/ChollaVolume.hpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/ChollaVolume.hpp (rev 0)
+++ cgm/branches/cubit/geom/Cholla/ChollaVolume.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,57 @@
+//- Class: ChollaVolume
+//- Owner: Steven J. Owen
+//- Description: volume representation for the Cholla entities
+//- Created: 8/30/2009
+//- Checked By:
+//- Version:
+
+#ifndef ChollaVolume_HPP
+#define ChollaVolume_HPP
+
+#include "DLIList.hpp"
+#include "ChollaEntity.hpp"
+
+class ChollaSurface;
+
+class ChollaVolume : public ChollaEntity
+{
+private:
+ int id;
+ int blockId;
+
+ DLIList<ChollaSurface*> surfaceList;
+ void *myVolume;
+
+public:
+
+ ChollaVolume(int block_id);
+ ~ChollaVolume();
+
+ void assign_geometric_volume(void *vol)
+ {myVolume = vol;}
+ void* get_geometric_volume()
+ {return myVolume;}
+ void get_surfaces( DLIList<ChollaSurface*> &cholla_surf_list )
+ {cholla_surf_list = surfaceList; }
+ void add_surface( ChollaSurface *cholla_surf_ptr )
+ {surfaceList.append(cholla_surf_ptr);}
+ void add_surface_unique( ChollaSurface *cholla_surf_ptr )
+ {surfaceList.append_unique(cholla_surf_ptr);}
+ void remove_surface( ChollaSurface *cholla_surf_ptr)
+ {surfaceList.remove(cholla_surf_ptr);}
+ int get_block_id()
+ {return blockId;}
+ void set_block_id(int flag)
+ { blockId = flag; }
+
+ int get_id(){return id;}
+
+ void debug_draw();
+};
+
+#endif
+
+
+
+
+
Modified: cgm/branches/cubit/geom/Cholla/CubitFacet.cpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/CubitFacet.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/CubitFacet.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -1168,3 +1168,20 @@
edge->add_facet( this );
}
+
+
+CubitPoint *CubitFacet::opposite_point( CubitFacetEdge *edge )
+{
+ int i;
+ for( i = 0; i < 3; i++ )
+ if( point(i) != edge->point(0) && point(i) != edge->point(1) )
+ return point(i);
+
+ return NULL;
+}
+
+CubitVector CubitFacet::update_normal( void )
+{
+ this->update_plane();
+ return normal();
+}
Modified: cgm/branches/cubit/geom/Cholla/CubitFacet.hpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/CubitFacet.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/CubitFacet.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -85,9 +85,13 @@
virtual ~CubitFacet();
- CubitVector normal();
+ CubitVector normal();
//- Returns the normal to this facet.
-
+
+ CubitVector update_normal( void );
+ //- update the plane and return the new normal
+
+
const CubitBox& bounding_box() {return bBox;};
void bounding_box( CubitBox &box )
{ bBox = box; }
@@ -234,7 +238,13 @@
//- Get the edge on the triangle opposite of the passed point.
//- p1 and p2 will be passed back as NULL if point is not a
//- point on this triangle.
+
+
+ CubitPoint *opposite_point( CubitFacetEdge *edge );
+ //- returns the opposite point of input edge. Input edge should be incident on facet.
+ //- If input edge is not incident on facet then any of the one point can be returned
+
void points( CubitPoint *&p0, CubitPoint *&p1, CubitPoint *&p2 )
{ p0 = point(0); p1 = point(1); p2 = point(2); }
void tri_nodes( CubitPoint *&p0, CubitPoint *&p1, CubitPoint *&p2 )
Modified: cgm/branches/cubit/geom/Cholla/CubitFacetData.cpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/CubitFacetData.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/CubitFacetData.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -135,19 +135,21 @@
//Description: destructor
//===========================================================================
CubitFacetData::~CubitFacetData()
-{
- int ii = 3;
-
+{
+ destruct_facet_internals();
+}
+
+void CubitFacetData::destruct_facet_internals()
+{
+ int ii = 3;
for (ii = 2; ii>=0; ii--){
//remove this triangle-point association at the points.
CubitPoint *current_point = point(ii);
if (current_point)
- current_point->remove_facet(this);
+ current_point->remove_facet(this);
+
+ pointArray[ii] = NULL;
- DLIList <CubitFacet *> facet_list;
- current_point->facets(facet_list);
-
-
//remove edge-point association at the edges
CubitFacetEdge *current_edge = edgeArray[ii];
@@ -155,10 +157,11 @@
CubitStatus status;
if (current_edge)
status = current_edge->remove_facet(this);
-
+ edgeArray[ii] = NULL;
}
}
+
//===========================================================================
//Function Name: closest_point
//
@@ -229,13 +232,33 @@
if ( edge->point(0) == edge1_pt ) {
edge_d->set_point(new_pt, 1);
if ( !new_edge )
+ {
new_edge = new CubitFacetEdgeData( new_pt, edge2_pt );
+ DLIList<ToolData*> tds;
+ edge->get_all_TDs(&tds);
+ for (int i=0; i<tds.size(); i++)
+ {
+ ToolData* new_td = tds.get_and_step()->propogate(new_edge);
+ if (new_td)
+ new_edge->add_TD(new_td);
+ }
+ }
else if( new_edge->point(0) != new_pt )
new_edge->flip();
} else {
edge_d->set_point(new_pt, 0);
if ( !new_edge )
+ {
new_edge = new CubitFacetEdgeData( edge2_pt, new_pt );
+ DLIList<ToolData*> tds;
+ edge->get_all_TDs(&tds);
+ for (int i=0; i<tds.size(); i++)
+ {
+ ToolData* new_td = tds.get_and_step()->propogate(new_edge);
+ if (new_td)
+ new_edge->add_TD(new_td);
+ }
+ }
else if( new_edge->point(1) != new_pt )
new_edge->flip();
}
@@ -274,6 +297,17 @@
new_facet = new CubitFacetData( other_pt, edge2_pt, new_pt );
else
new_facet = new CubitFacetData( other_pt, new_pt, edge2_pt );
+
+ DLIList<ToolData*> td_list;
+ facet->get_all_TDs(&td_list);
+ for (int i=0; i< td_list.size(); i++)
+ {
+ ToolData* new_td = td_list.get_and_step()->propogate(new_facet);
+ if (new_td)
+ {
+ new_facet->add_TD(new_td);
+ }
+ }
if ( new_edge ) {
assert(!new_facet->edge(0));
@@ -546,8 +580,23 @@
return CUBIT_FAILURE;
// get other facet
- CubitFacetData* other_facet = dynamic_cast<CubitFacetData*>(pt_facets.next());
- assert(!!other_facet);
+ CubitFacetData* other_facet = NULL;
+ if( pt_facets.get() == this )
+ {
+ other_facet = dynamic_cast<CubitFacetData*>(pt_facets.next());
+ }
+ else
+ if( pt_facets.next() == this )
+ {
+ other_facet = dynamic_cast<CubitFacetData*>( pt_facets.get() );
+ }
+ else
+ {
+ assert(0);
+ return CUBIT_FAILURE;
+ }
+
+ assert(other_facet);
// get indices on other facet
int other_pt1_index = other_facet->point_index(point1);
@@ -572,9 +621,20 @@
// get the opposite points on facets
CubitPoint* this_other_pt = this->point(this_edge_index);
CubitPoint* other_other_pt = other_facet->point(other_edge_index);
+ if(this_other_pt == other_other_pt){
+ PRINT_WARNING("Unable to perform flip.\n");
+ return CUBIT_FAILURE;
+ }
+
// get the edge that is to be moved from this to the other facet
CubitFacetEdge* this_trade_edge = this->edge(this_pt2_index);
+ // get the edge thatis to be moved from the other facet to this
+ CubitFacetEdge* other_trade_edge = other_facet->edge(other_pt1_index);
+ if(this_trade_edge == other_trade_edge){
+ PRINT_WARNING("Unable to perform flip (2).\n");
+ return CUBIT_FAILURE;
+ }
int this_trade_use = this->edge_use(this_pt2_index);
if ( this_trade_edge )
{
@@ -582,8 +642,6 @@
this_trade_edge->add_facet(other_facet);
}
- // get the edge thatis to be moved from the other facet to this
- CubitFacetEdge* other_trade_edge = other_facet->edge(other_pt1_index);
int other_trade_use = other_facet->edge_use(other_pt1_index);
if ( other_trade_edge )
{
Modified: cgm/branches/cubit/geom/Cholla/CubitFacetData.hpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/CubitFacetData.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/CubitFacetData.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -35,7 +35,10 @@
CubitPoint *p3, int *tool_data);
CubitFacetData( CubitFacetEdge *e1, CubitFacetEdge *e2,
CubitFacetEdge *e3);
- ~CubitFacetData();
+ ~CubitFacetData();
+
+ void destruct_facet_internals();
+
virtual int id(){return entityId;}
virtual void set_id( int ii ) { entityId = ii; }
Modified: cgm/branches/cubit/geom/Cholla/CubitFacetEdge.hpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/CubitFacetEdge.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/CubitFacetEdge.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -231,6 +231,16 @@
double w[2] );
double angle_between_facets();
+
+ inline int less_than(CubitFacetEdge*& e1, CubitFacetEdge*& e2)
+ {
+ double len1 = e1->length();
+ double len2 = e2->length();
+
+ if (len1 == len2) return 0;
+ return (len1 < len2) ? -1 : 1;
+ }
+
};
inline void CubitFacetEdge::control_points(
Modified: cgm/branches/cubit/geom/Cholla/CurveFacetEvalTool.cpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/CurveFacetEvalTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/CurveFacetEvalTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -255,7 +255,7 @@
{
CubitStatus stat = CUBIT_SUCCESS;
int ii, jj;
- int mydebug = 0;
+ int mydebug = DEBUG_FLAG(181);
CubitBoolean done = CUBIT_FALSE;
DLIList<CubitFacetEdge*> *facet_loop;
CubitFacetEdge *edge, *startedge = NULL;
@@ -375,6 +375,10 @@
{
stat = CUBIT_FAILURE;
PRINT_WARNING("Can't define curve representation in mesh-based geometry\n");
+ PRINT_INFO(" Hint: Try importing as a free mesh and examining nodes and attached\n");
+ PRINT_INFO(" elements near the following locations:\n");
+ PRINT_INFO(" Start curve = %f %f %f\n", start_pt->x(), start_pt->y(), start_pt->z());
+ PRINT_INFO(" End curve = %f %f %f\n", end_pt->x(), end_pt->y(), end_pt->z());
if (mydebug)
{
surfFacetEvalTool->debug_draw_facets( CUBIT_YELLOW );
@@ -1934,7 +1938,7 @@
{
CubitFacetEdge* this_edge;
CubitFacetEdge* next_edge;
- CubitPoint *this_pt0, *this_pt1;
+ CubitPoint *this_pt1;
CubitPoint *next_pt0, *next_pt1;
this_edge = myEdgeList.get_and_step();
@@ -1996,3 +2000,50 @@
{
draw_edges(color);
}
+
+CubitBoolean CurveFacetEvalTool::replace_point( CubitPoint *del_pnt, CubitPoint *keep_pnt )
+{
+ CubitPoint *point_ptr;
+ int npoints = myPointList.size();
+ myPointList.reset();
+ CubitBoolean istat = CUBIT_FALSE;
+ int i;
+ for ( i = 0; i < npoints; i++ )
+ {
+ point_ptr = myPointList.get();
+
+ if( point_ptr == del_pnt )
+ {
+ myPointList.remove();
+ myPointList.insert( keep_pnt );
+ istat = CUBIT_TRUE;
+ }
+ myPointList.step();
+ }
+
+ return istat;
+}
+
+
+CubitBoolean CurveFacetEvalTool::replace_facets( DLIList< CubitFacetEdge *> &curv_edges )
+{
+
+ // replace edges
+ this->myEdgeList = curv_edges;
+
+ // replace points
+ DLIList<CubitPoint *> point_list;
+ int i;
+ // insert start point of every facet_edge
+ curv_edges.reset();
+ for( i = 0; i < curv_edges.size(); i++ )
+ {
+ point_list.append( CAST_TO( curv_edges.get_and_step(), CubitFacetEdge )->point(0) );
+ }
+ // insert end point of last facet_edge
+ curv_edges.step( curv_edges.size() - 1 );
+ point_list.append( CAST_TO( curv_edges.get(), CubitFacetEdge )->point(1) );
+ this->myPointList = point_list;
+
+ return CUBIT_TRUE;
+}
Modified: cgm/branches/cubit/geom/Cholla/CurveFacetEvalTool.hpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/CurveFacetEvalTool.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/CurveFacetEvalTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -59,7 +59,8 @@
CubitSense owrts );
// generate a list of edges and points from the loop list
// for this curve
-/*
+
+ /*
CubitStatus project_to_facet_edge(CubitVector &this_point,
CubitVector &closest_point,
CubitVector *tangent_ptr,
@@ -151,6 +152,11 @@
//- lies outside this set, the closest point will be on the plane
//- of the closest facet. The closest_point is set to be that point.
+ // replace del_pnt with keep_pnt in point list
+ CubitBoolean replace_point( CubitPoint *del_pnt, CubitPoint *keep_pnt );
+
+ CubitBoolean replace_facets( DLIList< CubitFacetEdge *> &curv_edges );
+
CubitStatus position_from_fraction( double fraction, // between 0 and 1
CubitVector &location_on_curve );
//- computes the location on the curve based on a fraction of the
@@ -183,6 +189,8 @@
CubitBoolean has_good_curve_data(){return goodCurveData;}
void debug_draw_facet_edges(int color = -1 );
+
+
};
#endif // CURVE_FACET_EVAL_TOOL_HPP
Modified: cgm/branches/cubit/geom/Cholla/FacetDataUtil.cpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/FacetDataUtil.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/FacetDataUtil.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -1251,8 +1251,7 @@
// Date: 11/28/2002
// Author: sjowen
//===========================================================================
-CubitStatus FacetDataUtil::write_facets( char *file_name,
- DLIList<CubitFacet *> &facet_list)
+CubitStatus FacetDataUtil::write_facets( const char *file_name, DLIList<CubitFacet *> &facet_list)
{
FILE *fp = fopen(file_name, "w");
if (!fp)
@@ -1301,6 +1300,8 @@
CubitBoolean &is_water_tight)
{
CubitStatus stat = CUBIT_SUCCESS;
+ //need to init this variable otherwise the caller must have.
+ is_water_tight = CUBIT_TRUE;
// combine the quads and tri lists
@@ -1745,6 +1746,9 @@
shell_list.back();
shell_list.change_to(NULL);
+ if(!delete_shell_ptr)
+ return CUBIT_FAILURE;
+
// mark all the points on the delete_shell as now being part of
// the other shell.
@@ -1766,6 +1770,7 @@
for (ll=0; ll<pt_shell_id; ll++)
shell_ptr = shell_list.get_and_step();
*shell_ptr += (*delete_shell_ptr);
+ delete delete_shell_ptr;
}
// set the marked flag to negative to indicate that it has been
@@ -1774,7 +1779,7 @@
del_points.append(new_pt);
new_pt->marked( -new_pt->marked() );
pt->marked( -pt->marked() );
- }
+ } // close_edges
if (!was_merged)
{
@@ -1801,7 +1806,7 @@
pt = pt;
}
}
- }
+ } // merge_point_list
// compress the shell list
@@ -1838,6 +1843,7 @@
// merge the points
pt0->merge_points( pt1, CUBIT_TRUE );
+ //pt0->set_as_feature();
if (mydebug)
{
@@ -1880,6 +1886,7 @@
{
nemerge++;
edge_merged = true;
+ dedge->set_as_feature();
}
}
}
@@ -2061,6 +2068,8 @@
}
if (on_boundary)
{
+ //PRINT_INFO("Merging 'boundary' points.\n");
+ //if (pt->marked() > 0) pt->marked( -pt->marked() );
unmerged_points.append(pt);
}
else
@@ -2199,6 +2208,42 @@
}
+
+void FacetDataUtil::destruct_facet_no_delete(CubitFacet *facet_ptr)
+{
+ CubitFacetData* facet_d_ptr = dynamic_cast<CubitFacetData*>(facet_ptr);
+ if(!facet_d_ptr){
+ PRINT_ERROR("Can't work with Facet pointer that isn't a facet data object.\n");
+ return;
+ }
+
+ DLIList<CubitPoint *>point_list;
+ DLIList<CubitFacetEdge *>edge_list;
+ facet_ptr->points(point_list);
+ facet_ptr->edges(edge_list);
+
+ facet_d_ptr->destruct_facet_internals();
+
+ CubitFacetEdge *edge_ptr;
+ CubitPoint *point_ptr;
+ int ii;
+
+ for (ii=0; ii<edge_list.size(); ii++)
+ {
+ edge_ptr = edge_list.get_and_step();
+ if (edge_ptr->num_adj_facets() == 0)
+ delete edge_ptr;
+ }
+
+ for (ii=0; ii<3; ii++)
+ {
+ point_ptr = point_list.get_and_step();
+ if (point_ptr->num_adj_facets() == 0)
+ delete point_ptr;
+ }
+
+}
+
//=============================================================================
//Function: intersect_facet (PUBLIC)
//Description: determine intersection of a segment with a facet
@@ -2213,7 +2258,8 @@
CubitVector &start, CubitVector &end, // start and end points of vector
CubitFacet *facet_ptr, // the facet to intersect
CubitVector &qq, // return the intersection point
- CubitVector &ac) // area coordinates of qq if is in or on facet
+ CubitVector &ac, // area coordinates of qq if is in or on facet
+ CubitBoolean bound) // if true, only check for intersections between the end points.
{
CubitPlane fplane = facet_ptr->plane();
@@ -2240,14 +2286,13 @@
}
// points are both on the same side of the plane
-
- else if(dstart*dend > 0.0)
+ else if(dstart*dend > 0.0 &&
+ (bound || fabs(dstart-dend) < CUBIT_RESABS) )
{
return CUBIT_PNT_OUTSIDE;
}
+ // points are on opposite sides of plane: if bound == false then compute intersection with plane
- // points ae on opposite sides of plane - compute intersection with plane
-
else
{
CubitVector dir = end-start;
@@ -2256,13 +2301,25 @@
}
FacetEvalTool::facet_area_coordinate( facet_ptr, qq, ac );
-
- if (fabs(ac.x()) < GEOMETRY_RESABS ||
- fabs(ac.y()) < GEOMETRY_RESABS ||
- fabs(ac.z()) < GEOMETRY_RESABS)
- {
+
+//mod mbrewer ... the original code would call a point
+ // on the boundary if any area coordinate was near
+ // zero, regardless of whether another area coordinate
+ // was negative... making it outside.
+// if (fabs(ac.x()) < GEOMETRY_RESABS ||
+// fabs(ac.y()) < GEOMETRY_RESABS ||
+// fabs(ac.z()) < GEOMETRY_RESABS)
+// {
+// return CUBIT_PNT_BOUNDARY;
+// }
+ if ( (fabs(ac.x()) < GEOMETRY_RESABS && (ac.y() > -GEOMETRY_RESABS &&
+ ac.z() > -GEOMETRY_RESABS) )||
+ (fabs(ac.y()) < GEOMETRY_RESABS && (ac.x() > -GEOMETRY_RESABS &&
+ ac.z() > -GEOMETRY_RESABS) )||
+ (fabs(ac.z()) < GEOMETRY_RESABS && (ac.x() > -GEOMETRY_RESABS &&
+ ac.y() > -GEOMETRY_RESABS) ) ){
return CUBIT_PNT_BOUNDARY;
- }
+ }
else if (ac.x() < 0.0 || ac.y() < 0.0 || ac.z() < 0.0)
{
return CUBIT_PNT_OUTSIDE;
@@ -2340,6 +2397,199 @@
return p0 + (t/DdD)*(p1 - p0);
}
+//=============================================================================
+//Function: get_bbox_intersections (PUBLIC)
+//Description: Get the intersection of the line defined by point1 and point2 with
+//bbox. Returns 0,1 or 2 for the number of intersections. A line
+//in one of the planes of the box will return 0. Returns -1 for failure.
+//Author mborden
+//Date: 04/05/07
+//=============================================================================
+int FacetDataUtil::get_bbox_intersections(CubitVector& point1,
+ CubitVector& point2,
+ const CubitBox& bbox,
+ CubitVector& intersection_1,
+ CubitVector& intersection_2)
+{
+ int debug = 0;
+ if( debug )
+ {
+ GfxDebug::draw_point( point1, CUBIT_RED );
+ GfxDebug::draw_point( point2, CUBIT_BLUE );
+ GfxDebug::flush();
+ }
+
+ double coords[6];
+ coords[0] = bbox.min_x();
+ coords[1] = bbox.max_x();
+ coords[2] = bbox.min_y();
+ coords[3] = bbox.max_y();
+ coords[4] = bbox.min_z();
+ coords[5] = bbox.max_z();
+ DLIList<CubitVector*> intersections;
+
+ int ii;
+ for( ii = 0; ii < 3; ii++ )
+ {
+ //Define four points for each plane.
+ double box_points[4][3];
+
+ //ii = 0 -> x-planes
+ //ii = 1 -> y_planes
+ //ii = 2 -> z_planes
+
+ //Only the coordinates for the plane we are in
+ //change. The other two are constant for the
+ //jj loops below.
+ box_points[0][(ii + 1) % 3] = coords[((ii*2)+2) % 6];
+ box_points[1][(ii + 1) % 3] = coords[((ii*2)+3) % 6];
+ box_points[2][(ii + 1) % 3] = coords[((ii*2)+3) % 6];
+ box_points[3][(ii + 1) % 3] = coords[((ii*2)+2) % 6];
+
+ box_points[0][(ii + 2) % 3] = coords[((ii*2)+4) % 6];
+ box_points[1][(ii + 2) % 3] = coords[((ii*2)+4) % 6];
+ box_points[2][(ii + 2) % 3] = coords[((ii*2)+5) % 6];
+ box_points[3][(ii + 2) % 3] = coords[((ii*2)+5) % 6];
+
+ int jj;
+ for( jj = 0; jj < 2; jj++ )
+ {
+ CubitPoint* points[4];
+ int kk;
+ for( kk = 0; kk < 4; kk++ )
+ {
+ box_points[kk][ii] = coords[(ii*2)+jj];
+ points[kk] = new CubitPointData( box_points[kk][0], box_points[kk][1], box_points[kk][2] );
+ }
+
+ //Create two facets for this plane to check for intersections.
+ CubitFacet* facets[2];
+ facets[0] = new CubitFacetData( points[0], points[1], points[3] );
+ facets[1] = new CubitFacetData( points[1], points[2], points[3] );
+
+ for( kk = 0; kk < 2; kk++ )
+ {
+ CubitVector intersection;
+ CubitVector area_coord;
+
+ //Make sure the points are not parrellel with the facet.
+ CubitVector dir = point2 - point1;
+ CubitVector normal = facets[kk]->normal();
+ if( fabs(dir % normal) < CUBIT_RESABS )
+ continue;
+
+ CubitPointContainment contain = intersect_facet( point1, point2, facets[kk],
+ intersection, area_coord, CUBIT_FALSE );
+ if( CUBIT_PNT_UNKNOWN == contain )
+ {
+ //The points are in a plane. Return 0.
+ delete facets[0];
+ delete facets[1];
+ int ll;
+ for( ll = 0; ll < 4; ll++ )
+ delete points[ll];
+ for( ll = intersections.size(); ll > 0; ll-- )
+ delete intersections.get_and_step();
+
+ return 0;
+ }
+ if( CUBIT_PNT_BOUNDARY == contain ||
+ CUBIT_PNT_INSIDE == contain )
+ {
+ //The point intersects the facet so it's inside the box's surface.
+ CubitVector* new_intersection = new CubitVector;
+ *new_intersection = intersection;
+ intersections.append( new_intersection );
+
+ if( debug )
+ {
+ GfxDebug::draw_point( *new_intersection, CUBIT_CYAN );
+ GfxDebug::flush();
+ }
+
+ break;
+ }
+ }
+
+ delete facets[0];
+ delete facets[1];
+ for( kk = 0; kk < 4; kk++ )
+ delete points[kk];
+ }
+ }
+
+ //Check for duplicate intersections.
+ intersections.reset();
+ for( ii = 0; ii < intersections.size(); ii++ )
+ {
+ CubitVector* base_vec = intersections.next(ii);
+ if( NULL == base_vec )
+ continue;
+
+ int jj;
+ for( jj = ii+1; jj < intersections.size(); jj++ )
+ {
+ CubitVector* compare_vec = intersections.next(jj);
+ if( NULL != compare_vec )
+ {
+ if( base_vec->distance_between_squared( *compare_vec ) < GEOMETRY_RESABS * GEOMETRY_RESABS )
+ {
+ intersections.step(jj);
+ delete intersections.get();
+ intersections.change_to( NULL );
+ intersections.reset();
+ }
+ }
+ }
+ }
+ intersections.remove_all_with_value( NULL );
+
+
+ if( intersections.size() > 2 )
+ {
+ assert( intersections.size() <= 2 );
+ return -1;
+ }
+ else if( intersections.size() > 0 )
+ {
+ intersection_1 = *intersections.get();
+ if( intersections.size() > 1 )
+ intersection_2 = *intersections.next();
+ }
+
+ //Delete memory.
+ for( ii = intersections.size(); ii > 0; ii-- )
+ delete intersections.get_and_step();
+
+ return intersections.size();
+}
+
+
+//=============================================================================
+//Function: mark_facets (PUBLIC)
+//Description: mark facets and their children. assumes facets have points and edges
+//Author sjowen
+//Date: 09/18/09
+//=============================================================================
+void FacetDataUtil::mark_facets( DLIList<FacetEntity *> &facet_list, int mark_value )
+{
+ int ifacet;
+ FacetEntity *facet_ptr;
+ CubitFacet *cfacet_ptr;
+ for (ifacet = 0; ifacet<facet_list.size(); ifacet++)
+ {
+ facet_ptr = facet_list.get_and_step();
+ cfacet_ptr = dynamic_cast<CubitFacet *> (facet_ptr);
+ cfacet_ptr->marked(mark_value);
+ for (int ii=0; ii<3; ii++)
+ {
+ cfacet_ptr->point(ii)->marked(mark_value);
+ cfacet_ptr->edge(ii)->marked(mark_value);
+ }
+ }
+
+}
+
//EOF
Modified: cgm/branches/cubit/geom/Cholla/FacetDataUtil.hpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/FacetDataUtil.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/FacetDataUtil.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -110,7 +110,7 @@
static bool ray_intersects_boundingbox(CubitVector& point, CubitVector& ray, const CubitBox& bbox);
// write a facet list to a facet file
- static CubitStatus write_facets( char *file_name,
+ static CubitStatus write_facets( const char *file_name,
DLIList<CubitFacet *> &facet_list);
// group facets into continuous lists
@@ -128,6 +128,8 @@
static void delete_facets(DLIList<DLIList<CubitFacet*>*> &shell_list);
static void delete_facets(DLIList<CubitFacet*> &facet_list);
static void delete_facet(CubitFacet *facet_ptr);
+ static void destruct_facet_no_delete(CubitFacet *facet_ptr);
+
// determine intersection of a segment with a facet
// returns CUBIT_PNT_UNKNOWN: if segment is in plane of facet
@@ -135,9 +137,10 @@
// CUBIT_PNT_INSIDE: if segment intersects inside facet
// CUBIT_PNT_BOUNDARY: if segment intersects a vertex or edge
static CubitPointContainment intersect_facet(CubitVector &start, CubitVector &end,
- CubitFacet *facet_ptr,
- CubitVector &qq,
- CubitVector &ac);
+ CubitFacet *facet_ptr,
+ CubitVector &qq,
+ CubitVector &ac,
+ CubitBoolean bound = CUBIT_TRUE);
// get axis-aligned bounding box of list of points
static CubitStatus get_bbox_of_points(DLIList<CubitPoint*>& point_list, CubitBox& bbox);
@@ -148,7 +151,19 @@
CubitVector &p0,
CubitVector &p1,
double &distance2);
+
+ // Get the intersection of the line defined by point1 and point2 with
+ // bbox. Returns 0,1 or 2 for the number of intersections. A line
+ // in one of the planes of the box will return 0.
+ static int get_bbox_intersections(CubitVector& point1,
+ CubitVector& point2,
+ const CubitBox& bbox,
+ CubitVector& intersection_1,
+ CubitVector& intersection_2);
+ // mark facets and their children
+ static void mark_facets( DLIList<FacetEntity *> &facet_list, int mark_value );
+
private:
// used with split_into_shells to group facets
Modified: cgm/branches/cubit/geom/Cholla/FacetEvalTool.cpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/FacetEvalTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/FacetEvalTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -23,6 +23,7 @@
#include "debug.hpp"
#include "TDFacetBoundaryEdge.hpp"
#include "TDFacetBoundaryPoint.hpp"
+#include "TDGeomFacet.hpp"
#include "GfxDebug.hpp"
//#include "FacetParamTool.hpp"
#include "KDDTree.hpp"
@@ -529,7 +530,6 @@
//===========================================================================
CubitStatus FacetEvalTool::mark_edge_pairs(CubitPoint* point)
{
- CubitStatus status = CUBIT_SUCCESS;
int i,j;
DLIList<CubitFacetEdge*> edge_list;
DLIList<CubitFacetEdge*> edge_list_init;
@@ -1319,7 +1319,7 @@
CubitStatus FacetEvalTool::project_to_patch(
CubitFacet *facet, // (IN) the facet where the patch is defined
CubitVector &ac, // (IN) area coordinate initial guess (from linear facet)
- CubitVector &pt, // (IN) point we are projecting to patch
+ const CubitVector &pt, // (IN) point we are projecting to patch
CubitVector &eval_pt, // (OUT) The projected point
CubitVector *eval_norm, // (OUT) normal at evaluated point
CubitBoolean &outside, // (OUT) the closest point on patch to pt is on an edge
@@ -1606,7 +1606,7 @@
//===========================================================================
CubitBoolean FacetEvalTool::is_at_vertex(
CubitFacet *facet, // (IN) facet we are evaluating
- CubitVector &pt, // (IN) the point
+ const CubitVector &pt, // (IN) the point
CubitVector &ac, // (IN) the ac of the point on the facet plane
double compare_tol, // (IN) return TRUE of closer than this
CubitVector &eval_pt, // (OUT) location at vertex if TRUE
@@ -2033,7 +2033,7 @@
// 4 = b-spline patches
double compare_tol, // (IN) tolerance for projection -
// should be about 1e-3*edge
- CubitVector &this_point, // (IN) point we are projecting
+ const CubitVector &this_point, // (IN) point we are projecting
CubitBoolean trim, // (IN) trim to facet (always trimmed
// if b-spline patch)
CubitBoolean *outside, // (OUT) TRUE if projected outside
@@ -2539,7 +2539,7 @@
// a starting guess.
//===========================================================================
CubitStatus FacetEvalTool::project_to_facet( CubitFacet *facet,
- CubitVector &pt,
+ const CubitVector &pt,
CubitVector &areacoord,
CubitVector &close_point,
CubitBoolean &outside_facet,
@@ -2596,7 +2596,7 @@
//===========================================================================
CubitStatus FacetEvalTool::project_to_facetedge( CubitFacet *facet,
int vert0, int vert1,
- CubitVector &the_point,
+ const CubitVector &the_point,
CubitVector &pt_on_plane,
CubitVector &close_point,
CubitBoolean &outside_facet,
@@ -2999,7 +2999,7 @@
//===========================================================================
void FacetEvalTool::project_to_facet_plane(
CubitFacet *facet,
- CubitVector &pt,
+ const CubitVector &pt,
CubitVector &point_on_plane,
double &dist_to_plane)
{
@@ -3029,7 +3029,7 @@
//===========================================================================
void FacetEvalTool::facet_area_coordinate(
CubitFacet *facet,
- CubitVector &pt_on_plane,
+ const CubitVector &pt_on_plane,
CubitVector &areacoord )
{
double area2;
@@ -3924,16 +3924,16 @@
//===========================================================================
CubitBoolean FacetEvalTool::is_boundary_facet( CubitFacet *facet_ptr )
{
- TDFacetBoundaryEdge *td_fbe = NULL;
- TDFacetBoundaryPoint *td_fbp = NULL;
+ TDGeomFacet *td_fbe = NULL;
+ TDGeomFacet *td_fbp = NULL;
int ii;
for (ii=0; ii<3; ii++)
{
- td_fbe = TDFacetBoundaryEdge::get_facet_boundary_edge( facet_ptr->edge( ii ) );
- if (td_fbe != NULL)
+ td_fbe = TDGeomFacet::get_geom_facet( facet_ptr->edge( ii ) );
+ if ( td_fbe->on_boundary() )
return CUBIT_TRUE;
- td_fbp = TDFacetBoundaryPoint::get_facet_boundary_point( facet_ptr->point( ii ) );
- if (td_fbp != NULL)
+ td_fbp = TDGeomFacet::get_geom_facet( facet_ptr->point( ii ) );
+ if ( td_fbe->on_boundary() )
return CUBIT_TRUE;
}
return CUBIT_FALSE;
@@ -4338,3 +4338,255 @@
return CUBIT_SUCCESS;
}
+
+CubitStatus FacetEvalTool::get_intersections(CubitVector point1,
+ CubitVector point2,
+ DLIList<CubitVector*>& intersection_list,
+ bool bounded)
+{
+ //Find the points were the line intersects the bounding box.
+ CubitVector intersect_1;
+ CubitVector intersect_2;
+ CubitBox bbox = *myBBox;
+
+ //Increase the size of the box in each direction.
+ //Don't use scale because the box may be too thin (planar surface).
+ double offset = 2.0 * (point1 - point2).length();
+
+ CubitVector min;
+ min.x( bbox.min_x() - offset );
+ min.y( bbox.min_y() - offset );
+ min.z( bbox.min_z() - offset );
+ CubitVector max;
+ max.x( bbox.max_x() + offset );
+ max.y( bbox.max_y() + offset );
+ max.z( bbox.max_z() + offset );
+
+ bbox.reset( min, max );
+ int box_intersections = FacetDataUtil::get_bbox_intersections( point1, point2, bbox,
+ intersect_1, intersect_2 );
+
+ //The bounding box is larger than the surface we are checking.
+ //This means that if there are less than two intersections
+ //the line will not intersect the surface.
+ if( 2 > box_intersections )
+ return CUBIT_SUCCESS;
+
+ bbox.reset( intersect_1 );
+ bbox |= intersect_2;
+
+ //Find the facets that are intersected by the bbox that was just created.
+ DLIList<CubitFacet*> search_facets;
+ if( aTree )
+ {
+ //Get the facets from the tree.
+ aTree->find( bbox, search_facets );
+ }
+ else
+ search_facets = myFacetList;
+
+ int ii;
+ for( ii = search_facets.size(); ii > 0; ii-- )
+ {
+ CubitFacet* test_facet = search_facets.get_and_step();
+
+ CubitVector intersection;
+ CubitVector area_coord;
+ CubitPointContainment contain = FacetDataUtil::intersect_facet( intersect_1, intersect_2, test_facet,
+ intersection, area_coord );
+
+ if( bounded )
+ {
+ CubitVector dir1 = point2 - point1;
+ CubitVector dir2 = intersection - point1;
+
+ if( dir2.length_squared() > (GEOMETRY_RESABS * GEOMETRY_RESABS) )
+ {
+ if( dir1 % dir2 < 0 ||
+ ( ( dir2.length_squared() - dir1.length_squared() ) >
+ ( GEOMETRY_RESABS * GEOMETRY_RESABS ) ) )
+ {
+ //The inserction point is not between the two end points.
+ contain = CUBIT_PNT_OUTSIDE;
+ }
+ }
+ }
+
+ if( CUBIT_PNT_BOUNDARY == contain ||
+ CUBIT_PNT_INSIDE == contain )
+ {
+ //The point intersects the facets.
+ CubitVector* new_intersection = new CubitVector;
+ *new_intersection = intersection;
+ intersection_list.append( new_intersection );
+ }
+ }
+
+ //Remove duplicate intersections.
+ intersection_list.reset();
+ for( ii = 0; ii < intersection_list.size(); ii++ )
+ {
+ CubitVector* base_vec = intersection_list.next(ii);
+ if( NULL == base_vec )
+ continue;
+
+ int jj;
+ for( jj = ii+1; jj < intersection_list.size(); jj++ )
+ {
+ CubitVector* compare_vec = intersection_list.next(jj);
+ if( NULL != compare_vec )
+ {
+ if( base_vec->distance_between_squared( *compare_vec ) < GEOMETRY_RESABS * GEOMETRY_RESABS )
+ {
+ intersection_list.step(jj);
+ delete intersection_list.get();
+ intersection_list.change_to( NULL );
+ intersection_list.reset();
+ }
+ }
+ }
+ }
+ intersection_list.remove_all_with_value( NULL );
+
+ return CUBIT_SUCCESS;
+}
+
+int FacetEvalTool::intersect_ray( CubitVector &origin, CubitVector &direction, CubitFacet* facet, CubitVector* point, double &distance )
+{
+ // This algorithm can be found at http://geometryalgorithms.com/
+
+ CubitVector n; // triangle vectors
+ CubitVector w0, w; // ray vectors
+ double a, b; // params to calc ray-plane intersect
+
+ // get triangle edge vectors and plane normal
+ CubitVector normal = facet->normal();
+ CubitPoint *pt0 = facet->point(0);
+ CubitPoint *pt1 = facet->point(1);
+ CubitPoint *pt2 = facet->point(2);
+ double tol = GEOMETRY_RESABS;
+
+ CubitVector u( pt1->x() - pt0->x(),
+ pt1->y() - pt0->y(),
+ pt1->z() - pt0->z()); //(*p1-*p0);
+ CubitVector v( pt2->x() - pt0->x(),
+ pt2->y() - pt0->y(),
+ pt2->z() - pt0->z()); // = (*p2-*p0);
+
+ //u = T.V1 - T.V0;
+ //v = T.V2 - T.V0;
+ n = u * v; // cross product
+ if (n.length_squared() == 0) // triangle is degenerate
+ return -1; // do not deal with this case
+
+ //dir = R.P1 - R.P0; // ray direction vector
+ //w0 = R.P0 - T.V0;
+ w0 = CubitVector(origin.x() - pt0->x(),
+ origin.y() - pt0->y(),
+ origin.z() - pt0->z());
+
+ a = -(n%w0);
+ b = (n%direction);
+ if (fabs(b) < tol) { // ray is parallel to triangle plane
+ if (a == 0) // ray lies in triangle plane
+ return 2;
+ else return 0; // ray disjoint from plane
+ }
+
+ // get intersect point of ray with triangle plane
+ distance = a / b;
+ if (distance < 0.0) // ray goes away from triangle
+ return 0; // => no intersect
+ // for a segment, also test if (r > 1.0) => no intersect
+
+ point->set(origin + distance * direction); // intersect point of ray and plane
+
+ // the distance we want to return is real distance, not distance/magnitude
+ distance *= direction.length();
+
+ // is point inside facet?
+ double uu, uv, vv, wu, wv, D;
+ uu = u%u;
+ uv = u%v;
+ vv = v%v;
+ //w = *I - T.V0;
+ w = CubitVector(point->x() - pt0->x(),
+ point->y() - pt0->y(),
+ point->z() - pt0->z());
+ wu = w%u;
+ wv = w%v;
+ D = uv * uv - uu * vv;
+
+ // get and test parametric coords
+ double s, t;
+ s = (uv * wv - vv * wu) / D;
+ if (s < 0.0 || s > 1.0) // point is outside facet
+ return 0;
+ t = (uv * wu - uu * wv) / D;
+ if (t < 0.0 || (s + t) > 1.0) // point is outside facet
+ return 0;
+
+ return 1; // point is in facet
+
+}
+
+int FacetEvalTool::intersect_ray( CubitVector &origin, CubitVector &direction, CubitFacetEdge* facet_edge, CubitVector* point, double &hit_distance )
+{
+ // This algorithm can be found at http://geometryalgorithms.com/
+ double tol = GEOMETRY_RESABS;
+
+ CubitPoint* p0 = facet_edge->point(0);
+ CubitPoint* p1 = facet_edge->point(1);
+ CubitVector u0 = CubitVector(p0->x(), p0->y(), p0->z());
+ CubitVector u1 = CubitVector(p1->x(), p1->y(), p1->z());
+
+ CubitVector u = CubitVector(u0, u1);
+ CubitVector v = direction;
+ v.normalize();
+
+ CubitVector w = CubitVector(origin, u0);
+
+ double sc, tc; // sc is fraction along facet edge, tc is distance along ray
+
+ double a = u%u; // always >= 0
+ double b = u%v;
+ double c = v%v; // always >= 0
+ double d = u%w;
+ double e = v%w;
+ double D = a*c - b*b; // always >= 0
+
+ // compute the line parameters of the two closest points
+ if (D < tol)
+ {
+ // the lines are almost parallel
+ sc = 0.0;
+ tc = (b>c ? d/b : e/c); // use the largest denominator
+ }
+ else
+ {
+ sc = (b*e - c*d) / D;
+ tc = (a*e - b*d) / D;
+ }
+
+ // get the difference of the two closest points
+ CubitVector dP = CubitVector(w + (sc * u) - (tc * v)); // = <0 0 0> if intersection
+
+ double distance = sqrt(dP % dP); // return the closest distance (0 if intersection)
+
+ point->set(u0 + (sc * u));
+ hit_distance = tc; //distance from origin to intersection point
+
+ if (distance < tol)
+ {
+ //check if parallel (infinite intersection)
+ if (D < tol)
+ return 2;
+ //check if on edge
+ if (sc <= 1.0 && sc >= 0.0)
+ return 1;
+ else
+ return 0;
+ }
+
+ return 0;
+}
Modified: cgm/branches/cubit/geom/Cholla/FacetEvalTool.hpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/FacetEvalTool.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/FacetEvalTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -79,8 +79,6 @@
DLIList<CubitFacetEdge*> &edge_list );
//- populates the edge_list with edges contained by the given facets
- CubitStatus get_loops_from_facets(DLIList<CubitFacetEdge*> &all_edge_list,
- DLIList<DLIList<CubitFacetEdge*>*> &loop_list );
//- populates the loop_list with edges contained by the given edge list
void destroy_facets();
//- Destroys the facets, and points.
@@ -152,7 +150,7 @@
CubitVector Nijk[10] );
static CubitStatus project_to_patch( CubitFacet *facet,
CubitVector &ac,
- CubitVector &pt,
+ const CubitVector &pt,
CubitVector &eval_pt,
CubitVector *eval_norm,
CubitBoolean &outside,
@@ -169,7 +167,7 @@
//- determine the area coordinate of the facet at the edge
static CubitBoolean is_at_vertex( CubitFacet *facet,
- CubitVector &pt,
+ const CubitVector &pt,
CubitVector &ac,
double compare_tol,
CubitVector &eval_pt,
@@ -270,7 +268,7 @@
//- the facet area coordinates
static CubitStatus project_to_facet( CubitFacet *facet,
- CubitVector &pt,
+ const CubitVector &pt,
CubitVector &areacoord,
CubitVector &close_point,
CubitBoolean &outside,
@@ -282,7 +280,7 @@
CubitFacet *&last_facet,
int interp_order,
double compare_tol,
- CubitVector &this_point,
+ const CubitVector &this_point,
CubitBoolean trim,
CubitBoolean *outside,
CubitVector *closest_point_ptr,
@@ -296,7 +294,7 @@
CubitVector &close_point);
static CubitStatus project_to_facetedge( CubitFacet *facet,
int vert0, int vert1,
- CubitVector &the_point,
+ const CubitVector &the_point,
CubitVector &pt_on_plane,
CubitVector &close_point,
CubitBoolean &outside_facet,
@@ -315,13 +313,13 @@
//- evaluate the normal on a facet (use the interpOrder)
static void project_to_facet_plane( CubitFacet *facet,
- CubitVector &pt,
+ const CubitVector &pt,
CubitVector &point_on_plane,
double &dist );
//- project a point to the plane of a facet
static void facet_area_coordinate( CubitFacet *facet,
- CubitVector &pt_on_plane,
+ const CubitVector &pt_on_plane,
CubitVector &areacoord );
//- define the area coordinates of a point on a plane of the facet
@@ -405,6 +403,39 @@
static CubitFacetEdge *next_boundary_edge( CubitFacetEdge *this_edge, CubitPoint *p0 );
//- return the next edge on the boundary
+ CubitStatus get_intersections(CubitVector point1,
+ CubitVector point2,
+ DLIList<CubitVector*>& intersection_list,
+ bool bounded = CUBIT_FALSE);
+
+
+ // The following copyright applies to the following two functions...
+ //
+ // Copyright 2001, softSurfer (www.softsurfer.com)
+ //
+ // This code may be freely used and modified for any purpose
+ // providing that this copyright notice is included with it.
+ // SoftSurfer makes no warranty for this code, and cannot be held
+ // liable for any real or imagined damage resulting from its use.
+ // Users of this code must verify correctness for their application.
+
+ static int intersect_ray( CubitVector &origin, CubitVector &direction, CubitFacet* facet, CubitVector* point, double &distance );
+ //- Find intersection point of a ray and a facet
+ // Return: -1 = triangle is degenerate (a segment or point)
+ // 0 = disjoint (no intersect)
+ // 1 = intersect at unique point
+ // 2 = are in the same plane
+
+ static int intersect_ray( CubitVector &origin, CubitVector &direction, CubitFacetEdge* facet, CubitVector* point, double &distance );
+ //- Find intersection point of a ray and a facet edge
+ // Return: -1 = edge is degenerate (a point)
+ // 0 = disjoint (no intersect)
+ // 1 = intersect at unique point
+ // 2 = are the same line (infinite points)
+
+
+ CubitStatus get_loops_from_facets(DLIList<CubitFacetEdge*> &all_edge_list,
+ DLIList<DLIList<CubitFacetEdge*>*> &loop_list );
};
#endif // SMOOTH_FACET_EVAL_TOOL_HPP
Modified: cgm/branches/cubit/geom/Cholla/FacetorTool.cpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/FacetorTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/FacetorTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -18,6 +18,7 @@
#endif
#include "FacetorTool.hpp"
+#include "FacetorUtil.hpp"
#include "TDDelaunay.hpp"
#include "BoundaryConstrainTool.hpp"
#include "CubitPoint.hpp"
@@ -31,9 +32,7 @@
((q3)*((p2)-(p1)) + (q2)*((p1)-(p3)) + (q1)*((p3)-(p2)))
#define SQR(x) ((x) * (x))
#define FT_INSIDE_TOL 1.0e-6
-#define NUM_SORT_LISTS 64
#define QUALITY_ANGLE 0.361283155162 /* 20.7 degrees */
-#define INTERVAL (QUALITY_ANGLE/(NUM_SORT_LISTS-1))
#define ALPHA 0.70228615
//-------------------------------------------------------------------------
@@ -62,9 +61,7 @@
sizingFunction = sizing_function;
curVisitFlag = INT_MIN+1;
- lastTriLocated = NULL;
boxNodes[0] = boxNodes[1] = boxNodes[2] = boxNodes[3] = NULL;
- triSortArray = NULL;
}
@@ -78,8 +75,6 @@
FacetorTool<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::~FacetorTool()
{
numBoundaryEdges = 0;
- if (triSortArray != NULL)
- delete [] triSortArray;
}
@@ -305,129 +300,8 @@
return CUBIT_SUCCESS;
}
-//-------------------------------------------------------------------------
-// Function: circumcenter
-// Description: get the circumcenter of the triangle
-// Author: chynes
-// Date: 6/6/2002
-//-------------------------------------------------------------------------
-template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
-CubitVector &FacetorTool<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::circumcenter( TRI *tri_ptr )
-{
- ToolData *td = tri_ptr->get_TD( TDDelaunay< TRI, NODE >::is_delaunay );
- TDDelaunay< TRI, NODE > *td_del = dynamic_cast<TDDelaunay< TRI, NODE >*> (td);
- if(td_del == NULL) {
- td_del = new TDDelaunay<TRI, NODE>();
- tri_ptr->add_TD( td_del );
- }
- return td_del->circumcenter2d( tri_ptr );
-}
-
//-------------------------------------------------------------------------
-// Function: radius
-// Description: get the radius squared of the triangle circumcircle
-// Author: chynes
-// Date: 6/6/2002
-//-------------------------------------------------------------------------
-template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
-double FacetorTool<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::radius( TRI *tri_ptr )
-{
- ToolData *td = tri_ptr->get_TD( TDDelaunay< TRI, NODE >::is_delaunay );
- TDDelaunay< TRI, NODE > *td_del = dynamic_cast<TDDelaunay< TRI, NODE >*> (td);
- if (td_del == NULL)
- {
- td_del = new TDDelaunay< TRI, NODE >();
- tri_ptr->add_TD( td_del );
- }
- return td_del->radius2d( tri_ptr );
-}
-
-//-------------------------------------------------------------------------
-// Function: tri_visited
-// Description: set the tri_visited flag
-// Author: chynes
-// Date: 6/6/2002
-//-------------------------------------------------------------------------
-template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
-CubitBoolean FacetorTool<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::tri_visited( TRI *tri_ptr )
-{
- ToolData *td = tri_ptr->get_TD( TDDelaunay< TRI, NODE >::is_delaunay );
- TDDelaunay< TRI, NODE > *td_del = dynamic_cast<TDDelaunay< TRI, NODE >*> (td);
- if (td_del == NULL)
- {
- td_del = new TDDelaunay< TRI, NODE >();
- tri_ptr->add_TD( td_del );
- }
- return (td_del->visit_flag() == curVisitFlag);
-}
-
-//-------------------------------------------------------------------------
-// Function: tri_visited
-// Description: set the tri_visited flag
-// Author: chynes
-// Date: 6/3/2002
-//-------------------------------------------------------------------------
-template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
-void FacetorTool<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::
-tri_visited( TRI *facet_ptr, CubitBoolean visited )
-{
- ToolData *td = facet_ptr->get_TD( TDDelaunay< TRI, NODE >::is_delaunay );
- TDDelaunay< TRI, NODE > *td_del = dynamic_cast<TDDelaunay< TRI, NODE >*> (td);
- if (td_del == NULL)
- {
- td_del = new TDDelaunay< TRI, NODE >();
- facet_ptr->add_TD( td_del );
- }
- if (visited)
- td_del->visit_flag(curVisitFlag);
- else
- td_del->visit_flag(INT_MIN);
-}
-
-
-//-------------------------------------------------------------------------
-// Function: tri_sort_list
-// Description: set the tri sort list index
-// Author: chynes
-// Date: 6/3/2002
-//-------------------------------------------------------------------------
-template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
-void FacetorTool<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::tri_sort_list( TRI *facet_ptr,
- int sort_list_index )
-{
- ToolData *td = facet_ptr->get_TD( TDDelaunay< TRI, NODE >::is_delaunay );
- TDDelaunay< TRI, NODE > *td_del = dynamic_cast<TDDelaunay< TRI, NODE >*> (td);
- if (td_del == NULL)
- {
- td_del = new TDDelaunay<TRI, NODE>();
- facet_ptr->add_TD( td_del );
- }
- td_del->tri_sort_list(sort_list_index);
-}
-
-
-//-------------------------------------------------------------------------
-// Function: tri_sort_list
-// Description: get the tri sort list index
-// Author: chynes
-// Date: 6/3/2002
-//-------------------------------------------------------------------------
-template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
-int FacetorTool<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::tri_sort_list( TRI *facet_ptr )
-{
- ToolData *td = facet_ptr->get_TD( TDDelaunay< TRI, NODE >::is_delaunay );
- TDDelaunay< TRI, NODE > *td_del = dynamic_cast<TDDelaunay< TRI, NODE >*> (td);
- if (td_del == NULL)
- {
- td_del = new TDDelaunay<TRI, NODE>();
- facet_ptr->add_TD( td_del );
- }
- return td_del->tri_sort_list();
-}
-
-
-//-------------------------------------------------------------------------
// Function: insert_nodes
// Description: insert nodes into Delaunay mesh
// Author: chynes
@@ -440,9 +314,13 @@
CubitStatus rv = CUBIT_SUCCESS;
int ii;
NODE *point_ptr;
+ TRI* start_tri = NULL;
for (ii=0; ii<bounding_nodes->size() && rv == CUBIT_SUCCESS; ii++){
point_ptr = bounding_nodes->get_and_step();
- rv = insert_node( point_ptr );
+ rv = FacetorUtil<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::insert_node(
+ point_ptr, *facetList,
+ refFacePtr, curVisitFlag,
+ start_tri);
}
@@ -451,463 +329,6 @@
//-------------------------------------------------------------------------
-// Function: insert_node
-// Description: insert one node into Delaunay mesh
-// Author: chynes
-// Date: 6/3/2002
-//-------------------------------------------------------------------------
-template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
-CubitStatus FacetorTool<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::insert_node( NODE *node_ptr )
-{
- CubitStatus rv = CUBIT_SUCCESS;
-
- // get a list of all triangles whose circumcircle contain the point
-
- DLIList<TRI *> tri_list;
- CubitVector the_point = node_ptr->coordinates();
- rv = natural_neighbor_tris( the_point, tri_list );
-
-
- // Use a Bowyer-Watson insertion
-
- if (rv == CUBIT_SUCCESS)
- {
- rv = bowyer_watson_insert( node_ptr, tri_list );
- }
-
- return rv;
-}
-
-
-//-------------------------------------------------------------------------
-// Function: bowyer_watson_insert
-// Description: Bowyer-Watson insertion into an existing Delaunay Mesh
-// Author: chynes
-// Date: 6/3/2002
-//-------------------------------------------------------------------------
-template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
-CubitStatus FacetorTool<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::bowyer_watson_insert( NODE *point_ptr,
- DLIList<TRI *> &tri_list)
-{
- CubitStatus rv = CUBIT_SUCCESS;
-
- // mark the tris in the list so we can distinguish them from their
- // neighbors
-
- curVisitFlag++;
- int ii, jj;
- TRI *tri_ptr;
- for (ii=0; ii<tri_list.size(); ii++)
- {
- tri_ptr = tri_list.get_and_step();
- tri_visited( tri_ptr, CUBIT_TRUE );
- }
- //MBREWER: This is not an optimal test. But, we need need to
- //do some tests to try to ensure that the void is valid for what
- //we need. This is attempting to avoid crashes by not allowing nodes
- //to be inserted when the mesh starts diverging from the Delaunay
- //criteria.
- rv = valid_void( point_ptr, tri_list );
- if(!rv)
- return rv;
-
- // find all edges at the boundary of the visited triangles and create
- // new triangles with them
-
- // create a new triangle with this edge and the node
- TRI *adjtri_ptr;
- TRI *new_tri = NULL;
- EDGE *edge_ptr;
- DLIList<EDGE *> edge_list;
- for (ii=0; ii<tri_list.size(); ii++)
- {
- tri_ptr = tri_list.get_and_step();
- for (jj=0; jj<3; jj++){
-
- int kk = jj;
- // - if TRI == CubitFacet
- // - kk will be corrected in adjacent() to
- // - give the correct EDGE index
- adjtri_ptr = tri_ptr->adjacent( kk, refFacePtr );
- if (!adjtri_ptr || !tri_visited( adjtri_ptr ))
- {
- edge_ptr = tri_ptr->edge(kk);
- assert(edge_list.append_unique( edge_ptr ));
- if(tri_ptr->sense(kk) == CUBIT_FORWARD)
- new_tri = (TRI *) new TRICHILD( edge_ptr->start_node(), edge_ptr->end_node(), point_ptr, refFacePtr);
- else
- new_tri = (TRI *) new TRICHILD( edge_ptr->end_node(), edge_ptr->start_node(), point_ptr, refFacePtr);
- facetList->append(new_tri);
- }
- }
- }
- lastTriLocated = new_tri;
-
- // delete the triangles in the original triangle list
-
- EDGE *del_edge_ptr;
- DLIList<EDGE *> del_edge_list;
- for (ii=0; ii<tri_list.size(); ii++)
- {
- tri_ptr = tri_list.get_and_step();
- del_edge_list.clean_out();
- facetList->move_to(tri_ptr);
- facetList->extract();
- tri_ptr->edges( del_edge_list );
- delete tri_ptr;
-
- // delete the unused edges
- for (jj=0; jj<del_edge_list.size(); jj++)
- {
- del_edge_ptr = del_edge_list.get_and_step();
- if (del_edge_ptr->number_tris() == 0 && del_edge_ptr->number_faces() == 0 )
- delete del_edge_ptr;
- }
- }
-
- return rv;
-}
-/************************************************************/
-//author: mbrewer
-//This function performs tests on the void created by a point's
-//insertion to make sure that invalid connectivities are not
-//being created.
-/************************************************************/
-template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
-CubitStatus FacetorTool<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::valid_void( NODE * /*point_ptr*/,
- DLIList<TRI *> &tri_list)
-{
- int temp_i, temp_j;
- DLIList<EDGE*> boundary_edge_list;
- DLIList<NODE*> boundary_node_list;
- TRI *adjtri_ptr;
- TRI *tri_ptr;
- EDGE *edge_ptr;
- DLIList<EDGE *> edge_list;
- //loop over the tri's in tri_list and find all of the curves
- //on the boundary of the set (ie, on the boundary of the void).
- for (temp_i=0; temp_i<tri_list.size(); temp_i++)
- {
- tri_ptr = tri_list.get_and_step();
- //check each edge to see whether it is a boundary edge or not
- for (temp_j=0; temp_j<3; temp_j++){
-
- int kk = temp_j;
- // - if TRI == CubitFacet
- // - kk will be corrected in adjacent() to
- // - give the correct EDGE index
- adjtri_ptr = tri_ptr->adjacent( kk, refFacePtr );
- if (!adjtri_ptr || !tri_visited( adjtri_ptr ))
- {
- edge_ptr = tri_ptr->edge(kk);
- boundary_edge_list.append(edge_ptr);
- }
- }
- }
- int list_size = boundary_edge_list.size();
- //uniquify the boundary edge list
- boundary_edge_list.uniquify_unordered();
- //the list shouldn't have changed size during the uniquify.
- //if it did, there is a problem.
- if(list_size != boundary_edge_list.size()){
- PRINT_WARNING("Unexpected result. Edge was duplicated on boundary.\n");
- return CUBIT_FAILURE;
- }
- //loop over the boundary edges and get the nodes in the boundary loop
- for(temp_i=0; temp_i<list_size; ++temp_i){
- edge_ptr=boundary_edge_list.get_and_step();
- boundary_node_list.append(edge_ptr->end_node());
- boundary_node_list.append(edge_ptr->start_node());
- }
- list_size = boundary_node_list.size();
- //each node should be in exactly two edges. First make sure that there
- //are the correct number of nodes.
- if(list_size%2){
- PRINT_WARNING("Unexpected result. Node not listed twice.\n");
- return CUBIT_FAILURE;
- }
- //now uniquify to make sure that the nodes were listed the correct number
- //of times.
- boundary_node_list.uniquify_unordered();
- if( (list_size/2) != boundary_node_list.size()){
- PRINT_WARNING("Unexpected result. Node was listed an incorrect number of times.\n");
- return CUBIT_FAILURE;
- }
- return CUBIT_SUCCESS;
-
-}
-
-//-------------------------------------------------------------------------
-// Function: natural_neighbor_tris
-// Description: get a list of all triangles whose circumcircle contain
-// the point
-// Author: chynes
-// Date: 6/3/2002
-//-------------------------------------------------------------------------
-template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
-CubitStatus FacetorTool<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::natural_neighbor_tris(
- CubitVector &the_point,
- DLIList <TRI *> &tri_list)
-{
- CubitStatus rv = CUBIT_SUCCESS;
-
- // find the triangle the point is contained in
-
- //CubitVector areacoord;
- TRI *tri_ptr;
- rv = locate_point( the_point, tri_ptr );
-
- // keep track of visitation to triangles by incrementing curVisitFlag
- // and comparing with the visit flag stored with the triangle
-
- curVisitFlag++;
-
- // Recursively search, (starting with the tri the point is in)
- // search for all tris whose circumcircle contain the point and place
- // in the tri_list
-
- if (rv == CUBIT_SUCCESS)
- {
- tri_list.append( tri_ptr );
- tri_visited( tri_ptr, CUBIT_TRUE );
- int iedge;
- TRI *adjtri_ptr;
- for (iedge=0; iedge<3 && rv == CUBIT_SUCCESS; iedge++)
- {
- int ii = iedge;
- adjtri_ptr = tri_ptr->adjacent( ii, refFacePtr );
- if (adjtri_ptr != NULL && !tri_visited( adjtri_ptr )){
- rv = point_in_circumcircle( the_point, adjtri_ptr, tri_list );
- }
- }
- }
- return rv;
-}
-
-
-//-------------------------------------------------------------------------
-// Function: locate_point
-// Description: return the triangle the point is located in
-// Author: chynes
-// Date: 6/3/2002
-//-------------------------------------------------------------------------
-template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
-CubitStatus FacetorTool<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::locate_point( CubitVector &the_point,
- TRI *&tri_ptr )
-{
- CubitStatus rv = CUBIT_SUCCESS;
-
- // start with the last one found
-
- if (lastTriLocated != NULL)
- tri_ptr = lastTriLocated;
-
- // otherwise use the first one on the list
-
- else
- {
- tri_ptr = facetList->get();
- }
-
-
- // loop until we find something
-
- NODE *n0, *n1, *n2;
- double aa, bb, cc;
- CubitBoolean found = CUBIT_FALSE;
-
- //avoiding infinite loop
- int counter = 0;
- int max_count = facetList->size();
-
- while(!found && rv == CUBIT_SUCCESS)
- {
- tri_ptr->tri_nodes( n0, n1, n2 );
- aa = DETERM(the_point.x(), the_point.y(),
- n1->coordinates().x(), n1->coordinates().y(),
- n2->coordinates().x(), n2->coordinates().y());
- bb = DETERM(n0->coordinates().x(), n0->coordinates().y(),
- the_point.x(), the_point.y(),
- n2->coordinates().x(), n2->coordinates().y());
- cc = DETERM(n0->coordinates().x(), n0->coordinates().y(),
- n1->coordinates().x(), n1->coordinates().y(),
- the_point.x(), the_point.y());
- if (aa > -FT_INSIDE_TOL &&
- bb > -FT_INSIDE_TOL &&
- cc > -FT_INSIDE_TOL)
- {
- found = CUBIT_TRUE; // this is the one
- }
- else
- {
- // set up to check the next logical neighbor
- if (aa <= bb && aa <= cc)
- {
- int edge_index = 1;
- tri_ptr = tri_ptr->adjacent( edge_index, refFacePtr );
- }
- else if (bb <= aa && bb <= cc)
- {
- int edge_index = 2;
- tri_ptr = tri_ptr->adjacent( edge_index, refFacePtr );
- }
- else
- {
- int edge_index = 0;
- tri_ptr = tri_ptr->adjacent( edge_index, refFacePtr );
- }
- // check to see if we've left the triangulation
- // also make sure that we are not stuck in a cycle
- if (tri_ptr == NULL || counter > max_count)
- {
- if(counter>max_count){
- PRINT_WARNING("Encountered problem locating a triangle; going to exhaustive search.\n");
- }
- rv = exhaustive_locate_point(the_point, tri_ptr );
- found = CUBIT_TRUE;
- }
- }
- ++counter;
- }
-
- lastTriLocated = tri_ptr;
-
- return rv;
-}
-
-//-------------------------------------------------------------------------
-// Function: exhaustive_locate_point
-// Description: return the triangle the point is located in by checking
-// all triangles
-// Author: chynes
-// Date: 6/3/2002
-//-------------------------------------------------------------------------
-template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
-CubitStatus FacetorTool<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::exhaustive_locate_point(
- CubitVector &the_point,
- TRI *&tri_ptr )
-{
- CubitStatus rv = CUBIT_SUCCESS;
-
-
- // loop until we find something
-
- int ii;
- NODE *n0, *n1, *n2;
- double aa, bb, cc;
- CubitBoolean found = CUBIT_FALSE;
- for (ii=0; ii<facetList->size() && !found; ii++)
- {
- tri_ptr = facetList->get_and_step();
- tri_ptr->tri_nodes( n0, n1, n2 );
- aa = DETERM(the_point.x(), the_point.y(),
- n1->coordinates().x(), n1->coordinates().y(),
- n2->coordinates().x(), n2->coordinates().y());
- bb = DETERM(n0->coordinates().x(), n0->coordinates().y(),
- the_point.x(), the_point.y(),
- n2->coordinates().x(), n2->coordinates().y());
- cc = DETERM(n0->coordinates().x(), n0->coordinates().y(),
- n1->coordinates().x(), n1->coordinates().y(),
- the_point.x(), the_point.y());
- if (aa > -FT_INSIDE_TOL &&
- bb > -FT_INSIDE_TOL &&
- cc > -FT_INSIDE_TOL)
- {
- found = CUBIT_TRUE; // this is the one
- }
- }
- if (!found)
- {
- rv = CUBIT_FAILURE;
- tri_ptr = NULL;
- }
-
- return rv;
-}
-
-//-------------------------------------------------------------------------
-// Function: are_nodes_colinear
-// Description: determine if the TRI is valid
-// Author: mbrewer
-// Date: 6/3/2002
-//-------------------------------------------------------------------------
-template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
-CubitBoolean FacetorTool<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::are_nodes_colinear( TRI *tri_ptr )
-{
- NODE *nodes[3];
- tri_ptr->tri_nodes( nodes[0], nodes[1], nodes[2] );
- double det = DETERM( nodes[0]->coordinates().x(),
- nodes[0]->coordinates().y(),
- nodes[1]->coordinates().x(),
- nodes[1]->coordinates().y(),
- nodes[2]->coordinates().x(),
- nodes[2]->coordinates().y());
- //PRINT_INFO("Det = %f\n",det);
-
- if(fabs(det) > CUBIT_DBL_MIN){
- return CUBIT_TRUE;
- }
- return CUBIT_FALSE;
-
-}
-
-//-------------------------------------------------------------------------
-// Function: point_in_circumcircle
-// Description: determine if the point is inside the circumcircle of the
-// triangle and recurse to the adjacent triangles
-// Author: chynes
-// Date: 6/3/2002
-//-------------------------------------------------------------------------
-template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
-CubitStatus FacetorTool<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::point_in_circumcircle(
- CubitVector &the_point,
- TRI *tri_ptr,
- DLIList <TRI *> &tri_list)
-{
- CubitStatus rv = CUBIT_SUCCESS;
-
- // check this triangle. If the nodes are colinear do not try to calculate
- //the circumcenter.
- if(!are_nodes_colinear(tri_ptr))
- {
- PRINT_ERROR("Can't evaluate center of circumcircle\n");
- return CUBIT_FAILURE;
- }
-
- CubitVector cc = circumcenter( tri_ptr );
- tri_visited( tri_ptr, CUBIT_TRUE );
- double dist2 = SQR(the_point.x() - cc.x()) + SQR(the_point.y() - cc.y());
- double r2 = radius( tri_ptr );
- double tol_factor = CUBIT_MAX(CUBIT_MAX(tri_ptr->edge(0)->length(),
- tri_ptr->edge(1)->length()),
- tri_ptr->edge(2)->length());
- //PRINT_INFO("Tolerance factor = %f\n", tol_factor);
-
-
-
- if (r2-dist2 > -(tol_factor*FT_INSIDE_TOL*FT_INSIDE_TOL))// inside or on circle
- {
- tri_list.append( tri_ptr );
-
- // go to its neighbors
-
- int iedge;
- TRI *adjtri_ptr;
- for (iedge=0; iedge<3 && rv == CUBIT_SUCCESS; iedge++){
-
- int ii = iedge;
- adjtri_ptr = tri_ptr->adjacent( ii, refFacePtr );
- if (adjtri_ptr != NULL && !tri_visited( adjtri_ptr ))
- {
- rv = point_in_circumcircle( the_point, adjtri_ptr, tri_list );
- }
- }
- }
- return rv;
-}
-
-
-//-------------------------------------------------------------------------
// Function: constrain_boundary
// Description: recover the boundary edges from the mesh
// Author: chynes
@@ -1121,19 +542,33 @@
// classify the triangles based on their minimum angle
- //rv =
- classify_triangles(tri_list);
+ //rv =
+ const int num_lists = 64;
+ const double interval = QUALITY_ANGLE / double( num_lists - 1 );
+ DLIList<TRI*>* tri_sort_array = new DLIList<TRI *> [num_lists];
+ classify_triangles(tri_list, tri_sort_array, num_lists, interval );
// process each of the triangles until done
TRI *tri_ptr;
- while ((tri_ptr = next_triangle()) != NULL && rv == CUBIT_SUCCESS)
+ TRI* start_tri = NULL;
+ while ((tri_ptr = next_triangle(tri_sort_array, num_lists)) != NULL && rv == CUBIT_SUCCESS)
{
- rv = insert_at_circumcenter( tri_ptr );
+ rv = FacetorUtil<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::insert_at_circumcenter(tri_ptr,
+ *facetList,
+ start_tri,
+ curVisitFlag,
+ refFacePtr,
+ tri_sort_array,
+ num_lists,
+ interval,
+ QUALITY_ANGLE,
+ sizingFunction,
+ pTool);
}
- delete [] triSortArray;
- triSortArray = NULL;
+ delete [] tri_sort_array;
+ tri_sort_array = NULL;
return rv;
}
@@ -1145,7 +580,10 @@
// Date: 6/3/2002
//-------------------------------------------------------------------------
template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
-CubitStatus FacetorTool<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::classify_triangles(DLIList<TRI *> &tri_list)
+CubitStatus FacetorTool<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::classify_triangles(DLIList<TRI *> &tri_list,
+ DLIList<TRI*>* sorted_lists,
+ const int num_lists,
+ const double interval)
{
CubitStatus rv = CUBIT_SUCCESS;
@@ -1154,8 +592,6 @@
// fall within a specified interval. Triangles will be processed
// from smallest angle to best angle
- triSortArray = new DLIList<TRI *> [NUM_SORT_LISTS];
-
// classify each trriangle and place into sort lists
TRI *tri_ptr;
@@ -1164,89 +600,14 @@
{
tri_ptr = tri_list.get_and_step();
//rv =
- classify_tri_by_angle( tri_ptr );
+ FacetorUtil<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::classify_tri_by_angle(
+ tri_ptr, sorted_lists, num_lists, interval, QUALITY_ANGLE);
}
return rv;
}
-//-------------------------------------------------------------------------
-// Function: classify_tri_by_angle
-// Description: compute the angles at the triangle vertices and classify
-// by its worst triangle
-// Author: chynes
-// Date: 6/3/2002
-//-------------------------------------------------------------------------
-template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
-CubitStatus FacetorTool<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::classify_tri_by_angle( TRI *tri_ptr )
-{
- //CubitStatus rv = CUBIT_SUCCESS;
- // Determine the minimum angle
-
- NODE *nodes[3];
- tri_ptr->tri_nodes( nodes[0], nodes[1], nodes[2] );
- double x0 = nodes[0]->coordinates().x();
- double y0 = nodes[0]->coordinates().y();
- double x1 = nodes[1]->coordinates().x();
- double y1 = nodes[1]->coordinates().y();
- double x2 = nodes[2]->coordinates().x();
- double y2 = nodes[2]->coordinates().y();
-
- double ax = x1 - x0;
- double ay = y1 - y0;
- double bx = x2 - x0;
- double by = y2 - y0;
- double dot = ax*bx + ay*by;
- double a_mag = sqrt( ax*ax + ay*ay );
- double b_mag = sqrt( bx*bx + by*by );
- double angle0 = dot / ( a_mag * b_mag );
- angle0 = acos( angle0 );
-
- ax = -ax;
- ay = -ay;
- bx = x2 - x1;
- by = y2 - y1;
- dot = ax*bx + ay*by;
- b_mag = sqrt( bx*bx + by*by );
- double angle1 = dot / ( a_mag * b_mag );
- angle1 = acos( angle1 );
-
- double angle2 = CUBIT_PI - angle0 - angle1;
-
- double min_angle = CUBIT_MIN( CUBIT_MIN(angle0,angle1),
- CUBIT_MIN(angle1,angle2) );
- if (min_angle < 0.0) {
- assert(0);
- return CUBIT_FAILURE;
- }
-
- // If it is greater than the QUALITY_ANGLE then place it in
- // the triSortArray[0], otherwise place it in one of the other deques
- // depending upon its minimum angle
-
- // Determine which list
-
- int index;
- if (min_angle >= QUALITY_ANGLE) {
- index = 0;
- }
- else {
- index = 1 + (int)(min_angle/INTERVAL);
- if (index < 1) index = 1;
- if (index > NUM_SORT_LISTS-1) index = NUM_SORT_LISTS-1;
- }
-
- // Place it on a list
-
- triSortArray[index].append( tri_ptr );
- tri_sort_list( tri_ptr, index );
-
- return CUBIT_SUCCESS;
-
-}
-
-
//-------------------------------------------------------------------------
// Function: next_triangle
// Description: get the next triangle to process
@@ -1254,231 +615,25 @@
// Date: 6/3/2002
//-------------------------------------------------------------------------
template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
-TRI *FacetorTool<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::next_triangle(void)
+TRI *FacetorTool<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::next_triangle(DLIList<TRI*>* sorted_lists,
+ const int num_lists)
{
TRI *tri_ptr = NULL;
int ii;
- for(ii=1; ii<NUM_SORT_LISTS && tri_ptr == NULL; ii++)
+ for( ii = 1; ii < num_lists && tri_ptr == NULL; ii++)
{
- if (triSortArray[ii].size() > 0)
- tri_ptr = triSortArray[ii].remove();
+ if (sorted_lists[ii].size() > 0)
+ tri_ptr = sorted_lists[ii].remove();
}
if (tri_ptr == NULL)
{
- if (triSortArray[0].size() > 0)
- tri_ptr = triSortArray[0].remove();
+ if (sorted_lists[0].size() > 0)
+ tri_ptr = sorted_lists[0].remove();
}
return tri_ptr;
}
-//-------------------------------------------------------------------------
-// Function: get_size
-// Description: get the distortion factor for point inside tri, if one exists
-// otherwise return 1;
-// Author: chynes
-// Date: 7/24/02
-//-------------------------------------------------------------------------
-template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
-double FacetorTool<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::get_size(CubitVector &cc, TRI *tri_ptr)
-{
- //extract data
- NODE *n0,*n1,*n2;
- CubitVector area_coord;
- tri_ptr->tri_nodes(n0,n1,n2);
-
- if (n0->coordinates().z() - 1.0 < fabs(FT_INSIDE_TOL)
- && n1->coordinates().z() - 1.0 < fabs(FT_INSIDE_TOL)
- && n2->coordinates().z() - 1.0 < fabs(FT_INSIDE_TOL) )
- return 1.0;
- else
- {
- //get vectors
- CubitVector v0 = n0->coordinates();
- CubitVector v1 = n1->coordinates();
- CubitVector v2 = n2->coordinates();
- //set z direction
- v0.z(cc.z());
- v1.z(cc.z());
- v2.z(cc.z());
-
- //create points
- CubitPoint *p0 = (CubitPoint*) new CubitPointData(v0);
- CubitPoint *p1 = (CubitPoint*) new CubitPointData(v1);
- CubitPoint *p2 = (CubitPoint*) new CubitPointData(v2);
-
- //create facet
- CubitFacet *temp_facet = (CubitFacet*) new CubitFacetData(p0,p1,p2);
-
- FacetEvalTool::facet_area_coordinate(temp_facet, cc, area_coord);
-
- delete p0;
- delete p1;
- delete p2;
- delete temp_facet;
-
- return (area_coord.x()*n0->coordinates().z())
- + (area_coord.y()*n1->coordinates().z())
- + (area_coord.z()*n2->coordinates().z());
- }
-
-}
-
//-------------------------------------------------------------------------
-// Function: insert_at_circumcenter
-// Description: insert a node at the circumcenter of a tri
-// Author: chynes
-// Date: 6/3/2002
-//-------------------------------------------------------------------------
-template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
-CubitStatus FacetorTool<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::insert_at_circumcenter(TRI *tri_ptr)
-{
- CubitStatus rv = CUBIT_SUCCESS;
-
- // find the cicumcenter of the triangle and the target size there
- //if nodes are colinear do not try to find circumenter
- if(!are_nodes_colinear(tri_ptr))
- {
- PRINT_ERROR("Can't evaluate center of circumcircle\n");
- return CUBIT_FAILURE;
- }
- CubitVector cc = circumcenter( tri_ptr );
-
- //translate cc into 3D space
- CubitVector cc_xyz;
- pTool->transform_to_xyz(cc_xyz, cc);
- // get target length in 3D space
- double target_length = sizingFunction->size_at_point( cc_xyz );
- // get new size
- double size = get_size(cc, tri_ptr);
- // update size
- cc.z(size);
- // update target_length
- target_length = target_length*size;
-
- // Determine if we should now insert the point. Allow insertions
- // in the general case down to circumcircle size of ALPHA times the
- // interpolated target edge length size. For tris with small
- // angles, allow additional inserts to improve the quality down
- // to 1/2 the target size
- if(!are_nodes_colinear(tri_ptr))
- {
- PRINT_ERROR("Can't evaluate radius of circumcircle\n");
- return CUBIT_FAILURE;
- }
-
-
- double r2 = radius( tri_ptr );
- CubitBoolean insert = CUBIT_FALSE;
- int tsindex = tri_sort_list( tri_ptr );
- assert(tsindex > -1);
- if (tsindex == 0)
- {
- if (r2 > SQR(ALPHA*target_length))
- {
- insert = CUBIT_TRUE;
- }
- }
- else
- {
- if (r2 > SQR(0.5*ALPHA*target_length))
- {
- insert = CUBIT_TRUE;
- }
- }
- if (insert)
- {
-
- // Determine the tris that will be affected by the insertion
-
- lastTriLocated = tri_ptr;
- DLIList <TRI *> tri_list;
- rv = natural_neighbor_tris( cc, tri_list );
- // If it was outside, then we are done with it
-
- if (tri_list.size() == 0)
- {
- return CUBIT_SUCCESS;
- }
- if (rv != CUBIT_SUCCESS) {
- return rv;
- }
-
- // See if we are too close to a boundary
-
- double x0, y0, x1, y1, cx, cy, edge_radius, dist;
- TRI *nntri_ptr;
- EDGE *edge_ptr;
- int ii, iedge;
- for (ii=0; ii<tri_list.size(); ii++)
- {
- nntri_ptr = tri_list.get_and_step();
- for (iedge=0; iedge<3; iedge++)
- {
- edge_ptr = tri_ptr->edge( iedge );
-
- // An edge encroaches if the distance from the prospective
- // new point to the midpoint of the edge is less than
- // half the length of the edge
-
- if (edge_ptr->marked()) // on the boundary?
- {
- x0 = (edge_ptr->start_node())->coordinates().x();
- y0 = (edge_ptr->start_node())->coordinates().y();
- x1 = (edge_ptr->end_node())->coordinates().x();
- y1 = (edge_ptr->end_node())->coordinates().y();
- cx = (x0 + x1) * 0.5;
- cy = (y0 + y1) * 0.5;
- edge_radius = sqrt(SQR(x1-x0) + SQR(y1-y0)) * 0.5;
- dist = sqrt( SQR(cx-cc.x()) + SQR(cy-cc.y()) );
-
- // Edge encroaches: don't insert, return now
-
- if (dist - edge_radius < FT_INSIDE_TOL)
- {
- return CUBIT_SUCCESS;
- }
- }
- }
- }
-
- // Before inserting, remove all the tris on the neighbor
- // tri_list from the lists
-
- int index;
- for (ii=0; ii<tri_list.size(); ii++)
- {
- nntri_ptr = tri_list.get_and_step();
- index = tri_sort_list( nntri_ptr );
- assert(index >= 0);
- triSortArray[index].remove( nntri_ptr );
- }
-
- // Create the new node
-
- NODE *new_node_ptr = (NODE *)new NODECHILD( cc, refFacePtr );
-
- // Insert the new node into the mesh
-
- rv = bowyer_watson_insert( new_node_ptr, tri_list );
- if (rv != CUBIT_SUCCESS)
- return rv;
-
- // get the new tris at the node and classify them
-
- tri_list.clean_out();
- new_node_ptr->tris( tri_list );
- for (ii=0; ii<tri_list.size() && rv == CUBIT_SUCCESS; ii++)
- {
- tri_ptr = tri_list.get_and_step();
- rv = classify_tri_by_angle( tri_ptr );
- }
- }
-
- return rv;
-
-}
-
-//-------------------------------------------------------------------------
// Function: clean_up_data
// Description: clean up any data we've allocated
// Author: chynes
@@ -1546,7 +701,6 @@
if (edge_ptr)
edge_ptr->marked( CUBIT_FALSE );
}
-
}
// EOF
Modified: cgm/branches/cubit/geom/Cholla/FacetorTool.hpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/FacetorTool.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/FacetorTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -68,16 +68,9 @@
//- bounding edges on the surfaces represented by their start
//- and end nodes
- DLIList<TRI*> *triSortArray;
- // array of lists of triangles sorted by their worst angle
-
NODE *boxNodes[4];
//- temporary nodes created enclosing the surface to facilitate
//- Delaunay node insertion
-
- TRI *lastTriLocated;
- //TRI *debugTri;
- //- last triangle the locate point function found
int curVisitFlag;
//- current visited flag for triangles
@@ -88,57 +81,9 @@
CubitStatus init_box();
//- create two initial bounding triangles
- CubitVector &circumcenter( TRI *tri_ptr );
- //- get the circumcenter of the triangle
-
- double radius( TRI *tri_ptr );
- //- get the radius squared of the triangle circumcircle
-
- CubitBoolean tri_visited( TRI *tri_ptr );
- void tri_visited( TRI *tri_ptr, CubitBoolean visited );
- //- get and set the visited flag
-
- void tri_sort_list( TRI *tri_ptr, int sort_list_index );
- int tri_sort_list( TRI *tri_ptr );
- //- get and set the tri sort array index that this tri is in
-
CubitStatus insert_nodes( DLIList<NODE *> *&bounding_nodes );
//- insert a list of nodes into an existing triangulation
- CubitStatus insert_node( NODE *node_ptr );
- //- nsert one node into Delaunay mesh
-
- CubitBoolean are_nodes_colinear( TRI *tri_ptr );
- //- are the nodes of this tri roughly colinear
-
- CubitStatus bowyer_watson_insert( NODE *node_ptr,
- DLIList<TRI *> &tri_list);
- //- Bowyer-Watson insertion into an existing Delaunay Mesh
- CubitStatus valid_void( NODE *node_ptr,
- DLIList<TRI *> &tri_list);
- //check the void created in Bowyer-Watson to ensure the boundary
- //seems valid.
-
- CubitStatus natural_neighbor_tris( CubitVector &the_point,
- DLIList <TRI *> &tri_list);
- //- get a list of all triangles whose circumcircle contain
- //- the point
-
- CubitStatus locate_point( CubitVector &the_point,
- TRI *&tri_ptr );
- //- return the triangle the point is located in
-
- CubitStatus exhaustive_locate_point( CubitVector &the_point,
- TRI *&tri_ptr );
- //- return the triangle the point is located in by checking
- //- all triangles
-
- CubitStatus point_in_circumcircle( CubitVector &the_point,
- TRI *tri_ptr,
- DLIList <TRI *> &tri_list );
- //- determine if the point is inside the circumcircle of the
- //- triangle and recurse to the adjacent triangles
-
CubitStatus constrain_boundary(void);
//- recover the boundary edges from the mesh
@@ -157,20 +102,15 @@
//- improve quality. This inserts nodes at the circumcenters of
//- triangles roughly based on the algorithm by Jonathon Shewchuk
- CubitStatus classify_triangles(DLIList<TRI *> &tri_list);
+ CubitStatus classify_triangles(DLIList<TRI *> &tri_list,
+ DLIList<TRI*>* sorted_lists,
+ const int num_lists,
+ const double interval);
//- order the triangles in the current mesh by their worst angle
- CubitStatus classify_tri_by_angle( TRI *tri_ptr );
- //- compute the angles at the triangle vertices and classify
- //- by its worst triangle
-
- TRI *next_triangle(void);
- //- get the next triangle to process
-
- double get_size(CubitVector &cc, TRI *tri_ptr);
-
- CubitStatus insert_at_circumcenter(TRI *tri_ptr);
- //- insert a node at the circumcenter of a tri
+ TRI *next_triangle(DLIList<TRI*>* sorted_lists,
+ const int num_lists);
+ //- get the next triangle to process;
void clean_up_data(void);
//- clean up any data we've allocated
Added: cgm/branches/cubit/geom/Cholla/FacetorUtil.cpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/FacetorUtil.cpp (rev 0)
+++ cgm/branches/cubit/geom/Cholla/FacetorUtil.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,934 @@
+
+#ifdef INLINE_TEMPLATES
+#define MY_INLINE inline
+#else
+#define MY_INLINE
+#endif
+
+#include "FacetorUtil.hpp"
+#include "TDDelaunay.hpp"
+#include "FacetEvalTool.hpp"
+#include "CubitPoint.hpp"
+#include "CubitPointData.hpp"
+#include "CubitFacet.hpp"
+#include "CubitFacetData.hpp"
+#include "ParamTool.hpp"
+
+#define DETERM(p1,q1,p2,q2,p3,q3)\
+ ((q3)*((p2)-(p1)) + (q2)*((p1)-(p3)) + (q1)*((p3)-(p2)))
+#define FT_INSIDE_TOL 1.0e-6
+#define SQR(x) ((x) * (x))
+#define ALPHA 0.70228615
+
+template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
+CubitStatus
+FacetorUtil<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::locate_point(
+ CubitVector& the_point,
+ DLIList<TRI*>& facet_list,
+ TRI* starting_tri,
+ SURF* owning_surface,
+ TRI*& tri_ptr)
+{
+ CubitStatus rv = CUBIT_SUCCESS;
+
+ // start with the last one found
+
+ if (starting_tri != NULL)
+ tri_ptr = starting_tri;
+
+ // otherwise use the first one on the list
+
+ else
+ {
+ tri_ptr = facet_list.get();
+ }
+
+
+ // loop until we find something
+
+ NODE *n0, *n1, *n2;
+ double aa, bb, cc;
+ CubitBoolean found = CUBIT_FALSE;
+
+ //avoiding infinite loop
+ int counter = 0;
+ int max_count = facet_list.size();
+
+ while(!found && rv == CUBIT_SUCCESS)
+ {
+ tri_ptr->tri_nodes( n0, n1, n2 );
+ aa = DETERM(the_point.x(), the_point.y(),
+ n1->coordinates().x(), n1->coordinates().y(),
+ n2->coordinates().x(), n2->coordinates().y());
+ bb = DETERM(n0->coordinates().x(), n0->coordinates().y(),
+ the_point.x(), the_point.y(),
+ n2->coordinates().x(), n2->coordinates().y());
+ cc = DETERM(n0->coordinates().x(), n0->coordinates().y(),
+ n1->coordinates().x(), n1->coordinates().y(),
+ the_point.x(), the_point.y());
+ if (aa > -FT_INSIDE_TOL &&
+ bb > -FT_INSIDE_TOL &&
+ cc > -FT_INSIDE_TOL)
+ {
+ found = CUBIT_TRUE; // this is the one
+ }
+ else
+ {
+ // set up to check the next logical neighbor
+ if (aa <= bb && aa <= cc)
+ {
+ int edge_index = 1;
+ tri_ptr = tri_ptr->adjacent( edge_index, owning_surface );
+ }
+ else if (bb <= aa && bb <= cc)
+ {
+ int edge_index = 2;
+ tri_ptr = tri_ptr->adjacent( edge_index, owning_surface );
+ }
+ else
+ {
+ int edge_index = 0;
+ tri_ptr = tri_ptr->adjacent( edge_index, owning_surface );
+ }
+ // check to see if we've left the triangulation
+ // also make sure that we are not stuck in a cycle
+ if (tri_ptr == NULL || counter > max_count)
+ {
+ if(counter>max_count){
+ PRINT_WARNING("Encountered problem locating a triangle; going to exhaustive search.\n");
+ }
+
+ rv = exhaustive_locate_point( the_point, facet_list, tri_ptr );
+ found = CUBIT_TRUE;
+ }
+ }
+ ++counter;
+ }
+
+ return rv;
+}
+
+template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
+CubitStatus
+FacetorUtil<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::exhaustive_locate_point(
+ CubitVector& the_point,
+ DLIList<TRI*>& facet_list,
+ TRI*& tri_ptr)
+{
+ CubitStatus rv = CUBIT_SUCCESS;
+
+ // loop until we find something
+
+ int ii;
+ NODE *n0, *n1, *n2;
+ double aa, bb, cc;
+ CubitBoolean found = CUBIT_FALSE;
+ for (ii=0; ii<facet_list.size() && !found; ii++)
+ {
+ tri_ptr = facet_list.get_and_step();
+ tri_ptr->tri_nodes( n0, n1, n2 );
+ aa = DETERM(the_point.x(), the_point.y(),
+ n1->coordinates().x(), n1->coordinates().y(),
+ n2->coordinates().x(), n2->coordinates().y());
+ bb = DETERM(n0->coordinates().x(), n0->coordinates().y(),
+ the_point.x(), the_point.y(),
+ n2->coordinates().x(), n2->coordinates().y());
+ cc = DETERM(n0->coordinates().x(), n0->coordinates().y(),
+ n1->coordinates().x(), n1->coordinates().y(),
+ the_point.x(), the_point.y());
+ if (aa > -FT_INSIDE_TOL &&
+ bb > -FT_INSIDE_TOL &&
+ cc > -FT_INSIDE_TOL)
+ {
+ found = CUBIT_TRUE; // this is the one
+ }
+ }
+ if (!found)
+ {
+ rv = CUBIT_FAILURE;
+ tri_ptr = NULL;
+ }
+
+ return rv;
+}
+
+//-------------------------------------------------------------------------
+// Function: are_nodes_colinear
+// Description: determine if the TRI is valid
+// Author: mbrewer
+// Date: 6/3/2002
+//-------------------------------------------------------------------------
+template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
+CubitBoolean
+FacetorUtil<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::are_nodes_colinear(TRI* tri_ptr)
+{
+ NODE *nodes[3];
+ tri_ptr->tri_nodes( nodes[0], nodes[1], nodes[2] );
+ double det = DETERM( nodes[0]->coordinates().x(),
+ nodes[0]->coordinates().y(),
+ nodes[1]->coordinates().x(),
+ nodes[1]->coordinates().y(),
+ nodes[2]->coordinates().x(),
+ nodes[2]->coordinates().y());
+ //PRINT_INFO("Det = %f\n",det);
+
+ if(fabs(det) > CUBIT_DBL_MIN){
+ return CUBIT_TRUE;
+ }
+ return CUBIT_FALSE;
+}
+
+//-------------------------------------------------------------------------
+// Function: circumcenter
+// Description: get the circumcenter of the triangle
+// Author: chynes
+// Date: 6/6/2002
+//-------------------------------------------------------------------------
+template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
+CubitVector&
+FacetorUtil<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::circumcenter(TRI* tri_ptr)
+{
+ ToolData *td = tri_ptr->get_TD( TDDelaunay<TRI,NODE>::is_delaunay );
+ TDDelaunay< TRI, NODE > *td_del = dynamic_cast<TDDelaunay< TRI, NODE >*> (td);
+ if(td_del == NULL) {
+ td_del = new TDDelaunay<TRI, NODE>();
+ tri_ptr->add_TD( td_del );
+ }
+ return td_del->circumcenter2d( tri_ptr );
+}
+
+//-------------------------------------------------------------------------
+// Function: tri_visited
+// Description: set the tri_visited flag
+// Author: chynes
+// Date: 6/6/2002
+//-------------------------------------------------------------------------
+template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
+CubitBoolean
+FacetorUtil<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::tri_visited(
+ TRI *tri_ptr,
+ int curr_visit_flag)
+{
+ ToolData *td = tri_ptr->get_TD( TDDelaunay< TRI, NODE >::is_delaunay );
+ TDDelaunay< TRI, NODE > *td_del = dynamic_cast<TDDelaunay< TRI, NODE >*> (td);
+ if (td_del == NULL)
+ {
+ td_del = new TDDelaunay< TRI, NODE >();
+ tri_ptr->add_TD( td_del );
+ }
+ return (td_del->visit_flag() == curr_visit_flag);
+}
+
+//-------------------------------------------------------------------------
+// Function: tri_visited
+// Description: set the tri_visited flag
+// Author: chynes
+// Date: 6/3/2002
+//-------------------------------------------------------------------------
+template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
+void
+FacetorUtil<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::tri_visited(
+ TRI *facet_ptr,
+ CubitBoolean visited,
+ int curr_visit_flag)
+{
+ ToolData *td = facet_ptr->get_TD( TDDelaunay< TRI, NODE >::is_delaunay );
+ TDDelaunay< TRI, NODE > *td_del = dynamic_cast<TDDelaunay< TRI, NODE >*> (td);
+ if (td_del == NULL)
+ {
+ td_del = new TDDelaunay< TRI, NODE >();
+ facet_ptr->add_TD( td_del );
+ }
+ if (visited)
+ td_del->visit_flag(curr_visit_flag);
+ else
+ td_del->visit_flag(INT_MIN);
+}
+
+//-------------------------------------------------------------------------
+// Function: radius
+// Description: get the radius squared of the triangle circumcircle
+// Author: chynes
+// Date: 6/6/2002
+//-------------------------------------------------------------------------
+template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
+double
+FacetorUtil<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::radius(TRI* tri_ptr)
+{
+ ToolData *td = tri_ptr->get_TD( TDDelaunay< TRI, NODE >::is_delaunay );
+ TDDelaunay< TRI, NODE > *td_del = dynamic_cast<TDDelaunay< TRI, NODE >*> (td);
+ if (td_del == NULL)
+ {
+ td_del = new TDDelaunay< TRI, NODE >();
+ tri_ptr->add_TD( td_del );
+ }
+ return td_del->radius2d( tri_ptr );
+}
+
+//-------------------------------------------------------------------------
+// Function: point_in_circumcircle
+// Description: determine if the point is inside the circumcircle of the
+// triangle and recurse to the adjacent triangles
+// Author: chynes
+// Date: 6/3/2002
+//-------------------------------------------------------------------------
+template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
+CubitStatus
+FacetorUtil<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::point_in_circumcircle(
+ CubitVector& the_point,
+ TRI* tri_ptr,
+ DLIList<TRI*>& tri_list,
+ SURF* surface_ptr,
+ int curr_visit_flag)
+{
+ CubitStatus rv = CUBIT_SUCCESS;
+
+ // check this triangle. If the nodes are colinear do not try to calculate
+ //the circumcenter.
+ if(!are_nodes_colinear(tri_ptr))
+ {
+ PRINT_ERROR("Can't evaluate center of circumcircle\n");
+ return CUBIT_FAILURE;
+ }
+
+ CubitVector cc = circumcenter( tri_ptr );
+ tri_visited( tri_ptr, CUBIT_TRUE, curr_visit_flag );
+ double dist2 = SQR(the_point.x() - cc.x()) + SQR(the_point.y() - cc.y());
+ double r2 = radius( tri_ptr );
+ double tol_factor = CUBIT_MAX(CUBIT_MAX(tri_ptr->edge(0)->length(),
+ tri_ptr->edge(1)->length()),
+ tri_ptr->edge(2)->length());
+ //PRINT_INFO("Tolerance factor = %f\n", tol_factor);
+
+
+
+ if (r2-dist2 > -(tol_factor*FT_INSIDE_TOL*FT_INSIDE_TOL))// inside or on circle
+ {
+ tri_list.append( tri_ptr );
+
+ // go to its neighbors
+
+ int iedge;
+ TRI *adjtri_ptr;
+ for (iedge=0; iedge<3 && rv == CUBIT_SUCCESS; iedge++){
+
+ int ii = iedge;
+ adjtri_ptr = tri_ptr->adjacent( ii, surface_ptr );
+ if (adjtri_ptr != NULL && !tri_visited( adjtri_ptr, curr_visit_flag ))
+ {
+ rv = point_in_circumcircle( the_point, adjtri_ptr, tri_list,
+ surface_ptr, curr_visit_flag );
+ }
+ }
+ }
+ return rv;
+}
+
+//-------------------------------------------------------------------------
+// Function: natural_neighbor_tris
+// Description: get a list of all triangles whose circumcircle contain
+// the point
+// Author: chynes
+// Date: 6/3/2002
+//-------------------------------------------------------------------------
+template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
+CubitStatus
+FacetorUtil<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::natural_neighbor_tris(
+ CubitVector& the_point,
+ DLIList<TRI*>& facet_list,
+ TRI*& start_tri,
+ SURF* surface_ptr,
+ int& curr_visit_flag,
+ DLIList<TRI*>& tri_list)
+{
+ CubitStatus rv = CUBIT_SUCCESS;
+
+ // find the triangle the point is contained in
+
+ //CubitVector areacoord;
+ TRI *tri_ptr;
+ rv = locate_point( the_point, facet_list, start_tri, surface_ptr, tri_ptr );
+ start_tri = tri_ptr;
+
+ // keep track of visitation to triangles by incrementing curr_visit_flag
+ // and comparing with the visit flag stored with the triangle
+
+ curr_visit_flag++;
+
+ // Recursively search, (starting with the tri the point is in)
+ // search for all tris whose circumcircle contain the point and place
+ // in the tri_list
+
+ if (rv == CUBIT_SUCCESS)
+ {
+ tri_list.append( tri_ptr );
+ tri_visited( tri_ptr, CUBIT_TRUE, curr_visit_flag );
+ int iedge;
+ TRI *adjtri_ptr;
+ for (iedge=0; iedge<3 && rv == CUBIT_SUCCESS; iedge++)
+ {
+ int ii = iedge;
+ adjtri_ptr = tri_ptr->adjacent( ii, surface_ptr );
+ if (adjtri_ptr != NULL && !tri_visited( adjtri_ptr, curr_visit_flag )){
+ rv = point_in_circumcircle( the_point, adjtri_ptr,
+ tri_list, surface_ptr,
+ curr_visit_flag);
+ }
+ }
+ }
+ return rv;
+}
+
+/************************************************************/
+//author: mbrewer
+//This function performs tests on the void created by a point's
+//insertion to make sure that invalid connectivities are not
+//being created.
+/************************************************************/
+template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
+CubitStatus
+FacetorUtil<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::valid_void(
+ NODE * /*point_ptr*/,
+ DLIList<TRI *> &tri_list,
+ SURF* surface_ptr,
+ int curr_visit_flag)
+{
+ int temp_i, temp_j;
+ DLIList<EDGE*> boundary_edge_list;
+ DLIList<NODE*> boundary_node_list;
+ TRI *adjtri_ptr;
+ TRI *tri_ptr;
+ EDGE *edge_ptr;
+ DLIList<EDGE *> edge_list;
+ //loop over the tri's in tri_list and find all of the curves
+ //on the boundary of the set (ie, on the boundary of the void).
+ for (temp_i=0; temp_i<tri_list.size(); temp_i++)
+ {
+ tri_ptr = tri_list.get_and_step();
+ //check each edge to see whether it is a boundary edge or not
+ for (temp_j=0; temp_j<3; temp_j++){
+
+ int kk = temp_j;
+ // - if TRI == CubitFacet
+ // - kk will be corrected in adjacent() to
+ // - give the correct EDGE index
+ adjtri_ptr = tri_ptr->adjacent( kk, surface_ptr );
+ if (!adjtri_ptr || !tri_visited( adjtri_ptr, curr_visit_flag ))
+ {
+ edge_ptr = tri_ptr->edge(kk);
+ boundary_edge_list.append(edge_ptr);
+ }
+ }
+ }
+ int list_size = boundary_edge_list.size();
+ //uniquify the boundary edge list
+ boundary_edge_list.uniquify_unordered();
+ //the list shouldn't have changed size during the uniquify.
+ //if it did, there is a problem.
+ if(list_size != boundary_edge_list.size()){
+ PRINT_WARNING("Unexpected result. Edge was duplicated on boundary.\n");
+ return CUBIT_FAILURE;
+ }
+ //loop over the boundary edges and get the nodes in the boundary loop
+ for(temp_i=0; temp_i<list_size; ++temp_i){
+ edge_ptr=boundary_edge_list.get_and_step();
+ boundary_node_list.append(edge_ptr->end_node());
+ boundary_node_list.append(edge_ptr->start_node());
+ }
+ list_size = boundary_node_list.size();
+ //each node should be in exactly two edges. First make sure that there
+ //are the correct number of nodes.
+ if(list_size%2){
+ PRINT_WARNING("Unexpected result. Node not listed twice.\n");
+ return CUBIT_FAILURE;
+ }
+ //now uniquify to make sure that the nodes were listed the correct number
+ //of times.
+ boundary_node_list.uniquify_unordered();
+ if( (list_size/2) != boundary_node_list.size()){
+ PRINT_WARNING("Unexpected result. Node was listed an incorrect number of times.\n");
+ return CUBIT_FAILURE;
+ }
+ return CUBIT_SUCCESS;
+
+}
+
+//-------------------------------------------------------------------------
+// Function: bowyer_watson_insert
+// Description: Bowyer-Watson insertion into an existing Delaunay Mesh
+// Author: chynes
+// Date: 6/3/2002
+//-------------------------------------------------------------------------
+template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
+CubitStatus
+FacetorUtil<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::bowyer_watson_insert(
+ NODE* point_ptr,
+ DLIList<TRI*>& tri_list,
+ DLIList<TRI*>& facet_list,
+ int& curr_visit_flag,
+ SURF* surface_ptr,
+ TRI*& last_tri)
+{
+ CubitStatus rv = CUBIT_SUCCESS;
+
+ // mark the tris in the list so we can distinguish them from their
+ // neighbors
+
+ curr_visit_flag++;
+ int ii, jj;
+ TRI *tri_ptr;
+ for (ii=0; ii<tri_list.size(); ii++)
+ {
+ tri_ptr = tri_list.get_and_step();
+ tri_visited( tri_ptr, CUBIT_TRUE, curr_visit_flag );
+ }
+ //MBREWER: This is not an optimal test. But, we need need to
+ //do some tests to try to ensure that the void is valid for what
+ //we need. This is attempting to avoid crashes by not allowing nodes
+ //to be inserted when the mesh starts diverging from the Delaunay
+ //criteria.
+ rv = valid_void( point_ptr, tri_list, surface_ptr, curr_visit_flag );
+ if(!rv)
+ return rv;
+
+ // find all edges at the boundary of the visited triangles and create
+ // new triangles with them
+
+ // create a new triangle with this edge and the node
+ TRI *adjtri_ptr;
+ TRI *new_tri = NULL;
+ EDGE *edge_ptr;
+ DLIList<EDGE *> edge_list;
+ for (ii=0; ii<tri_list.size(); ii++)
+ {
+ tri_ptr = tri_list.get_and_step();
+ for (jj=0; jj<3; jj++){
+
+ int kk = jj;
+ // - if TRI == CubitFacet
+ // - kk will be corrected in adjacent() to
+ // - give the correct EDGE index
+ adjtri_ptr = tri_ptr->adjacent( kk, surface_ptr );
+ if (!adjtri_ptr || !tri_visited( adjtri_ptr, curr_visit_flag ))
+ {
+ edge_ptr = tri_ptr->edge(kk);
+ assert(edge_list.append_unique( edge_ptr ));
+ if(tri_ptr->sense(kk) == CUBIT_FORWARD)
+ new_tri = (TRI *) new TRICHILD( edge_ptr->start_node(), edge_ptr->end_node(), point_ptr, surface_ptr);
+ else
+ new_tri = (TRI *) new TRICHILD( edge_ptr->end_node(), edge_ptr->start_node(), point_ptr, surface_ptr);
+ facet_list.append(new_tri);
+ }
+ }
+ }
+ last_tri = new_tri;
+
+ // delete the triangles in the original triangle list
+
+ EDGE *del_edge_ptr;
+ DLIList<EDGE *> del_edge_list;
+ for (ii=0; ii<tri_list.size(); ii++)
+ {
+ tri_ptr = tri_list.get_and_step();
+ del_edge_list.clean_out();
+ facet_list.move_to(tri_ptr);
+ facet_list.extract();
+ tri_ptr->edges( del_edge_list );
+ delete tri_ptr;
+
+ // delete the unused edges
+ for (jj=0; jj<del_edge_list.size(); jj++)
+ {
+ del_edge_ptr = del_edge_list.get_and_step();
+ if (del_edge_ptr->number_tris() == 0 && del_edge_ptr->number_faces() == 0 )
+ delete del_edge_ptr;
+ }
+ }
+
+ return rv;
+}
+
+//-------------------------------------------------------------------------
+// Function: insert_node
+// Description: insert one node into Delaunay mesh
+// Author: chynes
+// Date: 6/3/2002
+//-------------------------------------------------------------------------
+template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
+CubitStatus
+FacetorUtil<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::insert_node(
+ NODE *node_ptr,
+ DLIList<TRI*>& facet_list,
+ SURF* surface_ptr,
+ int& curr_visit_flag,
+ TRI*& last_tri)
+{
+ CubitStatus rv = CUBIT_SUCCESS;
+
+ // get a list of all triangles whose circumcircle contain the point
+
+ DLIList<TRI *> tri_list;
+ CubitVector the_point = node_ptr->coordinates();
+ rv = natural_neighbor_tris( the_point, facet_list,
+ last_tri, surface_ptr,
+ curr_visit_flag, tri_list );
+
+
+ // Use a Bowyer-Watson insertion
+
+ if (rv == CUBIT_SUCCESS)
+ {
+ rv = bowyer_watson_insert( node_ptr, tri_list,
+ facet_list, curr_visit_flag,
+ surface_ptr, last_tri);
+ }
+
+ return rv;
+}
+
+//-------------------------------------------------------------------------
+// Function: get_size
+// Description: get the distortion factor for point inside tri, if one exists
+// otherwise return 1;
+// Author: chynes
+// Date: 7/24/02
+//-------------------------------------------------------------------------
+template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
+double
+FacetorUtil<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::get_size(CubitVector &cc, TRI *tri_ptr)
+{
+ //extract data
+ NODE *n0,*n1,*n2;
+ CubitVector area_coord;
+ tri_ptr->tri_nodes(n0,n1,n2);
+
+ if (n0->coordinates().z() - 1.0 < fabs(FT_INSIDE_TOL)
+ && n1->coordinates().z() - 1.0 < fabs(FT_INSIDE_TOL)
+ && n2->coordinates().z() - 1.0 < fabs(FT_INSIDE_TOL) )
+ return 1.0;
+ else
+ {
+ //get vectors
+ CubitVector v0 = n0->coordinates();
+ CubitVector v1 = n1->coordinates();
+ CubitVector v2 = n2->coordinates();
+
+ //set z direction
+ v0.z(cc.z());
+ v1.z(cc.z());
+ v2.z(cc.z());
+
+ //create points
+ CubitPoint *p0 = (CubitPoint*) new CubitPointData(v0);
+ CubitPoint *p1 = (CubitPoint*) new CubitPointData(v1);
+ CubitPoint *p2 = (CubitPoint*) new CubitPointData(v2);
+
+ //create facet
+ CubitFacet *temp_facet = (CubitFacet*) new CubitFacetData(p0,p1,p2);
+
+ FacetEvalTool::facet_area_coordinate(temp_facet, cc, area_coord);
+
+ delete p0;
+ delete p1;
+ delete p2;
+ delete temp_facet;
+
+ return (area_coord.x()*n0->coordinates().z())
+ + (area_coord.y()*n1->coordinates().z())
+ + (area_coord.z()*n2->coordinates().z());
+ }
+}
+
+//-------------------------------------------------------------------------
+// Function: tri_sort_list
+// Description: set the tri sort list index
+// Author: chynes
+// Date: 6/3/2002
+//-------------------------------------------------------------------------
+template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
+void
+FacetorUtil<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::tri_sort_list(
+ TRI *facet_ptr,
+ int sort_list_index )
+{
+ ToolData *td = facet_ptr->get_TD( TDDelaunay< TRI, NODE >::is_delaunay );
+ TDDelaunay< TRI, NODE > *td_del = dynamic_cast<TDDelaunay< TRI, NODE >*> (td);
+ if (td_del == NULL)
+ {
+ td_del = new TDDelaunay<TRI, NODE>();
+ facet_ptr->add_TD( td_del );
+ }
+ td_del->tri_sort_list(sort_list_index);
+}
+
+
+//-------------------------------------------------------------------------
+// Function: tri_sort_list
+// Description: get the tri sort list index
+// Author: chynes
+// Date: 6/3/2002
+//-------------------------------------------------------------------------
+template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
+int
+FacetorUtil<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::tri_sort_list( TRI *facet_ptr )
+{
+ ToolData *td = facet_ptr->get_TD( TDDelaunay< TRI, NODE >::is_delaunay );
+ TDDelaunay< TRI, NODE > *td_del = dynamic_cast<TDDelaunay< TRI, NODE >*> (td);
+ if (td_del == NULL)
+ {
+ td_del = new TDDelaunay<TRI, NODE>();
+ facet_ptr->add_TD( td_del );
+ }
+ return td_del->tri_sort_list();
+}
+
+//-------------------------------------------------------------------------
+// Function: classify_tri_by_angle
+// Description: compute the angles at the triangle vertices and classify
+// by its worst triangle
+// Author: chynes
+// Date: 6/3/2002
+//-------------------------------------------------------------------------
+template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
+CubitStatus
+FacetorUtil<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::classify_tri_by_angle(
+ TRI* tri_ptr,
+ DLIList<TRI*>* sorted_lists,
+ const int num_lists,
+ const double interval,
+ const double quality_angle)
+{
+ //CubitStatus rv = CUBIT_SUCCESS;
+
+ // Determine the minimum angle
+
+ NODE *nodes[3];
+ tri_ptr->tri_nodes( nodes[0], nodes[1], nodes[2] );
+ double x0 = nodes[0]->coordinates().x();
+ double y0 = nodes[0]->coordinates().y();
+ double x1 = nodes[1]->coordinates().x();
+ double y1 = nodes[1]->coordinates().y();
+ double x2 = nodes[2]->coordinates().x();
+ double y2 = nodes[2]->coordinates().y();
+
+ double ax = x1 - x0;
+ double ay = y1 - y0;
+ double bx = x2 - x0;
+ double by = y2 - y0;
+ double dot = ax*bx + ay*by;
+ double a_mag = sqrt( ax*ax + ay*ay );
+ double b_mag = sqrt( bx*bx + by*by );
+ double angle0 = dot / ( a_mag * b_mag );
+ angle0 = acos( angle0 );
+
+ ax = -ax;
+ ay = -ay;
+ bx = x2 - x1;
+ by = y2 - y1;
+ dot = ax*bx + ay*by;
+ b_mag = sqrt( bx*bx + by*by );
+ double angle1 = dot / ( a_mag * b_mag );
+ angle1 = acos( angle1 );
+
+ double angle2 = CUBIT_PI - angle0 - angle1;
+
+ double min_angle = CUBIT_MIN( CUBIT_MIN(angle0,angle1),
+ CUBIT_MIN(angle1,angle2) );
+ if (min_angle < 0.0) {
+ assert(0);
+ return CUBIT_FAILURE;
+ }
+
+ // If it is greater than the QUALITY_ANGLE then place it in
+ // the triSortArray[0], otherwise place it in one of the other deques
+ // depending upon its minimum angle
+
+ // Determine which list
+
+ int index;
+ if (min_angle >= quality_angle) {
+ index = 0;
+ }
+ else {
+ index = 1 + (int)(min_angle/interval);
+ if (index < 1) index = 1;
+ if (index > num_lists-1) index = num_lists-1;
+ }
+
+ // Place it on a list
+
+ sorted_lists[index].append( tri_ptr );
+ tri_sort_list( tri_ptr, index );
+
+ return CUBIT_SUCCESS;
+}
+
+//-------------------------------------------------------------------------
+// Function: insert_at_circumcenter
+// Description: insert a node at the circumcenter of a tri
+// Author: chynes
+// Date: 6/3/2002
+//-------------------------------------------------------------------------
+template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC> MY_INLINE
+CubitStatus
+FacetorUtil<SURF, TRI, EDGE, NODE, TRICHILD, NODECHILD, SIZEFUNC>::insert_at_circumcenter(
+ TRI* tri_ptr,
+ DLIList<TRI*>& facet_list,
+ TRI*& start_tri,
+ int& curr_visit_flag,
+ SURF* surface_ptr,
+ DLIList<TRI*>* sorted_lists,
+ const int num_lists,
+ const double interval,
+ const double quality_angle,
+ SIZEFUNC* sizing_function,
+ ParamTool* p_tool)
+{
+ CubitStatus rv = CUBIT_SUCCESS;
+
+ // find the cicumcenter of the triangle and the target size there
+ //if nodes are colinear do not try to find circumenter
+ if(!are_nodes_colinear(tri_ptr))
+ {
+ PRINT_ERROR("Can't evaluate center of circumcircle\n");
+ return CUBIT_FAILURE;
+ }
+ CubitVector cc = circumcenter( tri_ptr );
+
+ //translate cc into 3D space
+ CubitVector cc_xyz;
+ p_tool->transform_to_xyz(cc_xyz, cc);
+ // get target length in 3D space
+ double target_length = sizing_function->size_at_point( cc_xyz );
+ // get new size
+ double size = get_size(cc, tri_ptr);
+ // update size
+ cc.z(size);
+ // update target_length
+ target_length = target_length*size;
+
+ // Determine if we should now insert the point. Allow insertions
+ // in the general case down to circumcircle size of ALPHA times the
+ // interpolated target edge length size. For tris with small
+ // angles, allow additional inserts to improve the quality down
+ // to 1/2 the target size
+ if(!are_nodes_colinear(tri_ptr))
+ {
+ PRINT_ERROR("Can't evaluate radius of circumcircle\n");
+ return CUBIT_FAILURE;
+ }
+
+
+ double r2 = radius( tri_ptr );
+ CubitBoolean insert = CUBIT_FALSE;
+ int tsindex = tri_sort_list( tri_ptr );
+ assert(tsindex > -1);
+ if (tsindex == 0)
+ {
+ if (r2 > SQR(ALPHA*target_length))
+ {
+ insert = CUBIT_TRUE;
+ }
+ }
+ else
+ {
+ if (r2 > SQR(0.5*ALPHA*target_length))
+ {
+ insert = CUBIT_TRUE;
+ }
+ }
+ if (insert)
+ {
+
+ // Determine the tris that will be affected by the insertion
+
+ start_tri = tri_ptr;
+ DLIList <TRI *> tri_list;
+ rv = natural_neighbor_tris( cc, facet_list,
+ start_tri, surface_ptr,
+ curr_visit_flag, tri_list );
+ // If it was outside, then we are done with it
+
+ if (tri_list.size() == 0)
+ {
+ return CUBIT_SUCCESS;
+ }
+ if (rv != CUBIT_SUCCESS) {
+ return rv;
+ }
+
+ // See if we are too close to a boundary
+
+ double x0, y0, x1, y1, cx, cy, edge_radius, dist;
+ TRI *nntri_ptr;
+ EDGE *edge_ptr;
+ int ii, iedge;
+ for (ii=0; ii<tri_list.size(); ii++)
+ {
+ nntri_ptr = tri_list.get_and_step();
+ for (iedge=0; iedge<3; iedge++)
+ {
+ edge_ptr = tri_ptr->edge( iedge );
+
+ // An edge encroaches if the distance from the prospective
+ // new point to the midpoint of the edge is less than
+ // half the length of the edge
+
+ if (edge_ptr->marked()) // on the boundary?
+ {
+ x0 = (edge_ptr->start_node())->coordinates().x();
+ y0 = (edge_ptr->start_node())->coordinates().y();
+ x1 = (edge_ptr->end_node())->coordinates().x();
+ y1 = (edge_ptr->end_node())->coordinates().y();
+ cx = (x0 + x1) * 0.5;
+ cy = (y0 + y1) * 0.5;
+ edge_radius = sqrt(SQR(x1-x0) + SQR(y1-y0)) * 0.5;
+ dist = sqrt( SQR(cx-cc.x()) + SQR(cy-cc.y()) );
+
+ // Edge encroaches: don't insert, return now
+
+ if (dist - edge_radius < FT_INSIDE_TOL)
+ {
+ return CUBIT_SUCCESS;
+ }
+ }
+ }
+ }
+
+ // Before inserting, remove all the tris on the neighbor
+ // tri_list from the lists
+
+ int index;
+ for (ii=0; ii<tri_list.size(); ii++)
+ {
+ nntri_ptr = tri_list.get_and_step();
+ index = tri_sort_list( nntri_ptr );
+ assert(index >= 0);
+ sorted_lists[index].remove( nntri_ptr );
+ }
+
+ // Create the new node
+
+ NODE *new_node_ptr = (NODE *)new NODECHILD( cc, surface_ptr );
+
+ // Insert the new node into the mesh
+
+ rv = bowyer_watson_insert( new_node_ptr, tri_list,
+ facet_list, curr_visit_flag,
+ surface_ptr, start_tri);
+ if (rv != CUBIT_SUCCESS)
+ return rv;
+
+ // get the new tris at the node and classify them
+
+ tri_list.clean_out();
+ new_node_ptr->tris( tri_list );
+ for (ii=0; ii<tri_list.size() && rv == CUBIT_SUCCESS; ii++)
+ {
+ tri_ptr = tri_list.get_and_step();
+ rv = classify_tri_by_angle( tri_ptr, sorted_lists, num_lists, interval, quality_angle );
+ }
+ }
+
+ return rv;
+}
Added: cgm/branches/cubit/geom/Cholla/FacetorUtil.hpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/FacetorUtil.hpp (rev 0)
+++ cgm/branches/cubit/geom/Cholla/FacetorUtil.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,134 @@
+//- Class: FacetorUtil
+//- Description: Utility functions used by FactorTool and available to other classes.
+// FacetorUtil uses template functions that accepts both CubitNode, CubitTri, CubitEdge classes
+//- and CubitPoint, CubitFacet, CubitFacetEdge classes. CubitPoint, CubitFacet, and
+//- CubitFacetEdge classes have been modified to account for the difference between the mdb
+//= entities and geometric entities.
+//-------------------------------------------------------------------------
+// Filename : FacetorTool.hpp
+//
+// Purpose : 2D Delaunay Mesher
+//
+// Creator : Christopher Hynes
+//
+// Creation Date : 5/31/2002
+//
+// Owner : Steve Owen
+//-------------------------------------------------------------------------
+
+#ifndef FACETOR_UTIL_HPP
+#define FACETOR_UTIL_HPP
+
+
+#include "CubitDefines.h"
+class ParamTool;
+
+template<class SURF, class TRI, class EDGE, class NODE, class TRICHILD, class NODECHILD, class SIZEFUNC>
+class FacetorUtil
+{
+public:
+ FacetorUtil(){}
+ ~FacetorUtil(){}
+
+ //- Insert one node into a Delaunay mesh
+ static CubitStatus insert_node(NODE *node_ptr,
+ DLIList<TRI*>& facet_list,
+ SURF* surface_ptr,
+ int& curr_visit_flag,
+ TRI*& last_tri);
+
+ // Insert a node at the circumcenter of a tri
+ static CubitStatus insert_at_circumcenter(TRI *tri_ptr,
+ DLIList<TRI*>& facet_list,
+ TRI*& start_tri,
+ int& curr_visit_flag,
+ SURF* surface_ptr,
+ DLIList<TRI*>* sorted_lists,
+ const int num_lists,
+ const double interval,
+ const double quality_angle,
+ SIZEFUNC* sizing_function,
+ ParamTool* p_tool);
+
+ // Compute the angles at the triangle vertices and classify
+ // by its worst triangle
+ static CubitStatus classify_tri_by_angle(TRI* tri_ptr,
+ DLIList<TRI*>* sorted_lists,
+ const int num_lists,
+ const double interval,
+ const double quality_angle);
+
+private:
+
+ //Get the tri_visited flag.
+ static CubitBoolean tri_visited(TRI *tri_ptr,
+ int curr_visit_flag);
+
+ //Set the tri_visited flag.
+ static void tri_visited(TRI *tri_ptr,
+ CubitBoolean visited,
+ int curr_visit_flag);
+
+ //Search every TRI until the one that the_point is in
+ //is found.
+ static CubitStatus exhaustive_locate_point(CubitVector& the_point,
+ DLIList<TRI*>& facet_list,
+ TRI*& tri_ptr);
+
+ static CubitStatus point_in_circumcircle(CubitVector& the_point,
+ TRI* tri_ptr,
+ DLIList<TRI*>& tri_list,
+ SURF* surface_ptr,
+ int curr_visit_flag);
+
+ //Find the TRI in facet_list that the_point is in.
+ //If starting_tri is not NULL the search will begin
+ //with it.
+ static CubitStatus locate_point(CubitVector& the_point,
+ DLIList<TRI*>& facet_list,
+ TRI* starting_tri,
+ SURF* owning_surface,
+ TRI*& tri_ptr);
+
+ //check the void created in Bowyer-Watson to ensure the boundary
+ //seems valid.
+ static CubitStatus valid_void( NODE * /*point_ptr*/,
+ DLIList<TRI *> &tri_list,
+ SURF* surface_ptr,
+ int curr_visit_flag);
+
+ static CubitStatus natural_neighbor_tris(CubitVector& the_point,
+ DLIList<TRI*>& facet_list,
+ TRI*& start_tri,
+ SURF* surface_ptr,
+ int& curr_visit_flag,
+ DLIList<TRI*>& tri_list);
+
+ //- Bowyer-Watson insertion into an existing Delaunay Mesh
+ static CubitStatus bowyer_watson_insert(NODE* point_ptr,
+ DLIList<TRI*>& tri_list,
+ DLIList<TRI*>& facet_list,
+ int& curr_visit_flag,
+ SURF* surf_ptr,
+ TRI*& last_tri);
+
+ //Return true if all three points in tri_ptr are colinear.
+ //Return false otherwise.
+ static CubitBoolean are_nodes_colinear(TRI* tri_ptr);
+
+ static CubitVector& circumcenter(TRI* tri_ptr);
+
+ static double get_size(CubitVector &cc, TRI *tri_ptr);
+
+ // get and set the tri sort array index that this tri is in
+ static void tri_sort_list( TRI *tri_ptr, int sort_list_index );
+ static int tri_sort_list( TRI *tri_ptr );
+
+ static double radius(TRI* tri_ptr);
+};
+
+// Added by CAT for NT port
+#if defined(TEMPLATE_DEFS_INCLUDED)
+ #include "FacetorUtil.cpp"
+#endif
+#endif
Modified: cgm/branches/cubit/geom/Cholla/LoopParamTool.cpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/LoopParamTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/LoopParamTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -59,7 +59,8 @@
// Author: Shiraj Khan
// Date: 1/21/2003
//===================================================================================
-CubitStatus LoopParamTool::new_space_LoopParam( DLIList<DLIList<CubitPoint *>*> &loops_cubit_points)
+CubitStatus LoopParamTool::new_space_LoopParam( DLIList<DLIList<CubitPoint *>*> &loops_cubit_points,
+ CubitVector* normal)
{
int ii;
@@ -131,7 +132,13 @@
//(vec1) crossproduct (vec2)
// where vec1 and vec2 are the vectors originating from a common point( center of mass of a plane) and
// lying on the plane.
- if ( determinant_aa == 0.0 )
+ if(normal){
+ a = normal->x();
+ b = normal->y();
+ c = normal->z();
+ d = -(a*Xc + b*Yc + c*Zc );
+ }
+ else if ( determinant_aa == 0.0 )
{
sub_loops_cubit_points = loops_cubit_points.get_and_step();
point1 = sub_loops_cubit_points->get_and_step();
@@ -350,7 +357,12 @@
for ( jj = 0; jj < sub_loop_cubit_points->size(); jj++ )
{
point_ptr = sub_loop_cubit_points->get_and_step();
- TDVector *td_pos = new TDVector(point_ptr->coordinates());
+ ToolData* td = point_ptr->get_TD( &TDVector::is_td_vector );
+ TDVector* td_pos = NULL;
+ if( NULL == td )
+ td_pos = new TDVector(point_ptr->coordinates());
+ else
+ td_pos = static_cast<TDVector*>( td );
point_ptr->add_TD(td_pos);
point_coordinates = point_ptr->coordinates();
@@ -376,7 +388,7 @@
// Author: Shiraj Khan
// Date: 1/21/2003
//===================================================================================
-CubitStatus LoopParamTool::transform_to_uv(CubitVector &, CubitVector &)
+CubitStatus LoopParamTool::transform_to_uv(const CubitVector &, CubitVector &)
{
PRINT_ERROR("This function is not appropriate for the the LoopParamTool.\n");
assert(0);
@@ -410,7 +422,7 @@
// Author: Shiraj Khan
// Date: 1/21/2003
//===================================================================================
-CubitStatus LoopParamTool::transform_to_xyz(CubitVector &, CubitVector &)
+CubitStatus LoopParamTool::transform_to_xyz(CubitVector &, const CubitVector &)
{
PRINT_ERROR("This function is not appropriate for the the LoopParamTool.\n");
assert(0);
@@ -536,154 +548,140 @@
CubitStatus LoopParamTool::check_selfintersecting_coincident_edges(DLIList<DLIList<CubitPoint *>*>
&loops_bounding_points)
{
+ //This function checks each line segment against every other line segment
+ //to see if they intersect or overlap. Each line will be described
+ //by the following equations:
+ //
+ // Pa = P1 + ua( P2 - P1 )
+ // Pb = P3 + ub( P4 - P3 )
+ //
+ //Setting the Pa equal to Pb and solving for ua and ub you will get two
+ //equation. Both will have the common denominator:
+ //
+ // denom = ( (uv4.y() - uv3.y()) * (uv2.x() - uv1.x() ) -
+ // (uv4.x() - uv3.x()) * (uv2.y() - uv1.y() ) )
+ //
+ //And the numerators will be:
+ //
+ // numer_a = ( (uv4.x() - uv3.x()) * (uv1.y() - uv3.y() ) -
+ // (uv4.y() - uv3.y()) * (uv1.x() - uv3.x() ) )
+ //
+ // numer_b = ( (uv2.x() - uv1.x()) * (uv1.y() - uv3.y() ) -
+ // (uv2.y() - uv1.y()) * (uv1.x() - uv3.x() ) )
+ //
+ //ua and ub then become:
+ //
+ // ua = numer_a / denom
+ // ub = numer_b / denom
+ //
+ //If the lines are parallel then denom will be zero. If they are
+ //also coincedent then the numerators will also be zero. For the
+ //segments to intersect ua and ub need to both be between 0
+ //and 1.
+
int ii, jj, kk, ll;
- DLIList<CubitPoint *> *sub_loops_bounding_points1, *sub_loops_bounding_points2;
- CubitPoint *start_point1, *end_point1, *start_point2, *end_point2;
- CubitVector uv1, uv2, uv3, uv4;
- CubitVector u, v, w;
- double s,t;
- int flag = 1;
-
for ( ii = 0; ii < loops_bounding_points.size(); ii++ )
{
- sub_loops_bounding_points1 = loops_bounding_points.next(ii);
+ DLIList<CubitPoint*>* sub_loops_bounding_points1 = loops_bounding_points.next(ii);
for( jj = 0; jj < sub_loops_bounding_points1->size(); jj++ )
{
-
- start_point1 = sub_loops_bounding_points1->next(jj);//
+ CubitPoint* start_point1 = sub_loops_bounding_points1->next(jj);
+ CubitPoint* end_point1 = NULL;
if ( jj == sub_loops_bounding_points1->size()-1 )
end_point1 = sub_loops_bounding_points1->next(0);
else
end_point1 = sub_loops_bounding_points1->next(jj+1);
- uv1 = start_point1->coordinates();
- uv2 = end_point1->coordinates();
-
- if ( (uv1.x() > EPSILON_LOWER) && (uv1.x() < EPSILON_UPPER) )
- uv1.x(0.0);
- if ( (uv1.y() > EPSILON_LOWER) && (uv1.y() < EPSILON_UPPER) )
- uv1.y(0.0);
- if ( (uv1.z() > EPSILON_LOWER) && (uv1.z() < EPSILON_UPPER) )
- uv1.z(0.0);
- if ( (uv2.x() > EPSILON_LOWER) && (uv2.x() < EPSILON_UPPER) )
- uv2.x(0.0);
- if ( (uv2.y() > EPSILON_LOWER) && (uv2.y() < EPSILON_UPPER) )
- uv2.y(0.0);
- if ( (uv2.z() > EPSILON_LOWER) && (uv2.z() < EPSILON_UPPER) )
- uv2.z(0.0);
+ CubitVector uv1 = start_point1->coordinates();
+ CubitVector uv2 = end_point1->coordinates();
- for ( kk = 0; kk < loops_bounding_points.size(); kk++ )
+ //Start with the current loop in the list. The previous
+ //lists have already been checked against this list.
+ for ( kk = ii; kk < loops_bounding_points.size(); kk++ )
{
- sub_loops_bounding_points2 = loops_bounding_points.next(kk);
+ DLIList<CubitPoint*>* sub_loops_bounding_points2 = loops_bounding_points.next(kk);
for ( ll = 0; ll < sub_loops_bounding_points2->size(); ll++ )
{
- start_point2 = sub_loops_bounding_points2->next(ll);//
+ CubitPoint* start_point2 = sub_loops_bounding_points2->next(ll);
+ CubitPoint* end_point2 = NULL;
if ( ll == sub_loops_bounding_points2->size()-1 )
end_point2 = sub_loops_bounding_points2->next(0);
else
end_point2 = sub_loops_bounding_points2->next(ll+1);
- uv3 = start_point2->coordinates();
- uv4 = end_point2->coordinates();
+ CubitVector uv3 = start_point2->coordinates();
+ CubitVector uv4 = end_point2->coordinates();
if ( start_point1 == end_point2 || start_point1== start_point2 ||
end_point1 == start_point2 || end_point1 == end_point2 )
continue;
- if ( (uv3.x() > EPSILON_LOWER) && (uv3.x() < EPSILON_UPPER) )
- uv3.x(0.0);
- if ( (uv3.y() > EPSILON_LOWER) && (uv3.y() < EPSILON_UPPER) )
- uv3.y(0.0);
- if ( (uv3.z() > EPSILON_LOWER) && (uv3.z() < EPSILON_UPPER) )
- uv3.z(0.0);
- if ( (uv4.x() > EPSILON_LOWER) && (uv4.x() < EPSILON_UPPER) )
- uv4.x(0.0);
- if ( (uv4.y() > EPSILON_LOWER) && (uv4.y() < EPSILON_UPPER) )
- uv4.y(0.0);
- if ( (uv4.z() > EPSILON_LOWER) && (uv4.z() < EPSILON_UPPER) )
- uv4.z(0.0);
-
if ( (uv1 == uv3) && (uv2 == uv4) )
continue;
-
- // If condition to check that both points (uv3 and uv4 )lie on
- //the straight line through uv1 and uv2
- if ( (uv3.y()*(uv2.x()-uv1.x()) ==
- ((uv2.y()-uv1.y()) * uv3.x()+ uv1.y()*uv2.x()-uv1.x()*uv2.y()) ) &&
- (uv4.y()*(uv2.x()-uv1.x()) ==
- ((uv2.y()-uv1.y()) * uv4.x()+ uv1.y()*uv2.x()-uv1.x()*uv2.y())) )
+ double denom = ( (uv4.y() - uv3.y()) * (uv2.x() - uv1.x() ) -
+ (uv4.x() - uv3.x()) * (uv2.y() - uv1.y() ) );
+
+ double numer_a = ( (uv4.x() - uv3.x()) * (uv1.y() - uv3.y() ) -
+ (uv4.y() - uv3.y()) * (uv1.x() - uv3.x() ) );
+
+ double numer_b = ( (uv2.x() - uv1.x()) * (uv1.y() - uv3.y() ) -
+ (uv2.y() - uv1.y()) * (uv1.x() - uv3.x() ) );
+
+ if( denom < CUBIT_RESABS && denom > -CUBIT_RESABS )
{
-
- // This condition to check that one of the 2 points (uv3 and uv4)
- //lie between uv1 and uv2 or two edges exactly overlapping
- if ( ( (( uv3.x() > uv1.x()) && (uv3.x() < uv2.x())) ||
- (( uv3.x() > uv2.x()) && (uv3.x() < uv1.x())) ) ||
- ( (( uv4.x() > uv1.x()) && (uv4.x() < uv2.x())) ||
- (( uv4.x() > uv2.x()) && (uv4.x() < uv1.x())) ) ||
- ( (( uv3.y() > uv1.y()) && (uv3.y() < uv2.y())) ||
- (( uv3.y() > uv2.y()) && (uv3.y() < uv1.y())) ) ||
- ( (( uv4.y() > uv1.y()) && (uv4.y() < uv2.y())) ||
- (( uv4.y() > uv2.y()) && (uv4.y() < uv1.y())) ) ||
- (( uv1 == uv3 ) && ( uv2 == uv4 )) ||
- (( uv1 == uv4 ) && ( uv2 == uv3 )) )
+ //The lines are parallel. Check the numerators to
+ //see if they are coincident.
+ if( numer_a < CUBIT_RESABS && numer_a > -CUBIT_RESABS &&
+ numer_b < CUBIT_RESABS && numer_b > -CUBIT_RESABS )
{
- PRINT_ERROR("Can't mesh due to coincident edges \n\n\n");
- flag = 0;
- break;
+ //The lines are coincident. Now see if the segments
+ //over lap.
+ double ua;
+ double ub;
+ if( (uv2.x() - uv1.x()) < CUBIT_RESABS &&
+ (uv2.x() - uv1.x()) > -CUBIT_RESABS )
+ {
+ if( (uv2.y() - uv1.y() < CUBIT_RESABS &&
+ uv2.y() - uv1.y() > -CUBIT_RESABS)){
+ PRINT_ERROR("Can't mesh due to zero-length edge.\n");
+ return CUBIT_FAILURE;
+ }
+ ua = (uv3.y() - uv1.y() ) / ( uv2.y() - uv1.y() );
+ ub = (uv4.y() - uv1.y() ) / ( uv2.y() - uv1.y() );
+ }
+ else
+ {
+ ua = (uv3.x() - uv1.x() ) / ( uv2.x() - uv1.x() );
+ ub = (uv4.x() - uv1.x() ) / ( uv2.x() - uv1.x() );
+ }
+
+ if( ua > CUBIT_RESABS && ua < (1.0 - CUBIT_RESABS ) ||
+ ub > CUBIT_RESABS && ub < (1.0 - CUBIT_RESABS ))
+ {
+ //The segments overlap.
+ PRINT_ERROR("Can't mesh due to coincident edges \n\n\n");
+ return CUBIT_FAILURE;
+ }
}
}
-
- u = uv2 - uv1;
- v = uv4 - uv3;
- w = uv1 - uv3;
- s = v.x()*u.y()-v.y()*u.x();
- t = u.x()*v.y()-u.y()*v.x();
- if ( s < CUBIT_RESABS && s > -CUBIT_RESABS)
- s = CUBIT_DBL_MAX;
else
- s = ( v.y()*w.x()-v.x()*w.y() )/( s );
- if ( t < CUBIT_RESABS && t > -CUBIT_RESABS)
- t = CUBIT_DBL_MAX;
- else
- t = ( u.x()*w.y()-u.y()*w.x() )/( t );
-
- //this condition to check whether two segments intersect
- if ( (s > (0.0+CUBIT_RESABS) && s < (1.0-CUBIT_RESABS)) &&
- (t > (0.0+CUBIT_RESABS) && t < (1.0-CUBIT_RESABS)))
{
- PRINT_ERROR("1. Can't mesh due to self intersecting edges \n\n\n");
- flag = 0;
- break;
+ double ua = numer_a / denom;
+ double ub = numer_b / denom;
+
+ if( ( (ua > CUBIT_RESABS && ua < (1.0-CUBIT_RESABS)) &&
+ (ub > CUBIT_RESABS && ub < (1.0-CUBIT_RESABS))) )
+ {
+ PRINT_ERROR("Can't mesh due to self intersecting edges \n\n\n");
+ return CUBIT_FAILURE;
+ }
}
- else if( (double_equal(s, 0.0) || double_equal( s,1.0) ) &&
- ((t > (0.0+CUBIT_RESABS)) && (t < (1.0-CUBIT_RESABS))))
- {
- PRINT_ERROR("2. Can't mesh due to self intersecting edges \n\n\n");
- flag = 0;
- break;
- }
- else if ( (double_equal(t,0.0) || double_equal(t,1.0) ) &&
- ((s > (0.0+CUBIT_RESABS)) && (s < (1.0-CUBIT_RESABS))))
- {
- PRINT_ERROR("3. Can't mesh due to self intersecting edges, t = %f, s = %f \n\n\n", t,s);
- flag = 0;
- break;
- }
}//end of for ( ll )
- if ( flag == 0 ) break;
}// end of for ( kk )
- if ( flag == 0 ) break;
}//end of for ( jj )
- if ( flag == 0 ) break;
}// end of for ( ii )
- //if the self-intersecting and coincident edges are there then return CUBIT_FAILURE
- // else return CUBIT_SUCCESS
- if ( flag == 0 )
- return CUBIT_FAILURE;
- else
- return CUBIT_SUCCESS;
-
+ return CUBIT_SUCCESS;
}
bool LoopParamTool::double_equal(double val, double equal_to)
Modified: cgm/branches/cubit/geom/Cholla/LoopParamTool.hpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/LoopParamTool.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/LoopParamTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -30,8 +30,8 @@
~LoopParamTool();
virtual CubitStatus set_up_space();
- virtual CubitStatus transform_to_uv(CubitVector &, CubitVector &);
- virtual CubitStatus transform_to_xyz(CubitVector &, CubitVector &);
+ virtual CubitStatus transform_to_uv(const CubitVector &, CubitVector &);
+ virtual CubitStatus transform_to_xyz(CubitVector &, const CubitVector &);
//These functions are required because this is a child of ParamTool.
//They do nothing.
@@ -45,7 +45,8 @@
///The calling code is reponsible for removing and deleting the memory of the TDVectors.
///
- CubitStatus new_space_LoopParam( DLIList<DLIList<CubitPoint *>*> &loop_cubit_points);
+ CubitStatus new_space_LoopParam( DLIList<DLIList<CubitPoint *>*> &loop_cubit_points,
+ CubitVector* normal = NULL);
///
///This function must be called first for this tool. This sets up the plane and
///the transformation to the XY plane.
Modified: cgm/branches/cubit/geom/Cholla/Makefile.am
===================================================================
--- cgm/branches/cubit/geom/Cholla/Makefile.am 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/Makefile.am 2010-01-06 19:22:14 UTC (rev 3423)
@@ -21,6 +21,7 @@
ChollaPoint.cpp \
ChollaSkinTool.cpp \
ChollaSurface.cpp \
+ ChollaVolume.cpp \
ChordalAxis.cpp \
CubitFacet.cpp \
CubitFacetData.cpp \
@@ -57,6 +58,7 @@
ChollaPoint.hpp \
ChollaSkinTool.hpp \
ChollaSurface.hpp \
+ ChollaVolume.hpp \
ChordalAxis.hpp \
CubitFacet.hpp \
CubitFacetData.hpp \
@@ -71,6 +73,7 @@
FacetEntity.hpp \
FacetEvalTool.hpp \
FacetorTool.hpp \
+ FacetorUtil.hpp \
GeoNode.hpp \
GeoTet.hpp \
LoopParamTool.hpp \
@@ -93,12 +96,14 @@
libcholla_la_include_HEADERS += \
BoundaryConstrainTool.cpp \
FacetorTool.cpp \
+ FacetorUtil.cpp \
TetFacetorTool.cpp \
TDDelaunay.cpp
else
libcholla_la_SOURCES += \
BoundaryConstrainTool.cpp \
FacetorTool.cpp \
+ FacetorUtil.cpp \
TetFacetorTool.cpp \
TDDelaunay.cpp
endif
Modified: cgm/branches/cubit/geom/Cholla/TDGeomFacet.cpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/TDGeomFacet.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/TDGeomFacet.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -7,7 +7,10 @@
#include "CubitFacetEdge.hpp"
#include "CubitFacet.hpp"
#include "CastTo.hpp"
+#include "ChollaVolume.hpp"
#include "ChollaSurface.hpp"
+#include "ChollaCurve.hpp"
+#include "ChollaPoint.hpp"
#include "CubitPoint.hpp"
TDGeomFacet::TDGeomFacet()
@@ -16,6 +19,7 @@
hitFlag = 0;
partnerEdgeList = NULL;
partnerPointList = NULL;
+ onBoundaryFlag = 0;
}
TDGeomFacet::~TDGeomFacet()
@@ -145,6 +149,27 @@
}
return -1;
}
+void TDGeomFacet::add_cholla_owner( ChollaEntity *cholla_entity )
+{
+ ChollaSurface *cholla_surface = dynamic_cast<ChollaSurface *> (cholla_entity);
+ if (cholla_surface != NULL)
+ add_cholla_surf(cholla_surface);
+ else
+ {
+ ChollaCurve *cholla_curve = dynamic_cast<ChollaCurve *> (cholla_entity);
+ if (cholla_curve != NULL)
+ add_cholla_curve( cholla_curve );
+ else
+ {
+ ChollaPoint *cholla_point = dynamic_cast<ChollaPoint *> (cholla_entity);
+ if (cholla_point != NULL)
+ add_cholla_point( cholla_point );
+ else
+ assert(0); // not a recognized cholla entity
+ }
+ }
+ return;
+}
void TDGeomFacet::add_cholla_surf( ChollaSurface *f_s_m )
{
int ii;
@@ -201,5 +226,50 @@
return CUBIT_FALSE;
}
+void TDGeomFacet::reset_TD_as_new()
+{
+ blockId = -1;
+ hitFlag = 0;
+ partnerEdgeList = NULL;
+ partnerPointList = NULL;
+ onBoundaryFlag = 0;
+ ChollaSurfaceList.clean_out();
+ ChollaCurveList.clean_out();
+ myPoints.clean_out();
+ //normal??????;
+ //need to delete these?
+ partnerEdgeList=NULL;
+ partnerPointList=NULL;
+}
+int TDGeomFacet::geo_type()
+{
+ if (ChollaSurfaceList.size() > 0)
+ return 2;
+ else if (ChollaCurveList.size() > 0)
+ return 1;
+ else if (myPoints.size() > 0)
+ return 0;
+ return -1;
+}
+
+CubitBoolean TDGeomFacet::is_in_volume( ChollaVolume *chvol_ptr )
+{
+ for (int ii=0; ii<ChollaSurfaceList.size(); ii++)
+ {
+ ChollaSurface *chsurf_ptr = ChollaSurfaceList.get_and_step();
+ if (chsurf_ptr->is_in_volume( chvol_ptr ))
+ return CUBIT_TRUE;
+ }
+ for (int jj=0; jj<ChollaCurveList.size(); jj++)
+ {
+ ChollaCurve *chcurv_ptr = ChollaCurveList.get_and_step();
+ if (chcurv_ptr->is_in_volume( chvol_ptr ))
+ return CUBIT_TRUE;
+ }
+ return CUBIT_FALSE;
+}
+
+
+
Modified: cgm/branches/cubit/geom/Cholla/TDGeomFacet.hpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/TDGeomFacet.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/TDGeomFacet.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -15,8 +15,11 @@
#include "ToolData.hpp"
#include "CubitPoint.hpp"
class FacetEntity;
+class ChollaEntity;
+class ChollaVolume;
class ChollaSurface;
class ChollaCurve;
+class ChollaPoint;
class CubitFacet;
class CubitFacetEdge;
@@ -42,6 +45,9 @@
DLIList<ChollaCurve*> ChollaCurveList;
//- list of curves this element (edge) is on
+ DLIList<ChollaPoint*> ChollaPointList;
+ //- list chollapoints this element (point) is on
+
DLIList<CubitPoint*> myPoints;
//- list of associated points for this entity (could be one).
@@ -74,6 +80,11 @@
void set_hit_flag(int flag)
{hitFlag = flag;}
+
+ int on_boundary(){return onBoundaryFlag;}
+ void on_boundary( int status ){ onBoundaryFlag = status; }
+
+ void add_cholla_owner(ChollaEntity *cholla_entity);
void add_cholla_surf(ChollaSurface *f_s_m);
@@ -97,7 +108,19 @@
void remove_cholla_curve( ChollaCurve *chcurv_ptr )
{ChollaCurveList.remove( chcurv_ptr );}
+
+ void add_cholla_point(ChollaPoint *chpt_ptr)
+ {ChollaPointList.append_unique( chpt_ptr );}
+ void get_cholla_points(DLIList<ChollaPoint*> &point_list)
+ {point_list = ChollaPointList;}
+
+ void remove_cholla_points()
+ {ChollaPointList.clean_out();}
+
+ void remove_cholla_point( ChollaPoint *point_ptr )
+ { ChollaPointList.remove( point_ptr ); }
+
void add_point(CubitPoint *point)
{myPoints.append(point);}
@@ -143,6 +166,8 @@
return 0;
else
return partnerPointList->size(); }
+
+ CubitBoolean is_in_volume( ChollaVolume *chvol_ptr );
SetDynamicMemoryAllocation(memoryManager)
//- class specific new and delete operators
@@ -177,6 +202,11 @@
CubitBoolean is_partner( CubitFacetEdge *edge_ptr );
CubitBoolean is_partner( CubitPoint *point_ptr );
+
+ void reset_TD_as_new();
+
+ int geo_type();
+
};
Modified: cgm/branches/cubit/geom/Cholla/debug.cpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/debug.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/debug.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -5,6 +5,7 @@
#include "CubitFacetEdge.hpp"
#include "GfxDebug.hpp"
#include "CubitBox.hpp"
+#include "ChollaSurface.hpp"
#include "debug.hpp"
static int fg_color = CUBIT_MAGENTA;
@@ -62,6 +63,15 @@
GfxDebug::zoom(box);
}
+
+void dsurfdraw( ChollaSurface *surf)
+{
+ DLIList<FacetEntity*> surface_facets;
+ surf->get_facets(surface_facets);
+ dldraw(surface_facets);
+}
+
+
void dldraw( DLIList<FacetEntity *> &facet_list )
{
FacetEntity *facet_ptr;
Modified: cgm/branches/cubit/geom/Cholla/debug.hpp
===================================================================
--- cgm/branches/cubit/geom/Cholla/debug.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Cholla/debug.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -9,6 +9,8 @@
class CubitPoint;
class CubitVector;
class CubitBox;
+class ChollaSurface;
+
template <class X> class DLIList;
void dcolor(int icol);
@@ -21,6 +23,8 @@
void dpdraw( CubitPoint *facet_ptr );
+void dsurfdraw( ChollaSurface *surf);
+
void dview();
void dzoom(CubitBox &box);
Modified: cgm/branches/cubit/geom/CubitAttrib.cpp
===================================================================
--- cgm/branches/cubit/geom/CubitAttrib.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/CubitAttrib.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -21,8 +21,8 @@
#include "GeometryQueryTool.hpp"
-
+
CubitAttrib::CubitAttrib(RefEntity *attrib_owner)
{
attribOwnerEntity = attrib_owner;
@@ -31,12 +31,12 @@
hasWritten = CUBIT_FALSE;
deleteAttrib = CUBIT_FALSE;
nextAttrib = NULL;
-
+
// add this to the owner
if (attrib_owner) attrib_owner->add_cubit_attrib(this);
}
-CubitAttrib::~CubitAttrib()
+CubitAttrib::~CubitAttrib()
{
if( !hasActuated )
CADeferredAttrib::remove_unactuated_ca( this );
@@ -50,7 +50,7 @@
ref_ent = entity_list.get_and_step();
ref_ent->actuate_cubit_attrib(CA_ENTITY_NAME);
ref_ent->actuate_cubit_attrib ( CA_UNIQUE_ID );
- ref_ent->actuate_cubit_attrib(CA_SIZING_FUNCTION_SKELETON);
+ ref_ent->actuate_cubit_attrib(CA_SIZING_FUNCTION_SKELETON);
ref_ent->actuate_cubit_attrib(CA_MESH_INTERVAL);
ref_ent->actuate_cubit_attrib(CA_GROUP);
ref_ent->actuate_cubit_attrib(CA_GENESIS_ENTITY);
@@ -90,10 +90,10 @@
ref_ent->actuate_cubit_attrib(CA_MATERIAL_BLOCK);
//#endif
ref_ent->actuate_cubit_attrib(CA_MERGE_STATUS);
- }
+ }
return CUBIT_SUCCESS;
}
-
+
void CubitAttrib::has_written(CubitBoolean set_has_written)
{
hasWritten = set_has_written;
@@ -121,7 +121,7 @@
{
//- return true if the csa and this are equivalent
CubitSimpleAttrib* this_csa_ptr = cubit_simple_attrib();
-
+
CubitBoolean equivalent =
CubitSimpleAttrib::equivalent(csa_ptr, this_csa_ptr);
delete this_csa_ptr;
Modified: cgm/branches/cubit/geom/CubitAttribUser.cpp
===================================================================
--- cgm/branches/cubit/geom/CubitAttribUser.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/CubitAttribUser.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -127,6 +127,9 @@
GeometryEntity* GE_ptr =
BTE_ptr->get_geometry_entity_ptr();
+ if( NULL == GE_ptr )
+ return CUBIT_FAILURE;
+
// check for duplicates
if (DEBUG_FLAG(94))
{
@@ -171,6 +174,41 @@
return CUBIT_SUCCESS;
}
+CubitStatus CubitAttribUser::clear_simple_attribs_set_to_actuate()
+{
+ CubitAttrib *cubit_attrib_ptr = NULL;
+ CubitAttrib *next_attrib_ptr = NULL;
+ for(cubit_attrib_ptr = headAttrib;
+ cubit_attrib_ptr != NULL;)
+ {
+ //ignore Assembly and Name attributes
+ next_attrib_ptr = cubit_attrib_ptr->next_attrib();
+ if( cubit_attrib_ptr->int_attrib_type() != CA_ENTITY_NAME &&
+ cubit_attrib_ptr->int_attrib_type() != CA_ASSEMBLY_DATA &&
+ CGMApp::instance()->attrib_manager()->auto_actuate_flag(
+ cubit_attrib_ptr->int_attrib_type()))
+ {
+ remove_cubit_attrib( cubit_attrib_ptr );
+ delete cubit_attrib_ptr;
+ }
+ cubit_attrib_ptr = next_attrib_ptr;
+ }
+
+ if (DEBUG_FLAG(94))
+ {
+ PRINT_DEBUG_94("CubitAttribUser::clear_simple_attribs()\n");
+ }
+ TopologyEntity* te_ptr = dynamic_cast<TopologyEntity*>(this);
+ if( !te_ptr )
+ return CUBIT_FAILURE;
+
+ remove_all_simple_attribute(te_ptr->bridge_manager()->topology_bridge());
+ write_cubit_attrib_by_type(CA_ASSEMBLY_DATA);
+ write_cubit_attrib_by_type( CA_ENTITY_NAME );
+ set_written_flag(CUBIT_FALSE);
+ return CUBIT_SUCCESS;
+}
+
CubitStatus CubitAttribUser::clear_simple_attribs()
{
@@ -182,7 +220,7 @@
//ignore Assembly and Name attributes
next_attrib_ptr = cubit_attrib_ptr->next_attrib();
if( cubit_attrib_ptr->int_attrib_type() != CA_ENTITY_NAME &&
- cubit_attrib_ptr->int_attrib_type() != CA_ASSEMBLY_DATA )
+ cubit_attrib_ptr->int_attrib_type() != CA_ASSEMBLY_DATA)
{
remove_cubit_attrib( cubit_attrib_ptr );
delete cubit_attrib_ptr;
@@ -538,14 +576,14 @@
attrib->att_internal_name(), attrib->attrib_owner()->class_name(),
attrib->attrib_owner()->id());
- if (attrib->actuate() == CUBIT_FAILURE)
+ if(attrib->actuate() == CUBIT_FAILURE)
{
actuate_status = CUBIT_FAILURE;
}
// need to check again for delete flag, since it might have been set
// in actuate function
- if (attrib->delete_attrib() == CUBIT_TRUE)
+ if( attrib->delete_attrib() == CUBIT_TRUE)
{
remove_cubit_attrib(attrib);
delete attrib;
@@ -605,6 +643,7 @@
CubitStatus CubitAttribUser::auto_update_cubit_attrib ()
{
+
// for this cau, automatically create and update ca's
// first, create ca's for any attribute type which has its auto
@@ -731,6 +770,14 @@
return result;
}
+CubitStatus CubitAttribUser::clear_all_simple_attrib_set_to_actuate( DLIList<RefEntity*>& entity_list )
+{
+ CubitStatus result = CUBIT_SUCCESS;
+ for( int i = entity_list.size(); i--; )
+ if( entity_list.get_and_step()->clear_simple_attribs_set_to_actuate() != CUBIT_SUCCESS )
+ result = CUBIT_FAILURE;
+ return result;
+}
void CubitAttribUser::find_cubit_attrib_type (int type,
DLIList<CubitAttrib*>& attrib_list) const
Modified: cgm/branches/cubit/geom/CubitAttribUser.hpp
===================================================================
--- cgm/branches/cubit/geom/CubitAttribUser.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/CubitAttribUser.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -69,6 +69,9 @@
CubitStatus clear_simple_attribs();
// Remove all CubitSimpleAttrib from TopologyBridges.
+
+ CubitStatus clear_simple_attribs_set_to_actuate();
+ // Remove all CubitSimpleAttrib from TopologyBridges if attrib type's actuate was set to true
public:
CubitStatus auto_read_cubit_attrib ();
@@ -158,6 +161,9 @@
static CubitStatus clear_all_simple_attrib( DLIList<RefEntity*>& entity_list );
//- remove all CubitSimpleAttrib from TopologyBridges.
+ static CubitStatus clear_all_simple_attrib_set_to_actuate( DLIList<RefEntity*>& entity_list );
+ //- remove all CubitSimpleAttrib from TopologyBridges that have actuate flag set to true.
+
private:
static void auto_reset_cubit_attrib(DLIList<RefEntity*> ref_ents);
//- set the update flag on all attribs on these entities and their children to false
Modified: cgm/branches/cubit/geom/CubitGeomConfigure.h.in
===================================================================
--- cgm/branches/cubit/geom/CubitGeomConfigure.h.in 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/CubitGeomConfigure.h.in 2010-01-06 19:22:14 UTC (rev 3423)
@@ -4,13 +4,21 @@
#cmakedefine CUBIT_GEOM_BUILD_SHARED_LIBS
-#if defined(WIN32) && defined(CUBIT_GEOM_BUILD_SHARED_LIBS)
+#if defined(CUBIT_GEOM_BUILD_SHARED_LIBS)
#if defined(cubit_geom_EXPORTS)
-#define CUBIT_GEOM_EXPORT __declspec(dllexport)
+# if defined(WIN32)
+# define CUBIT_GEOM_EXPORT __declspec(dllexport)
+# elif defined(__GNUC__) && __GNUC__ >= 4
+# define CUBIT_GEOM_EXPORT __attribute__ ((visibility("default")))
+# endif
#else
-#define CUBIT_GEOM_EXPORT __declspec(dllimport)
+# if defined(WIN32)
+# define CUBIT_GEOM_EXPORT __declspec(dllimport)
+# endif
#endif
-#else
+#endif
+
+#ifndef CUBIT_GEOM_EXPORT
#define CUBIT_GEOM_EXPORT
#endif
Modified: cgm/branches/cubit/geom/Curve.cpp
===================================================================
--- cgm/branches/cubit/geom/Curve.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Curve.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -245,15 +245,25 @@
{
// If not within parameter range, return
// the the closest endpoint
+ CubitVector start, end;
+ position_from_u( start_param, start );
+ position_from_u( end_param, end );
+
if( (param < start_param) || (param > end_param) )
{
- CubitVector start, end;
- position_from_u( start_param, start );
- position_from_u( end_param, end );
result = ( (start - result).length_squared() <
(end - result).length_squared() ) ? start : end ;
}
+ else
+ {
+ double tmp_dist_sq = (from_pt - result).length_squared();
+ if( (start-from_pt).length_squared() < tmp_dist_sq )
+ result = start;
+ else if( (end-from_pt).length_squared() < tmp_dist_sq )
+ result = end;
+ }
}
+
return CUBIT_SUCCESS;
}
Modified: cgm/branches/cubit/geom/CurveOverlapFacet.cpp
===================================================================
--- cgm/branches/cubit/geom/CurveOverlapFacet.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/CurveOverlapFacet.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -6,6 +6,7 @@
#include "CurveOverlapFacet.hpp"
#include "IntersectionTool.hpp"
+#include "GfxPreview.hpp"
//AnalyticGeometryTool* CurveOverlapFacet::agt = AnalyticGeometryTool::instance();
@@ -270,3 +271,20 @@
return dP.length(); // return the closest distance
}
+
+void CurveOverlapFacet::draw( int color )
+{
+ GfxPreview::draw_line( p0, p1, color );
+ return;
+}
+
+CubitVector CurveOverlapFacet::start_point()
+{
+ return p0;
+}
+
+CubitVector CurveOverlapFacet::end_point()
+{
+ return p1;
+}
+
Modified: cgm/branches/cubit/geom/CurveOverlapFacet.hpp
===================================================================
--- cgm/branches/cubit/geom/CurveOverlapFacet.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/CurveOverlapFacet.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -32,6 +32,11 @@
double facet_to_facet_distance( CurveOverlapFacet *other_facet );
+ void draw( int color );
+
+ CubitVector start_point();
+ CubitVector end_point();
+
protected:
private:
Modified: cgm/branches/cubit/geom/DAG.hpp
===================================================================
--- cgm/branches/cubit/geom/DAG.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/DAG.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -71,6 +71,8 @@
~DAG() ;
//- Destructor
+
+ static void delete_instance() { if(instance_) delete instance_; };
void add_deactivated_DAG_node(ModelEntity* deactivatedDAGNodePtr) ;
//R void
Modified: cgm/branches/cubit/geom/DagDrawingTool.hpp
===================================================================
--- cgm/branches/cubit/geom/DagDrawingTool.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/DagDrawingTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -58,10 +58,10 @@
class CUBIT_GEOM_EXPORT DagDrawingTool
{
- public:
+ public:
- static DagDrawingTool* instance();
- ~DagDrawingTool();
+ static DagDrawingTool* instance();
+ ~DagDrawingTool();
/*
void draw_DAG( DLIList<Body*>& body_list, int down );
void draw_DAG( DLIList<RefVolume*>& volume_list, int up, int down );
@@ -135,11 +135,18 @@
int window_id() const;
//The last window drawn in my DagDrawingTool
-*/
+*/
+
+ //! Print the DAG of the specified surfaces.
void printDag(DLIList<RefFace*> &face_list, int depth);
+
+ //! Print the DAG of the specified body.
void printDag(DLIList<Body*> &body_list, int depth);
+
+ //! Print the DAG of the entities.
void printDag(DLIList<ModelEntity*> &entity_list, int depth);
+ //! Print the DAG of the entity.
void printDag( ModelEntity* ME_ptr, int depth );
protected:
Modified: cgm/branches/cubit/geom/GSaveOpen.cpp
===================================================================
--- cgm/branches/cubit/geom/GSaveOpen.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/GSaveOpen.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -8,6 +8,7 @@
#include "RefEntityFactory.hpp"
// Initialize Globals
+int GSaveOpen::performingUndo = 0;
int GSaveOpen::gsoSetsIds = 0;
int GSaveOpen::gsoIncBodyId = 0;
int GSaveOpen::gsoIncRefVolumeId = 0;
@@ -20,13 +21,25 @@
GSaveOpen::GSaveOpen()
{
RefEntityFactory *ref = RefEntityFactory::instance();
-
- gsoSetsIds = 1;
- gsoIncBodyId = ref->current_body_id();
- gsoIncRefVolumeId = ref->current_volume_id();
- gsoIncRefFaceId = ref->current_face_id();
- gsoIncRefEdgeId = ref->current_edge_id();
- gsoIncRefVertexId = ref->current_vertex_id();
+
+ if( performingUndo == 1 )
+ {
+ gsoSetsIds = 0;
+ gsoIncBodyId = 0;
+ gsoIncRefVolumeId = 0;
+ gsoIncRefFaceId = 0;
+ gsoIncRefEdgeId = 0;
+ gsoIncRefVertexId = 0;
+ }
+ else
+ {
+ gsoSetsIds = 1;
+ gsoIncBodyId = ref->current_body_id();
+ gsoIncRefVolumeId = ref->current_volume_id();
+ gsoIncRefFaceId = ref->current_face_id();
+ gsoIncRefEdgeId = ref->current_edge_id();
+ gsoIncRefVertexId = ref->current_vertex_id();
+ }
gsoErrorCount = 0;
}
Modified: cgm/branches/cubit/geom/GSaveOpen.hpp
===================================================================
--- cgm/branches/cubit/geom/GSaveOpen.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/GSaveOpen.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -25,10 +25,10 @@
static int get_id_inc( RefEntity *entity );
static void set_error();
static void add_error_id( int id );
+ static int performingUndo;
protected:
static int gsoSetsIds;
-
static int gsoIncBodyId;
static int gsoIncRefVolumeId;
static int gsoIncRefFaceId;
Modified: cgm/branches/cubit/geom/GeomMeasureTool.cpp
===================================================================
--- cgm/branches/cubit/geom/GeomMeasureTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/GeomMeasureTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -40,6 +40,10 @@
#include "ProgressTool.hpp"
#include "AppUtil.hpp"
+#include <set>
+#include <map>
+#include <stack>
+#include <algorithm>
void GeomMeasureTool::get_edges_from_list(DLIList <RefEntity*> &entity_list,
DLIList <RefEdge*> &ref_edges )
@@ -1175,31 +1179,98 @@
ratio = (double) ((double)merged_surfaces / (double)unmerged_surfaces);
}
-void GeomMeasureTool::report_intersected_bodies(DLIList <RefVolume*> &volume_list,
- DLIList <Body*> &intersection_list)
+void GeomMeasureTool::report_intersected_volumes(DLIList <RefVolume*> &ref_vols,
+ DLIList <RefVolume*> &intersection_list)
{
- DLIList <Body*> bodies;
- get_bodies_from_list( volume_list, bodies);
- report_intersected_bodies( bodies, intersection_list);
+ DLIList <RefVolume*> results;
+ RefVolume *curr_vol;
+ int i, j;
+ ProgressTool *progress_ptr = NULL;
+ int total_volumes = ref_vols.size();
+ if (total_volumes > 5)
+ {
+ progress_ptr = AppUtil::instance()->progress_tool();
+ assert(progress_ptr != NULL);
+ progress_ptr->start(0, 100, "Overlapping Volumes Progress",
+ NULL, CUBIT_TRUE, CUBIT_TRUE);
+ }
+ double curr_percent = 0.0;
+
+ for( i = 0; i < ref_vols.size(); i++ )
+ {
+ curr_vol = ref_vols.next(i);
+
+ //is this body a multi-volume-body?
+ Body *single_volume_body = curr_vol->body();
+ DLIList<RefVolume*> body_vols;
+ single_volume_body->ref_volumes( body_vols );
+ if( body_vols.size() > 1 )
+ single_volume_body = NULL;
+
+ for( j = (i + 1); j < ref_vols.size(); j++ )
+ {
+ RefVolume *curr_vol2 = ref_vols.next(j);
+ if ( CubitMessage::instance()->Interrupt() )
+ {
+ //interrpt. We need to exit.
+ if ( progress_ptr != NULL )
+ {
+ progress_ptr->end();
+ }
+ //just leave what has been calculated...
+ return;
+ }
+
+ Body *single_volume_body2 = curr_vol2->body();
+ DLIList<RefVolume*> body_vols2;
+ single_volume_body2->ref_volumes( body_vols2 );
+ if( body_vols2.size() > 1 )
+ single_volume_body2 = NULL;
+
+ //update the progress..
+ if ( progress_ptr != NULL )
+ {
+ curr_percent = ((double)(i+1))/((double)(total_volumes));
+ progress_ptr->percent(curr_percent);
+ }
+
+ //if both are single-volume-bodies
+ if( single_volume_body && single_volume_body2 )
+ {
+ if( GeometryQueryTool::instance()->bodies_overlap( single_volume_body,
+ single_volume_body2 ) )
+ {
+ intersection_list.append( curr_vol );
+ intersection_list.append( curr_vol2 );
+ }
+ }
+ else if( GeometryQueryTool::instance()->volumes_overlap( curr_vol, curr_vol2 ) )
+ {
+ intersection_list.append( curr_vol );
+ intersection_list.append( curr_vol2 );
+ }
+ }
+ }
+ if ( progress_ptr != NULL )
+ {
+ progress_ptr->end();
+ }
}
void GeomMeasureTool::report_intersected_bodies(DLIList <Body*> &ref_bodies,
DLIList <Body*> &intersection_list)
{
-
- DLIList <Body*> results;
Body *curr_body, *curr_body_2;
int ii, jj;
ProgressTool *progress_ptr = NULL;
- char title[29];
int total_bodies = ref_bodies.size();
if (total_bodies > 5)
{
- strcpy(title, "Overlapping Volumes Progress");
progress_ptr = AppUtil::instance()->progress_tool();
assert(progress_ptr != NULL);
- progress_ptr->start(0, 100, title, NULL, CUBIT_TRUE, CUBIT_TRUE);
+ progress_ptr->start(0, 100, "Overlapping Volumes Progress",
+ NULL, CUBIT_TRUE, CUBIT_TRUE);
}
double curr_percent = 0.0;
@@ -1211,7 +1282,6 @@
for( jj = (ii + 1); jj < ref_bodies.size(); jj++ )
{
curr_body_2 = ref_bodies.next(jj);
- results.clean_out();
if ( CubitMessage::instance()->Interrupt() )
{
//interrpt. We need to exit.
@@ -1224,11 +1294,10 @@
}
if (GeometryQueryTool::instance()->bodies_overlap(curr_body,
- curr_body_2) )
+ curr_body_2) )
{
intersection_list.append(curr_body);
intersection_list.append(curr_body_2);
- GeometryQueryTool::instance()->delete_Body(results);
}
}
//update the progress..
@@ -1375,20 +1444,6 @@
}
}
-void GeomMeasureTool::ratio_of_shells_to_volumes(int number_of_shells,
- DLIList <RefVolume*> &ref_volumes,
- int &number_of_volumes,
- double &ratio)
-{
- int ii, number = 0;
-
- for( ii = ref_volumes.size(); ii > 0; ii-- )
- number++;
- number_of_volumes = number;
-
- ratio = (double) ((double)number_of_shells / (double)number_of_volumes);
-
-}
void GeomMeasureTool::print_surface_measure_summary( DLIList <RefFace*> &ref_faces )
{
@@ -1837,6 +1892,725 @@
return;
}
+
+// Find all of the surfaces in the given volumes that have narrow regions.
+void GeomMeasureTool::find_surfs_with_narrow_regions(DLIList <RefVolume*> &ref_vols,
+ double tol,
+ DLIList <RefFace*> &surfs_with_narrow_regions)
+{
+ int j;
+ double tol_sq = tol*tol;
+
+ int ii, jj;
+ DLIList <RefFace*> ref_faces, temp_faces;
+ RefVolume *ref_vol;
+ RefFace *curr_face;
+ for ( ii = 0; ii < ref_vols.size(); ii++ )
+ {
+ DLIList<RefFace*> faces;
+ ref_vol = ref_vols.get_and_step();
+ ref_vol->ref_faces(faces);
+ for ( jj = faces.size(); jj > 0; jj-- )
+ {
+ curr_face = faces.get_and_step();
+ curr_face->marked(0);
+ temp_faces.append(curr_face);
+ }
+ }
+
+ //uniquely add the faces.
+ for ( jj = temp_faces.size(); jj > 0; jj-- )
+ {
+ curr_face = temp_faces.get_and_step();
+ if ( curr_face->marked()== 0 )
+ {
+ curr_face->marked(1);
+ ref_faces.append(curr_face);
+ }
+ }
+
+ int num_faces = ref_faces.size();
+
+ ProgressTool *progress_ptr = NULL;
+ if (num_faces > 20)
+ {
+ progress_ptr = AppUtil::instance()->progress_tool();
+ assert(progress_ptr != NULL);
+ progress_ptr->start(0, 100, "Finding Surfaces with Narrow Regions",
+ NULL, CUBIT_TRUE, CUBIT_TRUE);
+ }
+
+ int total_faces = 0;
+ double curr_percent = 0.0;
+
+ for(j=0; j<num_faces; j++)
+ {
+ DLIList<CubitVector> split_pos1_list;
+ DLIList<CubitVector> split_pos2_list;
+ RefFace *cur_face = ref_faces.get_and_step();
+ total_faces++;
+ if ( progress_ptr != NULL )
+ {
+ curr_percent = ((double)(total_faces))/((double)(num_faces));
+ progress_ptr->percent(curr_percent);
+ }
+
+ if ( CubitMessage::instance()->Interrupt() )
+ {
+ //interrpt. We need to exit.
+ if ( progress_ptr != NULL )
+ progress_ptr->end();
+ //just leave what has been calculated...
+ return;
+ }
+ find_split_points_for_narrow_regions(cur_face,
+ tol, split_pos1_list, split_pos2_list);
+ if(split_pos1_list.size() > 0)
+ surfs_with_narrow_regions.append_unique(cur_face);
+ }
+
+ if ( progress_ptr != NULL )
+ progress_ptr->end();
+}
+
+bool GeomMeasureTool::is_surface_narrow(RefFace *face, double small_curve_size)
+{
+ bool ret = true;
+ DLIList<RefEdge*> edges;
+ face->ref_edges(edges);
+ RefVolume *vol = face->ref_volume();
+ int i, j;
+ double dist_sq = small_curve_size*small_curve_size;
+ double proj_dist = 1.2 * small_curve_size;
+ for(i=edges.size(); i>0 && ret == true; i--)
+ {
+ RefEdge *cur_edge = edges.get_and_step();
+ double edge_length = cur_edge->measure();
+ if(edge_length > small_curve_size)
+ {
+ int num_incs = (int)(edge_length/small_curve_size) + 1;
+ double start, end;
+ cur_edge->get_param_range(start, end);
+ double dt = small_curve_size*((end-start)/edge_length);
+ double t = start;
+ bool one_bad = false;
+ for(j=0; j<num_incs && ret == true; j++)
+ {
+ CubitVector pos1, tangent;
+ cur_edge->position_from_u(t, pos1);
+ cur_edge->tangent(pos1, tangent, face);
+ CubitVector norm = face->normal_at(pos1, vol);
+ CubitVector indir = norm * tangent;
+ indir.normalize();
+ CubitVector new_pos = pos1 + proj_dist * indir;
+ CubitVector pt_on_surf;
+ face->get_surface_ptr()->closest_point_trimmed(new_pos, pt_on_surf);
+ if((pt_on_surf-pos1).length_squared() < dist_sq)
+ {
+ one_bad = false;
+ }
+ else // we found one out of small_curve range
+ {
+ if(one_bad) // if we had already found one out of range this makes two in a row
+ ret = false;
+ else // this is the first one out of range
+ one_bad = true;
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+void GeomMeasureTool::find_split_points_for_narrow_regions(RefFace *face,
+ double size,
+ DLIList<CubitVector> &split_pos1_list,
+ DLIList<CubitVector> &split_pos2_list)
+{
+ int k, i, j;
+ double size_sq = size*size;
+ DLIList<RefEdge*> edges;
+ face->ref_edges(edges);
+ while(edges.size() > 1)
+ {
+ RefEdge *cur_edge = edges.extract();
+ for(k=edges.size(); k--;)
+ {
+ RefEdge *other_edge = edges.get_and_step();
+ DLIList<CubitVector*> e1_pos_list, e2_pos_list;
+ DLIList<RefVertex*> e1_vert_list, e2_vert_list;
+ if(narrow_region_exists(cur_edge, other_edge, face, size,
+ e1_pos_list, e2_pos_list, e1_vert_list, e2_vert_list))
+ {
+ e1_pos_list.reset();
+ e2_pos_list.reset();
+ e1_vert_list.reset();
+ e2_vert_list.reset();
+
+ // Loop through each pair of positions defining a split.
+ for(i=e1_pos_list.size(); i--;)
+ {
+ int do_the_split = 1;
+ RefVertex *e1_vert = e1_vert_list.get_and_step();
+ RefVertex *e2_vert = e2_vert_list.get_and_step();
+ CubitVector *e1_pos = e1_pos_list.get_and_step();
+ CubitVector *e2_pos = e2_pos_list.get_and_step();
+
+ // Snap to existing vertices if we are not already at at vertex.
+ if(!e1_vert)
+ {
+ if((cur_edge->start_vertex()->coordinates() - *e1_pos).length_squared() < size_sq)
+ e1_vert = cur_edge->start_vertex();
+ else if((cur_edge->end_vertex()->coordinates() - *e1_pos).length_squared() < size_sq)
+ e1_vert = cur_edge->end_vertex();
+ }
+ if(!e2_vert)
+ {
+ if((other_edge->start_vertex()->coordinates() - *e2_pos).length_squared() < size_sq)
+ e2_vert = other_edge->start_vertex();
+ else if((other_edge->end_vertex()->coordinates() - *e2_pos).length_squared() < size_sq)
+ e2_vert = other_edge->end_vertex();
+ }
+
+ // We may have multiple edges separating these two vertices but the accumulated
+ // length of them may still be within our narrow size so check this. If this
+ // is the case we will not want to consider this as a place to split and
+ // will as a result discard these positions.
+ if(e1_vert && e2_vert)
+ {
+ double dist = size*sqrt(2.0);
+ RefVertex *cur_vert = e1_vert;
+ RefEdge *edge = cur_edge;
+ double length = 0.0;
+ while(edge && cur_vert != e2_vert && length <= dist)
+ {
+ edge = edge->get_other_curve(cur_vert, face);
+ if(edge)
+ {
+ length += edge->get_arc_length();
+ cur_vert = edge->other_vertex(cur_vert);
+ }
+ }
+ if(length <= dist)
+ do_the_split = 0;
+ else
+ {
+ // We want to keep this split.
+ split_pos1_list.append(e1_vert->coordinates());
+ split_pos2_list.append(e2_vert->coordinates());
+ }
+ }
+ else
+ {
+ // We want to keep this split.
+ split_pos1_list.append(*e1_pos);
+ split_pos2_list.append(*e2_pos);
+ }
+ }
+ }
+ while(e1_pos_list.size())
+ delete e1_pos_list.pop();
+ while(e2_pos_list.size())
+ delete e2_pos_list.pop();
+ }
+ }
+
+ // Make splits unique
+ DLIList<CubitVector> unique_list1, unique_list2;
+ split_pos1_list.reset();
+ split_pos2_list.reset();
+ for(i=split_pos1_list.size(); i--;)
+ {
+ CubitVector p1 = split_pos1_list.get_and_step();
+ CubitVector p2 = split_pos2_list.get_and_step();
+ int unique = 1;
+ for(j=unique_list1.size(); j>0 && unique; j--)
+ {
+ CubitVector u1 = unique_list1.get_and_step();
+ CubitVector u2 = unique_list2.get_and_step();
+ if((p1.about_equal(u1) && p2.about_equal(u2)) ||
+ (p1.about_equal(u2) && p2.about_equal(u1)))
+ {
+ unique = 0;
+ }
+ }
+ if(unique)
+ {
+ unique_list1.append(p1);
+ unique_list2.append(p2);
+ }
+ }
+ split_pos1_list = unique_list1;
+ split_pos2_list = unique_list2;
+}
+
+// Checks to see if at the given position the two edges are close together and
+// have the same tangent.
+int GeomMeasureTool::is_narrow_region_at_point(RefEdge *e1,
+ RefFace *face,
+ const CubitVector &pt_on_e1,
+ RefEdge *e2,
+ const double &tol_sq,
+ CubitVector &closest)
+{
+ int ret = 0;
+
+ CubitVector tan_1, tan_2;
+ e2->closest_point_trimmed(pt_on_e1, closest);
+ double dist = (pt_on_e1-closest).length_squared();
+ if(dist < tol_sq)
+ {
+ DLIList<CoEdge*> coes;
+ e1->tangent(pt_on_e1, tan_1);
+ e2->tangent(closest, tan_2);
+ e1->get_co_edges(coes, face);
+ if(coes.size() == 1)
+ {
+ if(coes.get()->get_sense() == CUBIT_REVERSED)
+ tan_1 *= -1.0;
+ coes.clean_out();
+ e2->get_co_edges(coes, face);
+ if(coes.size() == 1)
+ {
+ if(coes.get()->get_sense() == CUBIT_REVERSED)
+ tan_2 *= -1.0;
+ tan_1.normalize();
+ tan_2.normalize();
+ if(tan_1 % tan_2 < -0.9)
+ ret = 1;
+ }
+ }
+ }
+ return ret;
+}
+
+int GeomMeasureTool::narrow_region_exists(RefFace *face,
+ const double &tol)
+{
+ int k, ret = 0;
+ DLIList<RefEdge*> edges;
+ face->ref_edges(edges);
+ int num_curves = edges.size();
+ int num_small_curves = 0;
+ while(edges.size() > 1 && !ret)
+ {
+ // Remove the current edge each time so that we aren't
+ // doing redundant comparisons.
+ RefEdge *cur_edge = edges.extract();
+ if(cur_edge->get_arc_length() < tol)
+ num_small_curves++;
+
+ // Compare this edge with the remaining edges on the face.
+ for(k=edges.size(); k && !ret; k--)
+ {
+ RefEdge *other_edge = edges.get_and_step();
+
+ DLIList<CubitVector*> e1_pos_list, e2_pos_list;
+ DLIList<RefVertex*> 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();
+ }
+ }
+ if(!ret)
+ {
+ if(edges.size() == 1 && edges.get()->get_arc_length() < tol)
+ num_small_curves++;
+ }
+
+ ret = ret || (num_small_curves == num_curves);
+
+ return ret;
+}
+
+int GeomMeasureTool::narrow_region_exists(RefFace *face,
+ RefEdge *edge,
+ const double &tol)
+{
+ int k, ret = 0;
+ DLIList<RefEdge*> edges;
+ face->ref_edges(edges);
+ if(edges.move_to(edge))
+ {
+ edges.extract();
+
+ // Compare this edge with the remaining edges on the face.
+ for(k=edges.size(); k && !ret; k--)
+ {
+ RefEdge *other_edge = edges.get_and_step();
+
+ DLIList<CubitVector*> e1_pos_list, e2_pos_list;
+ DLIList<RefVertex*> e1_vert_list, e2_vert_list;
+ ret = narrow_region_exists(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 GeomMeasureTool::narrow_region_exists(
+ RefEdge *e1,
+ RefEdge *e2,
+ RefFace *face,
+ const double &tol,
+ DLIList<CubitVector*> &e1_pos_list,
+ DLIList<CubitVector*> &e2_pos_list,
+ DLIList<RefVertex*> &e1_vert_list,
+ DLIList<RefVertex*> &e2_vert_list)
+{
+ int ret = 0;
+ double tol_sq = tol*tol;
+ double small_step = 5.0*tol;
+ double small_step_sq = small_step*small_step;
+ double max_dist_sq = 0.0;
+ RefVertex *e1_start_vert = e1->start_vertex();
+ RefVertex *e1_end_vert = e1->end_vertex();
+
+ CubitVector closest;
+ DLIList<RefVertex*> e1_verts, e2_verts;
+
+ e1->ref_vertices(e1_verts);
+ e2->ref_vertices(e2_verts);
+ e1_verts.intersect_unordered(e2_verts);
+ int num_shared_verts = e1_verts.size();
+ RefVertex *shared_vert = NULL;
+ RefEdge *edge1 = NULL;
+ RefEdge *edge2 = NULL;
+ if(num_shared_verts == 1)
+ {
+ shared_vert = e1_verts.get();
+ DLIList<CoEdge*> coes;
+ e1->get_co_edges(coes, face);
+ if(coes.size() == 1)
+ {
+ RefVolume *vol = face->ref_volume();
+ CubitSense facevol_sense = face->sense(vol);
+ if((coes.get()->start_vertex() == shared_vert) ==
+ (facevol_sense == CUBIT_FORWARD))
+ {
+ edge1 = e1;
+ edge2 = e2;
+ }
+ else
+ {
+ edge1 = e2;
+ edge2 = e1;
+ }
+ }
+ }
+
+ // Project cur endpoints onto other.
+ int do_narrow_region_check = 1;
+ if(num_shared_verts == 1 && shared_vert == e1_start_vert)
+ {
+ // Edges are next to each other. Check the angle between them
+ // before doing anything else.
+ double interior_angle = edge1->angle_between(edge2, face);
+ if(interior_angle > CUBIT_PI/4.0)
+ do_narrow_region_check = 0;
+ }
+ if(do_narrow_region_check &&
+ is_narrow_region_at_point(e1, face, e1_start_vert->coordinates(), e2, tol_sq, closest))
+ {
+ max_dist_sq = (closest - e1_start_vert->coordinates()).length_squared();
+ e1_pos_list.append(new CubitVector(e1_start_vert->coordinates()));
+ e2_pos_list.append(new CubitVector(closest));
+ e1_vert_list.append(e1_start_vert);
+ e2_vert_list.append(NULL);
+ }
+ do_narrow_region_check = 1;
+ if(num_shared_verts == 1 && shared_vert == e1_end_vert)
+ {
+ // Edges are next to each other. Check the angle between them
+ // before doing anything else.
+ double interior_angle = edge1->angle_between(edge2, face);
+ if(interior_angle > CUBIT_PI/4.0)
+ do_narrow_region_check = 0;
+ }
+ if(do_narrow_region_check &&
+ is_narrow_region_at_point(e1, face, e1_end_vert->coordinates(), e2, tol_sq, closest))
+ {
+ double cur_dist_sq = (closest - e1_end_vert->coordinates()).length_squared();
+ max_dist_sq = max_dist_sq > cur_dist_sq ? max_dist_sq : cur_dist_sq;
+ e1_pos_list.append(new CubitVector(e1_end_vert->coordinates()));
+ e2_pos_list.append(new CubitVector(closest));
+ e1_vert_list.append(e1_end_vert);
+ e2_vert_list.append(NULL);
+ }
+
+ if(e1_pos_list.size() < 2)
+ {
+ RefVertex *e2_start_vert = e2->start_vertex();
+ RefVertex *e2_end_vert = e2->end_vertex();
+ do_narrow_region_check = 1;
+ if(num_shared_verts == 1 && shared_vert == e2_start_vert)
+ {
+ // Edges are next to each other. Check the angle between them
+ // before doing anything else.
+ double interior_angle = edge1->angle_between(edge2, face);
+ if(interior_angle > CUBIT_PI/4.0)
+ do_narrow_region_check = 0;
+ }
+ if(do_narrow_region_check &&
+ is_narrow_region_at_point(e2, face, e2_start_vert->coordinates(), e1, tol_sq, closest))
+ {
+ if(e1_pos_list.size() == 0 || !closest.about_equal(*e1_pos_list.get()))
+ {
+ double cur_dist_sq = (closest - e2_start_vert->coordinates()).length_squared();
+ max_dist_sq = max_dist_sq > cur_dist_sq ? max_dist_sq : cur_dist_sq;
+ e2_pos_list.append(new CubitVector(e2_start_vert->coordinates()));
+ e1_pos_list.append(new CubitVector(closest));
+ e2_vert_list.append(e2_start_vert);
+ e1_vert_list.append(NULL);
+ }
+ }
+ if(e1_pos_list.size() < 2)
+ {
+ do_narrow_region_check = 1;
+ if(num_shared_verts == 1 && shared_vert == e2_end_vert)
+ {
+ // Edges are next to each other. Check the angle between them
+ // before doing anything else.
+ double interior_angle = edge1->angle_between(edge2, face);
+ if(interior_angle > CUBIT_PI/4.0)
+ do_narrow_region_check = 0;
+ }
+ if(do_narrow_region_check &&
+ is_narrow_region_at_point(e2, face, e2_end_vert->coordinates(), e1, tol_sq, closest))
+ {
+ if(e1_pos_list.size() == 0 || !closest.about_equal(*e1_pos_list.get()))
+ {
+ double cur_dist_sq = (closest - e2_end_vert->coordinates()).length_squared();
+ max_dist_sq = max_dist_sq > cur_dist_sq ? max_dist_sq : cur_dist_sq;
+ e2_pos_list.append(new CubitVector(e2_end_vert->coordinates()));
+ e1_pos_list.append(new CubitVector(closest));
+ e2_vert_list.append(e2_end_vert);
+ e1_vert_list.append(NULL);
+ }
+ }
+ }
+ }
+
+ if(e1_pos_list.size() == 2)
+ {
+ int w;
+ int all_good = 1;
+ // double dist_tol = sqrt(max_dist_sq)*5.0;
+ e1_pos_list.reset();
+ e2_pos_list.reset();
+ CubitVector *cur1 = e1_pos_list.get_and_step();
+ CubitVector *cur2 = e1_pos_list.get();
+ CubitVector *other1 = e2_pos_list.get_and_step();
+ CubitVector *other2 = e2_pos_list.get();
+
+ double len1 = e1->get_arc_length(*cur1, *cur2);
+ if(len1 > tol)
+ {
+ double len2 = e2->get_arc_length(*other1, *other2);
+ if(len2 > tol)
+ {
+ double cur_param1 = e1->u_from_position(*cur1);
+ double cur_param2 = e1->u_from_position(*cur2);
+ int num_divisions = 2;
+ CubitVector cur_pos;
+ double param_step = (cur_param2-cur_param1)/num_divisions;
+ double cur_param = cur_param1 + param_step;
+ for(w=1; w<num_divisions && all_good; w++)
+ {
+ e1->position_from_u(cur_param, cur_pos);
+ cur_param += param_step;
+ if(is_narrow_region_at_point(e1, face, cur_pos, e2, tol_sq, closest))
+ {
+ // Sanity check to make sure we aren't splitting off negative space.
+ CubitVector mid = (cur_pos + closest)/2.0;
+ CubitVector tmp_pt;
+ face->get_surface_ptr()->closest_point_trimmed(mid, tmp_pt);
+ if(!mid.about_equal(tmp_pt))
+ {
+ CubitVector norm = face->normal_at(tmp_pt);
+ CubitVector dir(tmp_pt - mid);
+ dir.normalize();
+ if(fabs(norm % dir) < .9)
+ all_good = 0;
+ }
+ }
+ }
+ }
+ else
+ all_good = 0;
+ }
+ else
+ all_good = 0;
+
+ if(all_good)
+ 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;
+ }
+ }
+
+ 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--;)
+ {
+ CubitVector *e1_pos = e1_pos_list.get_and_step();
+ CubitVector *e2_pos = e2_pos_list.get_and_step();
+ RefVertex *e1_vert = e1_vert_list.get_and_step();
+ RefVertex *e2_vert = e2_vert_list.get_and_step();
+
+ RefVertex *cur_vert = NULL;
+ RefEdge *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)
+ {
+ CubitVector next_pos;
+ CubitVector prev_pos = cur_vert->coordinates();
+ int num_incs = 20;
+ double step = cur_edge->get_arc_length()/(double)num_incs;
+ int still_good = 1;
+ int cntr = 0;
+ double direction = (cur_vert == cur_edge->start_vertex() ? 1.0 : -1.0);
+ // Do coarse traversal along curve to see where we start deviating from
+ // narrow.
+ while(still_good)
+ {
+ cur_edge->point_from_arc_length(prev_pos, step*direction, next_pos);
+ if(is_narrow_region_at_point(cur_edge, face, next_pos, other_edge, tol_sq, closest) &&
+ cntr < num_incs)
+ {
+ prev_pos = next_pos;
+ cntr++;
+ }
+ else
+ still_good = 0;
+ }
+ if(cntr < num_incs)
+ {
+ cntr = 0;
+ double cur_arc_length = cur_edge->get_arc_length(prev_pos, next_pos);
+ // Do bisection on remaining interval to zero in on point where
+ // we go from narrow to non-narrow.
+ CubitVector mid_pos;
+ double close_enough = tol/20.0;
+ while(cur_arc_length > close_enough && cntr < 100)
+ {
+ cntr++; // prevent infinite looping
+ cur_edge->point_from_arc_length(prev_pos, cur_arc_length*direction/2.0, mid_pos);
+ if(is_narrow_region_at_point(cur_edge, face, mid_pos, other_edge, tol_sq, closest))
+ prev_pos = mid_pos;
+ else
+ next_pos = mid_pos;
+ cur_arc_length = cur_edge->get_arc_length(prev_pos, next_pos);
+ }
+ if(cur_edge->get_arc_length(cur_vert->coordinates(), prev_pos) > tol)
+ {
+ // end up with the position that guarantees a new split curve that
+ // is smaller than the small curve size.
+ other_edge->closest_point_trimmed(prev_pos, closest);
+ if(cur_edge == e1)
+ {
+ e1_pos_list.append(new CubitVector(prev_pos));
+ e2_pos_list.append(new CubitVector(closest));
+ }
+ else
+ {
+ e2_pos_list.append(new CubitVector(prev_pos));
+ e1_pos_list.append(new CubitVector(closest));
+ }
+ e1_vert_list.append(NULL);
+ e2_vert_list.append(NULL);
+ ret = 1;
+ }
+ }
+ }
+ }
+ }
+
+ if(ret)
+ {
+ int i, j;
+ e1_pos_list.reset();
+ e2_pos_list.reset();
+ e1_vert_list.reset();
+ e2_vert_list.reset();
+ for(i=e1_pos_list.size(); i--;)
+ {
+ CubitVector *e1_pos = e1_pos_list.get();
+ CubitVector *e2_pos = e2_pos_list.get();
+ int num_divisions = 6;
+ CubitVector step = (*e2_pos - *e1_pos)/num_divisions;
+ CubitVector cur_pos = *e1_pos + step;
+ int removed = 0;
+ for(j=1; j<num_divisions; j++)
+ {
+ CubitVector tmp_pt;
+ face->get_surface_ptr()->closest_point_trimmed(cur_pos, tmp_pt);
+ if(!cur_pos.about_equal(tmp_pt))
+ {
+ CubitVector norm = face->normal_at(tmp_pt);
+ CubitVector dir(tmp_pt - cur_pos);
+ dir.normalize();
+ if(fabs(norm % dir) < .9)
+ {
+ removed = 1;
+ j=num_divisions;
+ e1_pos_list.remove();
+ e2_pos_list.remove();
+ e1_vert_list.remove();
+ e2_vert_list.remove();
+ }
+ }
+ else
+ cur_pos += step;
+ }
+ if(!removed)
+ {
+ e1_pos_list.step();
+ e2_pos_list.step();
+ e1_vert_list.step();
+ e2_vert_list.step();
+ }
+ }
+
+ if(e1_pos_list.size() == 0)
+ ret = 0;
+ }
+
+ return ret;
+}
+
void GeomMeasureTool::find_small_curves( DLIList <RefVolume*> &ref_vols,
double tol,
DLIList <RefEdge*> &small_curves,
@@ -1861,10 +2635,38 @@
}
}
}
+
+ int num_curves = ref_edges.size();
+ ProgressTool *progress_ptr = NULL;
+ if (num_curves> 20)
+ {
+ progress_ptr = AppUtil::instance()->progress_tool();
+ assert(progress_ptr != NULL);
+ progress_ptr->start(0, 100, "Finding Small Curves",
+ NULL, CUBIT_TRUE, CUBIT_TRUE);
+ }
+
+ int total_curves = 0;
+ double curr_percent = 0.0;
double length;
//find the small curves and reset the marked flag.
for ( ii = ref_edges.size(); ii > 0; ii-- )
{
+ total_curves++;
+ if ( progress_ptr != NULL )
+ {
+ curr_percent = ((double)(total_curves))/((double)(num_curves));
+ progress_ptr->percent(curr_percent);
+ }
+ if ( CubitMessage::instance()->Interrupt() )
+ {
+ //interrpt. We need to exit.
+ if ( progress_ptr != NULL )
+ progress_ptr->end();
+ //just leave what has been calculated...
+ return;
+ }
+
curr_edge = ref_edges.get_and_step();
//skip point curves
@@ -1879,8 +2681,115 @@
small_lengths.append(length);
}
}
+
+ if ( progress_ptr != NULL )
+ progress_ptr->end();
+
return;
}
+
+RefEdge* GeomMeasureTool::find_first_small_curve(RefVolume* vol,
+ double tol)
+{
+ RefEdge *ret = NULL;
+ int j;
+ DLIList <RefEdge*> ref_edges;
+ vol->ref_edges(ref_edges);
+ for(j=ref_edges.size(); j > 0 && !ret; j--)
+ {
+ RefEdge *curr_edge = ref_edges.get_and_step();
+ if(curr_edge->measure() <= tol)
+ ret = curr_edge;
+ }
+ return ret;
+}
+
+void GeomMeasureTool::find_narrow_faces(DLIList<RefVolume*> &ref_vols,
+ double small_curve_size,
+ DLIList<RefFace*> &narrow_faces,
+ DLIList<RefFace*> &surfs_to_ignore)
+{
+ int ii, jj;
+ DLIList <RefFace*> ref_faces, temp_faces;
+ RefVolume *ref_vol;
+ RefFace *curr_face;
+
+ for ( ii = 0; ii < ref_vols.size(); ii++ )
+ {
+ DLIList<RefFace*> faces;
+ ref_vol = ref_vols.get_and_step();
+ ref_vol->ref_faces(faces);
+ for ( jj = faces.size(); jj > 0; jj-- )
+ {
+ curr_face = faces.get_and_step();
+ curr_face->marked(0);
+ temp_faces.append(curr_face);
+ }
+ }
+
+ //uniquely add the faces.
+ for ( jj = temp_faces.size(); jj > 0; jj-- )
+ {
+ curr_face = temp_faces.get_and_step();
+ if ( curr_face->marked()== 0 )
+ {
+ curr_face->marked(1);
+ ref_faces.append(curr_face);
+ }
+ }
+
+ int num_faces = ref_faces.size();
+ ProgressTool *progress_ptr = NULL;
+ if (num_faces > 20)
+ {
+ progress_ptr = AppUtil::instance()->progress_tool();
+ assert(progress_ptr != NULL);
+ progress_ptr->start(0, 100, "Finding Narrow Surfaces",
+ NULL, CUBIT_TRUE, CUBIT_TRUE);
+ }
+
+ int total_faces = 0;
+ double curr_percent = 0.0;
+
+ for ( ii = ref_faces.size(); ii > 0; ii-- )
+ {
+ total_faces++;
+ if ( progress_ptr != NULL )
+ {
+ curr_percent = ((double)(total_faces))/((double)(num_faces));
+ progress_ptr->percent(curr_percent);
+ }
+
+ if ( CubitMessage::instance()->Interrupt() )
+ {
+ //interrpt. We need to exit.
+ if ( progress_ptr != NULL )
+ progress_ptr->end();
+ //just leave what has been calculated...
+ return;
+ }
+
+ curr_face = ref_faces.get_and_step();
+ if(!surfs_to_ignore.is_in_list(curr_face))
+ {
+ if(narrow_region_exists(curr_face, small_curve_size))
+ {
+ DLIList<CubitVector> split_pos1_list;
+ DLIList<CubitVector> split_pos2_list;
+ find_split_points_for_narrow_regions(curr_face,
+ small_curve_size, split_pos1_list, split_pos2_list);
+ if(split_pos1_list.size() == 0)
+ narrow_faces.append_unique(curr_face);
+ }
+ }
+ }
+
+ if ( progress_ptr != NULL )
+ progress_ptr->end();
+
+ return;
+}
+
void GeomMeasureTool::find_small_faces( DLIList <RefVolume*> &ref_vols,
double tol,
DLIList <RefFace*> &small_faces)
@@ -1891,32 +2800,72 @@
RefFace *curr_face;
for ( ii = 0; ii < ref_vols.size(); ii++ )
{
+ DLIList<RefFace*> faces;
ref_vol = ref_vols.get_and_step();
- ref_vol->ref_faces(temp_faces);
- //uniquely add the faces.
- for ( jj = temp_faces.size(); jj > 0; jj-- )
+ ref_vol->ref_faces(faces);
+ for ( jj = faces.size(); jj > 0; jj-- )
{
- curr_face = temp_faces.pop();
- if ( curr_face->marked()== 0 )
- {
- curr_face->marked(1);
- ref_faces.append(curr_face);
- }
+ curr_face = faces.get_and_step();
+ curr_face->marked(0);
+ temp_faces.append(curr_face);
}
}
+
+ //uniquely add the faces.
+ for ( jj = temp_faces.size(); jj > 0; jj-- )
+ {
+ curr_face = temp_faces.get_and_step();
+ if ( curr_face->marked()== 0 )
+ {
+ curr_face->marked(1);
+ ref_faces.append(curr_face);
+ }
+ }
+
+ int num_faces = ref_faces.size();
+ ProgressTool *progress_ptr = NULL;
+ if (num_faces > 20)
+ {
+ progress_ptr = AppUtil::instance()->progress_tool();
+ assert(progress_ptr != NULL);
+ progress_ptr->start(0, 100, "Finding Small Surfaces",
+ NULL, CUBIT_TRUE, CUBIT_TRUE);
+ }
+
+ int total_faces = 0;
+ double curr_percent = 0.0;
double area;
//find the small curves and reset the marked flag.
for ( ii = ref_faces.size(); ii > 0; ii-- )
{
+ total_faces++;
+ if ( progress_ptr != NULL )
+ {
+ curr_percent = ((double)(total_faces))/((double)(num_faces));
+ progress_ptr->percent(curr_percent);
+ }
+
+ if ( CubitMessage::instance()->Interrupt() )
+ {
+ //interrpt. We need to exit.
+ if ( progress_ptr != NULL )
+ progress_ptr->end();
+ //just leave what has been calculated...
+ return;
+ }
+
curr_face = ref_faces.get_and_step();
- //reset the mark.
- curr_face->marked(0);
area = measure_area(curr_face);
if ( area <= tol )
small_faces.append(curr_face);
}
+
+ if ( progress_ptr != NULL )
+ progress_ptr->end();
+
return;
}
+
void GeomMeasureTool::find_small_faces_hydraulic_radius( DLIList <RefVolume*> &ref_vols,
double tol,
DLIList <RefFace*> &small_faces,
@@ -1954,13 +2903,12 @@
DLIList <CoEdge*> co_edges;
int num_faces = ref_faces.size();
ProgressTool *progress_ptr = NULL;
- char title[32];
if (num_faces > 20)
{
- strcpy(title, "Small Surface Progress");
progress_ptr = AppUtil::instance()->progress_tool();
assert(progress_ptr != NULL);
- progress_ptr->start(0, 100, title, NULL, CUBIT_TRUE, CUBIT_TRUE);
+ progress_ptr->start(0, 100, "Small Surface Progress",
+ NULL, CUBIT_TRUE, CUBIT_TRUE);
}
double curr_percent = 0.0;
for ( ii = ref_faces.size(); ii > 0; ii-- )
@@ -2003,7 +2951,7 @@
//compute the hydraulic radius 4*(A/P).
if ( length <= CUBIT_RESABS )
{
- PRINT_INFO("Total Perimiter Length of Surface %d is less than tolerance.\n",
+ PRINT_INFO("Total Perimeter Length of Surface %d is less than tolerance.\n",
curr_face->id());
continue;
@@ -2629,14 +3577,14 @@
RefEdge *closest_edge_1, *closest_edge_2;
CubitVector curr_loc;
double closest_dist;
- double min_for_loop;
+ double min_for_loop_squared;
atree_list.reset();
for ( ii = 0; ii < atree_list.size(); ii++ )
{
curr_points = boundary_point_loops.get_and_step();
for ( jj = ii+1; jj < atree_list.size(); jj++ )
{
- min_for_loop = CUBIT_DBL_MAX;
+ min_for_loop_squared = CUBIT_DBL_MAX;
closest_edge_1 = NULL;
closest_edge_2 = NULL;
curr_tree = atree_list.next(jj);
@@ -2655,7 +3603,7 @@
//hmm, not sure what is wrong here.
PRINT_ERROR("Can't find closest point between loops.\n");
}
- if (closest_dist <= tol*tol && closest_dist < min_for_loop*min_for_loop )
+ if (closest_dist <= tol*tol && closest_dist < min_for_loop_squared )
{
//just store the smaller ones. Don't store
RefEntity *ref_ent = curr_point->owner();
@@ -2698,7 +3646,7 @@
continue;
}
- min_for_loop = sqrt(closest_dist);
+ min_for_loop_squared = closest_dist;
closest_edge_1 = ref_edge_1;
closest_edge_2 = ref_edge_2;
}
@@ -2707,7 +3655,7 @@
{
close_edges.append(closest_edge_1);
close_edges.append(closest_edge_2);
- small_lengths.append(min_for_loop);
+ small_lengths.append(sqrt(min_for_loop_squared));
}
}
}
@@ -2875,35 +3823,60 @@
///
/// Find fillets and rounds.
///
+#define FACE_BLEND 1
+#define VERTEX_BLEND 2
+#define BLEND_PROCESSED 3
+
void GeomMeasureTool::find_blends( RefVolume *ref_volume,
DLIList <RefFace*> &blend_faces,
DLIList <DLIList<RefFace*>*> &blend_groups )
{
//Assume for now that blends have cartesian angles between
//all the attached faces and itself.
- //Also a blend cannot be plannar. And directly accross from
+ //Also a blend cannot be planar. And directly accross from
//one blend edge, there is usually another blended edge but
//the angle between the two normals must be orthogonal. In other
//words their must be some sort of transition.
+ //mark all the faces as 0. The mark is used here to find the
+ // blend groups. The function is_vertex_blend() marks faces
+ // as being a vertex blend. The group of faces is then traversed
+ // until the adjacent surface (across the cross curve) is either
+ // a vertex blend or not a blend.
+ DLIList <RefFace*> ref_faces;
+ DLIList <RefFace*> vertex_blends, face_blends;
+ ref_volume->ref_faces(ref_faces);
+ int ii, jj;
+ for ( ii =0; ii < ref_faces.size(); ii++ )
+ ref_faces.get_and_step()->marked(0);
+
//First go through each face and each edge on each face.
- int ii, jj;
- DLIList <RefFace*> ref_faces;
DLIList <RefEdge*> ref_edges;
RefFace *ref_face;
RefEdge *ref_edge, *other_edge;
- ref_volume->ref_faces(ref_faces);
+ int num_vertex_blends = 0;
+ int num_face_blends = 0;
for ( ii = ref_faces.size(); ii > 0; ii-- )
{
ref_face = ref_faces.get_and_step();
- //Test the face to see if it is a blend.
+ //Test the face to see if it is a face or vertex blend.
other_edge = NULL;
ref_edge = NULL;
if ( is_face_blend(ref_face, ref_volume,
ref_edge, other_edge ) )
- blend_faces.append(ref_face);
+ {
+ face_blends.append(ref_face);
+ ref_face->marked(1);
+ num_face_blends++;
+ }
+ else if ( is_vertex_blend(ref_face, ref_volume) )
+ {
+ vertex_blends.append(ref_face);
+ ref_face->marked(2);
+ num_vertex_blends++; // keep track of the number of vertex blends
+ }
}
- if ( blend_faces.size() == 0 )
+ if ( face_blends.size() + vertex_blends.size() == 0 )
{
return;
}
@@ -2911,42 +3884,79 @@
//are that share curves.
DLIList <RefFace*> *blend_group;
DLIList <RefFace*> stack;
- RefFace *other_face;
- //mark all the faces as 0.
- for ( ii =0; ii < ref_faces.size(); ii++ )
- ref_faces.get_and_step()->marked(0);
- //mark just the blends as 1.
- for ( ii =0; ii < blend_faces.size(); ii++ )
- blend_faces.get_and_step()->marked(1);
+ RefFace *start_face = NULL, *other_face;
- for ( ii =0; ii < blend_faces.size(); ii++ )
+ // continue while there are blends to process
+ while ( vertex_blends.size() + face_blends.size() > 0 ||
+ start_face != NULL)
{
- ref_face = blend_faces.get_and_step();
- if ( ref_face->marked() == 2 )
- continue;
- blend_group = new DLIList <RefFace*>;
- blend_groups.append(blend_group);
- stack.clean_out();
- stack.append(ref_face);
- while ( stack.size() > 0 )
+ // if we don't have a start_face, get a new one.
+ if (!start_face)
{
- ref_face = stack.pop();
- ref_face->marked(2);
- blend_group->append(ref_face);
- ref_edges.clean_out();
- ref_face->ref_edges(ref_edges);
- for ( jj = 0; jj < ref_edges.size(); jj++ )
+ // this is the start of a new group
+ blend_group = new DLIList <RefFace*>;
+ blend_groups.append(blend_group);
+
+ // always prefer to start at a vertex blend if one exists
+ if (vertex_blends.size() > 0 )
{
- ref_edge = ref_edges.get_and_step();
- other_face = ref_edge->other_face(ref_face, ref_volume);
- if ( other_face == NULL )
- //shouldn't happend.
- continue;
- if ( other_face->marked() == 1 )
- stack.append(other_face);
+ start_face = vertex_blends.pop();
}
+ else
+ {
+ start_face = face_blends.pop();
+ }
}
+
+ blend_group->append(start_face); // add ref_face to group
+ blend_faces.append(start_face); // add the ref_face to the returned list
+ start_face->marked(BLEND_PROCESSED);
+
+ ref_edges.clean_out();
+ start_face->ref_edges(ref_edges);
+ for ( jj = 0; jj < ref_edges.size(); jj++ )
+ {
+ ref_edge = ref_edges.get_and_step();
+ other_face = ref_edge->other_face(start_face, ref_volume);
+ if (other_face == NULL)
+ {
+ start_face = NULL;
+ break;
+ }
+
+ // if this blend has been processed and isn't in the current group
+ if (other_face->marked() == BLEND_PROCESSED &&
+ !blend_group->is_in_list(other_face) )
+ {
+ start_face = NULL;
+ break; // reached an end of this loop
+ }
+ else if (other_face->marked() == VERTEX_BLEND)
+ {
+ blend_group->append(other_face); // add the ref_face to the group
+ blend_faces.append(other_face); // add the ref_face to the returned list
+ vertex_blends.remove(other_face);
+ other_face->marked(BLEND_PROCESSED);
+ start_face = NULL;
+ break; // a vertex blend is also end of the line
+ }
+ else if (other_face->marked() == FACE_BLEND)
+ {
+ start_face = other_face;
+ face_blends.remove(other_face);
+ break; // continue using this face as the new start face
+ }
+ }
+ // if we traversed through all the edges of this blend without
+ // finding another blend attached, this is the end of the chain
+ // and we need to find another starting place.
+ if ( jj >= ref_edges.size() )
+ {
+ start_face = NULL;
+ }
+
}
+
//cleanup marks.
for ( ii =0; ii < ref_faces.size(); ii++ )
ref_faces.get_and_step()->marked(0);
@@ -2957,6 +3967,198 @@
//REMEMBER TO DELETE the dllists in blend_faces.
return;
}
+
+// struct type object private to the next function
+class NextBlend
+{
+ public:
+ RefEdge* ref_edge;
+ RefFace* ref_face;
+};
+
+void GeomMeasureTool::find_blends_from_edge( RefVolume* ref_volume,
+ RefFace *start_face,
+ RefEdge* start_edge,
+ std::vector <RefFace*> &blend_faces)
+{
+ // initialize the mark on all surfaces in the volume
+ DLIList <RefFace*> ref_faces;
+ RefEdge *next_edge, *other_edge;
+ ref_volume->ref_faces(ref_faces);
+ int ii;
+ for ( ii =0; ii < ref_faces.size(); ii++ )
+ ref_faces.get_and_step()->marked(0);
+
+ std::stack<NextBlend> blend_stack;
+
+ NextBlend blend;
+ blend.ref_edge = start_edge;
+ blend.ref_face = start_face;
+ blend_faces.push_back(start_face);
+
+ blend_stack.push(blend);
+
+ while (blend_stack.size() > 0)
+ {
+ // this is an oddity with std::stack. Get the top of the stack
+ // and then you have to remove it from the stack with pop
+ NextBlend next_blend = blend_stack.top();
+ blend_stack.pop();
+ RefEdge* ref_edge = next_blend.ref_edge;
+ RefFace* ref_face = next_blend.ref_face;
+
+ RefFace* next_face;
+ next_face = ref_edge->other_face(ref_face, ref_volume);
+
+ // the the next face exists and it's a face blend, save the current blend,
+ // create a new blend object and add it to the stack
+ if ( next_face && is_face_blend(next_face, ref_volume, next_edge, other_edge ) )
+ {
+ // if the next face is already processed, the chain loops back on itself.
+ if (next_face->marked() == BLEND_PROCESSED)
+ {
+ for ( ii =0; ii < ref_faces.size(); ii++ )
+ ref_faces.get_and_step()->marked(0);
+ return;
+ }
+
+ blend_faces.push_back(next_face);
+ next_face->marked(BLEND_PROCESSED);
+
+ // the is_face_blend function assumes (poorly) rectangular surfaces
+ // without any holes. It returns the spring curves and we want
+ // the cross curves. So get all four edges and remove the two
+ // spring curves returned by is_face_blend
+ DLIList <RefEdge*> ref_edges;
+ next_face->ref_edges(ref_edges);
+ ref_edges.remove(next_edge);
+ ref_edges.remove(other_edge);
+
+ if (ref_edges.get() != ref_edge)
+ {
+ next_blend.ref_edge = ref_edges.get();
+ }
+ else
+ {
+ next_blend.ref_edge = ref_edges.next(1);
+ }
+ next_blend.ref_face = next_face;
+ blend_stack.push(next_blend);
+ }
+ else if ( next_face && is_vertex_blend(next_face, ref_volume) )
+ {
+ // we will stop the chain at a vertex blend
+ blend_faces.push_back(next_face);
+ next_face->marked(BLEND_PROCESSED);
+ }
+ }
+
+ // clean up the marks
+ std::vector<RefFace*>::iterator iter;
+ for ( iter = blend_faces.begin(); iter != blend_faces.end(); iter++)
+ (*iter)->marked(0);
+}
+
+// given a starting blend surface find a chain of blends from
+// that surface.
+//
+// Note that this function intentionally does _not_
+// clear the blend_face list so that additional chains can be added.
+CubitStatus GeomMeasureTool::find_blend_chains( RefFace *start_face,
+ std::vector<std::vector< RefFace*> > &blend_chains)
+{
+
+ if (start_face == NULL)
+ {
+ return CUBIT_FAILURE;
+ }
+
+ std::vector <RefFace*> blend_faces;
+
+ // get the owning volume of this blend
+ DLIList<RefEntity*> entity_list;
+ RefVolume* ref_volume;
+ int ii;
+
+ start_face->get_parent_ref_entities(entity_list);
+
+ // this indicates merged enitites and potential problems
+ if (entity_list.size() > 1)
+ {
+ return CUBIT_FAILURE;
+ }
+
+ // make sure we're at the beginning of the list and get the first
+ // and only item on the list and cast it to a RefVolume
+ entity_list.reset();
+ ref_volume = CAST_TO(entity_list.get(), RefVolume);
+
+ if (!ref_volume)
+ {
+ return CUBIT_FAILURE;
+ }
+
+ // initialize the mark on all surfaces in the volume
+ DLIList <RefFace*> ref_faces;
+ ref_volume->ref_faces(ref_faces);
+
+ RefEdge *spring_curve1, *spring_curve2;
+ if ( is_face_blend(start_face, ref_volume, spring_curve1, spring_curve2 ) )
+ {
+ // the is_face_blend function assumes (poorly) rectangular surfaces
+ // without any holes. It returns the spring curves and we want
+ // the cross curves. So get all four edges and remove the two
+ // spring curves returned by is_face_blend
+ DLIList <RefEdge*> ref_edges;
+ start_face->ref_edges(ref_edges);
+ ref_edges.remove(spring_curve1);
+ ref_edges.remove(spring_curve2);
+
+ // there is a special case where the blend is a periodic surface
+ // meaning that there _are_ no cross curves
+ if ( ref_edges.size() == 0 )
+ {
+ blend_faces.push_back(start_face);
+ }
+ else
+ {
+ // now find additional blends extending from either side of the blend
+ blend_faces.clear();
+ find_blends_from_edge( ref_volume, start_face, ref_edges.get(), blend_faces);
+ find_blends_from_edge( ref_volume, start_face, ref_edges.next(1), blend_faces);
+
+ // make sure that we have a unique list (the start surface is probably here twice)
+ std::vector<RefFace*>::iterator new_end;
+ std::sort( blend_faces.begin(), blend_faces.end() );
+ new_end = std::unique( blend_faces.begin(), blend_faces.end() );
+ blend_faces.erase(new_end, blend_faces.end());
+ }
+
+ blend_chains.push_back(blend_faces);
+ }
+ else if ( is_vertex_blend(start_face, ref_volume) )
+ {
+ DLIList<RefEdge*> ref_edges;
+ start_face->ref_edges(ref_edges);
+
+ for (ii = 0; ii < ref_edges.size(); ii++)
+ {
+ RefEdge* start_edge = ref_edges.get_and_step();
+ blend_faces.clear();
+ find_blends_from_edge( ref_volume, start_face, start_edge, blend_faces);
+
+ blend_chains.push_back(blend_faces);
+ }
+ }
+ else
+ {
+ // the given face is not a blend
+ return CUBIT_FAILURE;
+ }
+
+ return CUBIT_SUCCESS;
+}
+
//--------------------------------------------------------------------
//Function: Public, is_face_blend
//Description: Determines if a face is a blend surface, returns the
@@ -3085,6 +4287,93 @@
return CUBIT_FALSE;
}
+//--------------------------------------------------------------------
+//Function: Public, is_vertex_blend
+//Description: Determines if a face is a vertex blend surface.
+// For this type of blend, all ref_edges must be meet tangentially
+// with another surface. This assumes blend surface with no holes.
+//---------------------------------------------------------------------
+CubitBoolean GeomMeasureTool::is_vertex_blend(RefFace *ref_face,
+ RefVolume* ref_volume)
+{
+ //first we know that blend surfaces are not planar.
+ //so remove these first.
+ //Also, don't look at faces with more than 2 loops.
+ if ( ref_face->geometry_type() == PLANE_SURFACE_TYPE ||
+ ref_face->num_loops() > 2 )
+ return CUBIT_FALSE;
+
+ CubitBoolean is_cartesian;
+ DLIList<RefEdge*> ref_edges;
+ RefFace *other_face;
+ RefEdge *ref_edge = NULL;
+ int jj;
+ double angle;
+ ref_face->ref_edges(ref_edges);
+ for ( jj = ref_edges.size(); jj > 0; jj-- )
+ {
+ ref_edge = ref_edges.get_and_step();
+
+ //Weed-out case where one edge is shared between more
+ //than 2 surfaces of the same volume
+ DLIList<RefFace*> tmp_faces;
+ ref_edge->ref_faces( tmp_faces );
+
+ if( tmp_faces.size() > 2 )
+ {
+ int kk;
+ for(kk=tmp_faces.size(); kk--;)
+ {
+ if( !tmp_faces.get()->is_child( ref_volume ) )
+ tmp_faces.change_to(NULL);
+ tmp_faces.step();
+ }
+ tmp_faces.remove_all_with_value( NULL );
+ if( tmp_faces.size() > 2 )
+ //this isn't the type of surface we are looking for...
+ continue;
+ }
+
+ other_face = ref_edge->other_face(ref_face, ref_volume);
+ if ( other_face == NULL )
+ {
+ //this isn't the type of surface we are looking for...
+ break;
+ }
+ angle = GeometryQueryTool::instance()->surface_angle(ref_face,
+ other_face,
+ ref_edge,
+ ref_volume);
+ angle *= 180.0/CUBIT_PI;
+ is_cartesian = CUBIT_TRUE;
+ if ( angle <= GEOM_SIDE_LOWER ||
+ angle >= GEOM_SIDE_UPPER )
+ is_cartesian = CUBIT_FALSE;
+ //Okay, we have one major criteria achieved, this edge is a cartesian meet.
+
+ if ( !is_cartesian )
+ return CUBIT_FALSE;
+ //Now we need to check the radius of curvatures between these
+ //two surfaces. I'm not totally sure about this but I think we
+ // want the same radius of curvature.
+ double k1_s1, k2_s1, k1_s2, k2_s2;
+ CubitVector mid_point;
+ ref_edge->mid_point(mid_point);
+ ref_face->get_principal_curvatures( mid_point, k1_s1, k2_s1, ref_volume);
+ other_face->get_principal_curvatures( mid_point, k1_s2, k2_s2, ref_volume);
+ if (( is_equal(k1_s1, k1_s2) || is_equal(k1_s1, k2_s2) ) &&
+ ( is_equal(k2_s1, k1_s2) || is_equal(k2_s1, k2_s2) ) )
+ //try a different edge.
+ continue;
+ else
+ return CUBIT_FALSE;
+ }
+
+ // if all edges are tangent and share curvatures then it must be a
+ // vertex blend.
+ return CUBIT_TRUE;
+}
+
CubitBoolean GeomMeasureTool::find_opposite_edge( RefEdge* ref_edge,
RefFace* ref_face,
RefEdge *&other_edge,
@@ -3250,26 +4539,22 @@
}
CubitStatus GeomMeasureTool::get_centroid( RefFace *ref_face, CubitVector ¢roid, double &tot_area )
{
- int i;
- int num_tris, num_pnts, num_facets;
GMem g_mem;
unsigned short norm_tol = 5;
double dist_tol = -1.0;
ref_face->get_geometry_query_engine()->
- get_graphics(ref_face->get_surface_ptr(),num_tris, num_pnts, num_facets,
- &g_mem, norm_tol, dist_tol );
+ get_graphics(ref_face->get_surface_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;
ref_face->get_geometry_query_engine()->
- get_graphics(ref_face->get_surface_ptr(),num_tris, num_pnts, num_facets,
- &g_mem, norm_tol, dist_tol );
+ get_graphics(ref_face->get_surface_ptr(), &g_mem, norm_tol, dist_tol );
}
- if(num_tris < 1)
+ if(g_mem.fListCount < 1)
{
// Lets give up
PRINT_ERROR( "Unable to find the center of a surface\n" );
@@ -3286,7 +4571,7 @@
GPoint* plist = g_mem.point_list();
int* facet_list = g_mem.facet_list();
int c = 0;
- for( i=0; i<num_tris; i++ )
+ for( ; c < g_mem.fListCount; )
{
p[0] = plist[facet_list[++c]];
p[2] = plist[facet_list[++c]];
@@ -3314,6 +4599,9 @@
tot_area += tri_area;
}
+ if( tot_area == 0 )
+ return CUBIT_FAILURE;
+
centroid /= tot_area;
return CUBIT_SUCCESS;
}
@@ -3348,3 +4636,626 @@
id, centroid.x(), centroid.y(), centroid.z());
return CUBIT_SUCCESS;
}
+
+CubitStatus GeomMeasureTool::find_near_coincident_vertices(
+ DLIList<RefVolume*> &ref_volumes,
+ DLIList<RefVertex*> &ref_vertices_out,
+ DLIList<double> &distances,
+ double low_tol,
+ double high_tol,
+ bool filter_same_volume_cases)
+{
+ DLIList<RefVertex*> tmp_vert_list;
+ DLIList<RefVertex*> ref_verts;
+ int i,j;
+ for( i=ref_volumes.size(); i--; )
+ {
+ RefVolume *tmp_vol = ref_volumes.get_and_step();
+ tmp_vert_list.clean_out();
+ tmp_vol->ref_vertices( tmp_vert_list );
+ ref_verts += tmp_vert_list;
+ }
+
+ //put all the vertices in a tree
+ AbstractTree <RefVertex*> *a_tree = new RTree<RefVertex*>( high_tol );
+ for (i=ref_verts.size(); i--;)
+ a_tree->add(ref_verts.get_and_step());
+
+ std::multimap<double, dist_vert_struct> distance_vertex_map;
+
+ //for each vertex
+ for (i=ref_verts.size(); i--;)
+ {
+ RefVertex *tmp_vert = ref_verts.get_and_step();
+ RefVolume *v1 = tmp_vert->ref_volume();
+ CubitVector vert_xyz = tmp_vert->coordinates();
+
+ //get all close vertices
+ DLIList<RefVertex*> close_verts;
+ a_tree->find(tmp_vert->bounding_box(), close_verts);
+
+ //if any vertex is between low_tol and high_tol
+ //add it to the list
+ DLIList<RefVertex*> near_coincident_verts;
+ for( j=close_verts.size(); j--; )
+ {
+ RefVertex *close_vert = close_verts.get_and_step();
+ if( close_vert == tmp_vert )
+ continue;
+
+ RefVolume *v2 = close_vert->ref_volume();
+ bool check_distance = true;
+ if(filter_same_volume_cases && v1 && v2 && v1 == v2)
+ check_distance = false;
+ if(check_distance)
+ {
+ double distance = vert_xyz.distance_between( close_vert->coordinates() );
+ if( distance >= low_tol && distance <= high_tol )
+ {
+ dist_vert_struct tmp_struct;
+ tmp_struct.dist = distance;
+ tmp_struct.v1 = tmp_vert;
+ tmp_struct.v2 = close_vert;
+ distance_vertex_map.insert( std::multimap<double, dist_vert_struct>::
+ value_type( distance, tmp_struct ));
+ }
+ }
+ }
+
+ a_tree->remove( tmp_vert );
+ }
+
+ std::multimap<double, dist_vert_struct>::reverse_iterator iter;
+
+ iter = distance_vertex_map.rbegin();
+ for(; iter!=distance_vertex_map.rend(); iter++ )
+ {
+ distances.append( (*iter).second.dist );
+ ref_vertices_out.append( (*iter).second.v1 );
+ ref_vertices_out.append( (*iter).second.v2 );
+ }
+
+ delete a_tree;
+
+ return CUBIT_SUCCESS;
+}
+
+// This function is similar to find_near_coincident_vertices except for the
+// fact that it will only find the closest vertex in a given volume for
+// a vertex in another volume to be close to. This tries to exclude the case where
+// you would attempt to merge one vertex from one volume to two different
+// vertices in another volume.
+CubitStatus GeomMeasureTool::find_near_coincident_vertices_unique(
+ DLIList<RefVolume*> &ref_volumes,
+ double high_tol,
+ std::map <RefVertex*, DLIList<dist_vert_struct*>*> &vert_dist_map)
+{
+ DLIList<RefVertex*> tmp_vert_list;
+ DLIList<RefVertex*> ref_verts;
+ int i,j;
+ for( i=ref_volumes.size(); i--; )
+ {
+ RefVolume *tmp_vol = ref_volumes.get_and_step();
+ tmp_vert_list.clean_out();
+ tmp_vol->ref_vertices( tmp_vert_list );
+ ref_verts += tmp_vert_list;
+ }
+
+ //put all the vertices in a tree
+ AbstractTree <RefVertex*> *a_tree = new RTree<RefVertex*>( high_tol );
+ for (i=ref_verts.size(); i--;)
+ a_tree->add(ref_verts.get_and_step());
+
+ //for each vertex
+ for (i=ref_verts.size(); i--;)
+ {
+ RefVertex *tmp_vert = ref_verts.get_and_step();
+ RefVolume *vol1 = tmp_vert->ref_volume();
+ CubitVector vert_xyz = tmp_vert->coordinates();
+
+ //get all close vertices
+ DLIList<RefVertex*> close_verts;
+ a_tree->find(tmp_vert->bounding_box(), close_verts);
+
+ //if any vertex is between low_tol and high_tol
+ //add it to the list
+ DLIList<dist_vert_struct*> *near_coincident_verts = NULL;
+ for( j=close_verts.size(); j--; )
+ {
+ RefVertex *close_vert = close_verts.get_and_step();
+ if( close_vert == tmp_vert )
+ continue;
+
+ RefVolume *vol2 = close_vert->ref_volume();
+ if(vol1 && vol2 && vol1 != vol2)
+ {
+ if(!near_coincident_verts)
+ {
+ near_coincident_verts = new DLIList<dist_vert_struct*>;
+ vert_dist_map[tmp_vert] = near_coincident_verts;
+ }
+ double distance = vert_xyz.distance_between( close_vert->coordinates() );
+ int h;
+ bool found_entry_with_same_vol = false;
+ for(h=near_coincident_verts->size(); h>0 && !found_entry_with_same_vol; h--)
+ {
+ dist_vert_struct* vds = near_coincident_verts->get_and_step();
+ if(vds->vol2 == vol2)
+ {
+ found_entry_with_same_vol = true;
+ if(distance < vds->dist)
+ {
+ vds->dist = distance;
+ vds->vol2 = vol2;
+ vds->v2 = close_vert;
+ }
+ }
+ }
+ if(!found_entry_with_same_vol)
+ {
+ dist_vert_struct *new_vds = new dist_vert_struct;
+ new_vds->dist = distance;
+ new_vds->v2 = close_vert;
+ new_vds->vol2 = vol2;
+ near_coincident_verts->append(new_vds);
+ }
+ }
+ }
+ a_tree->remove( tmp_vert );
+ }
+
+ delete a_tree;
+
+ return CUBIT_SUCCESS;
+}
+
+struct dist_vert_vert_struct
+{
+ double dist;
+ RefVertex *vert1;
+ RefVertex *vert2;
+};
+
+struct dist_vert_curve_struct
+{
+ double dist;
+ RefVertex *vert;
+ RefEdge *edge;
+// bool operator<( const dist_vert_curve_struct& b ) const
+// {
+// return this->dist < b.dist;
+ // }
+};
+
+struct vert_curve_dist_sort
+{
+ bool operator()( const dist_vert_curve_struct& a, const dist_vert_curve_struct& b ) const
+ {
+ return a.dist < b.dist;
+ }
+};
+
+struct vert_curve_dist_sort_ptr
+{
+ bool operator()( dist_vert_curve_struct *a, dist_vert_curve_struct *b ) const
+ {
+ if( a->dist < b->dist )
+ return true;
+ else if( a->dist > b->dist )
+ return false;
+ else
+ return true;
+ }
+};
+
+struct vert_vert_dist_sort_ptr
+{
+ bool operator()( dist_vert_vert_struct *a, dist_vert_vert_struct *b ) const
+ {
+ if( a->dist < b->dist )
+ return true;
+ else if( a->dist > b->dist )
+ return false;
+ else
+ return true;
+ }
+};
+
+CubitStatus GeomMeasureTool::find_closest_vertex_curve_pairs(
+ DLIList<RefVolume*> &vol_list,
+ int &num_to_return,
+ DLIList<RefVertex*> &vert_list,
+ DLIList<RefEdge*> &curve_list,
+ DLIList<double> &distances)
+{
+ DLIList<RefFace*> surfs;
+
+ int i, total_num_entries = 0;
+ for( i=vol_list.size(); i--; )
+ {
+ RefVolume *tmp_vol = vol_list.get_and_step();
+ tmp_vol->ref_faces( surfs );
+ }
+
+ std::set<dist_vert_curve_struct*,vert_curve_dist_sort_ptr> distance_vertex_curve_set;
+
+ for(i=surfs.size(); i>0; i--)
+ {
+ RefFace *surf = surfs.get_and_step();
+ DLIList<RefVertex*> surf_verts;
+ surf->ref_vertices(surf_verts);
+ DLIList<RefEdge*> surf_curves;
+ surf->ref_edges(surf_curves);
+
+ int j;
+ for(j=surf_verts.size(); j>0; j--)
+ {
+ RefVertex *tmp_vert = surf_verts.get_and_step();
+ CubitVector vert_xyz = tmp_vert->coordinates();
+ CubitVector closest_pt;
+ int k;
+ for(k=surf_curves.size(); k>0; k--)
+ {
+ RefEdge *cur_edge = surf_curves.get_and_step();
+ if(cur_edge->start_vertex() != tmp_vert &&
+ cur_edge->end_vertex() != tmp_vert)
+ {
+ cur_edge->closest_point_trimmed(vert_xyz, closest_pt);
+ if(!closest_pt.about_equal(cur_edge->start_coordinates()) &&
+ !closest_pt.about_equal(cur_edge->end_coordinates()))
+ {
+ double dist_sq = vert_xyz.distance_between_squared(closest_pt);
+ dist_vert_curve_struct *tmp_struct = new dist_vert_curve_struct;
+ tmp_struct->dist = dist_sq;
+ tmp_struct->vert = tmp_vert;
+ tmp_struct->edge = cur_edge;
+ distance_vertex_curve_set.insert( tmp_struct );
+ total_num_entries++;
+ }
+ }
+ }
+ }
+ }
+
+ std::set<dist_vert_curve_struct*, vert_curve_dist_sort_ptr>::iterator iter, upper_iter;
+
+ int local_num_to_return = num_to_return;
+ if(num_to_return == -1)
+ {
+ local_num_to_return = total_num_entries;
+ }
+ int cntr = 0;
+ iter = distance_vertex_curve_set.begin();
+ for(; iter!=distance_vertex_curve_set.end() && cntr < local_num_to_return; iter++ )
+ {
+ distances.append( sqrt((*iter)->dist) );
+ vert_list.append( (*iter)->vert );
+ curve_list.append( (*iter)->edge );
+ cntr++;
+ }
+
+ iter = distance_vertex_curve_set.begin();
+ for(; iter!=distance_vertex_curve_set.end(); iter++ )
+ {
+ delete *iter;
+ }
+
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus GeomMeasureTool::find_closest_vertex_vertex_pairs(
+ DLIList<RefVolume*> &vol_list,
+ int &num_to_return,
+ DLIList<RefVertex*> &vert_list1,
+ DLIList<RefVertex*> &vert_list2,
+ DLIList<double> &distances)
+{
+ std::set<dist_vert_vert_struct*,vert_vert_dist_sort_ptr> distance_vertex_vertex_set;
+
+ int i, total_num_entries = 0;
+ for( i=vol_list.size(); i--; )
+ {
+ RefVolume *tmp_vol = vol_list.get_and_step();
+ DLIList<RefVertex*> vol_verts;
+ tmp_vol->ref_vertices(vol_verts);
+ while(vol_verts.size() > 1)
+ {
+ RefVertex *vert1 = vol_verts.pop();
+ CubitVector vert1_xyz = vert1->coordinates();
+ int j;
+ for(j=vol_verts.size(); j>0; j--)
+ {
+ RefVertex *vert2 = vol_verts.get_and_step();
+ double dist_sq = vert2->coordinates().distance_between_squared(vert1_xyz);
+ dist_vert_vert_struct *tmp_struct = new dist_vert_vert_struct;
+ tmp_struct->dist = dist_sq;
+ tmp_struct->vert1 = vert1;
+ tmp_struct->vert2 = vert2;
+ distance_vertex_vertex_set.insert( tmp_struct );
+ total_num_entries++;
+ }
+ }
+ }
+
+ std::set<dist_vert_vert_struct*, vert_vert_dist_sort_ptr>::iterator iter, upper_iter;
+
+ int local_num_to_return = num_to_return;
+ if(num_to_return == -1)
+ local_num_to_return = total_num_entries;
+ int cntr = 0;
+ iter = distance_vertex_vertex_set.begin();
+ for(; iter!=distance_vertex_vertex_set.end() && cntr < local_num_to_return; iter++ )
+ {
+ distances.append( sqrt((*iter)->dist) );
+ vert_list1.append( (*iter)->vert1 );
+ vert_list2.append( (*iter)->vert2 );
+ cntr++;
+ }
+
+ iter = distance_vertex_vertex_set.begin();
+ for(; iter!=distance_vertex_vertex_set.end(); iter++ )
+ {
+ delete *iter;
+ }
+
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus GeomMeasureTool::find_near_coincident_vertex_curve_pairs(
+ DLIList<RefVolume*> &ref_vols,
+ DLIList<RefEdge*> &ref_edges,
+ DLIList<RefVertex*> &ref_verts,
+ DLIList<double> &distances,
+ double low_tol,
+ double high_tol,
+ bool filter_same_volume_cases)
+{
+ //get all the curves and vertices of volumes in list
+ DLIList<RefVertex*> verts;
+ DLIList<RefEdge*> curves;
+
+ RTree<RefEdge*> a_tree(high_tol);
+
+ int i,j;
+ for( i=ref_vols.size(); i--; )
+ {
+ RefVolume *tmp_vol = ref_vols.get_and_step();
+ tmp_vol->ref_vertices( verts );
+
+ curves.clean_out();
+ tmp_vol->ref_edges( curves );
+ for( j=curves.size(); j--; )
+ {
+ RefEdge *tmp_edge = curves.get_and_step();
+ a_tree.add( tmp_edge );
+ }
+ }
+
+ ProgressTool *progress_ptr = NULL;
+ int total_verts = verts.size();
+ if (total_verts > 5)
+ {
+ progress_ptr = AppUtil::instance()->progress_tool();
+ assert(progress_ptr != NULL);
+ progress_ptr->start(0, 100, "Finding Near Coincident Vertex-Curve Pairs",
+ NULL, CUBIT_TRUE, CUBIT_TRUE);
+ }
+
+ double curr_percent = 0.0;
+ int processed_verts = 0;
+ int times = 0;
+ std::multimap<double, dist_vert_curve_struct> distance_vertex_curve_map;
+
+ //for each vertex
+ for( i=verts.size(); i--; )
+ {
+ processed_verts++;
+ if ( progress_ptr != NULL )
+ {
+ curr_percent = ((double)(processed_verts))/((double)(total_verts));
+ progress_ptr->percent(curr_percent);
+ }
+
+ RefVertex *tmp_vert = verts.get_and_step();
+ RefVolume *v1 = tmp_vert->ref_volume();
+ CubitBox vertex_box ( tmp_vert->coordinates(), tmp_vert->coordinates() );
+ DLIList<RefEdge*> close_curves;
+ a_tree.find( vertex_box, close_curves );
+
+ CubitVector vertex_xyz = tmp_vert->coordinates();
+
+ for( j=close_curves.size(); j--; )
+ {
+ RefEdge *tmp_edge = close_curves.get_and_step();
+ RefVolume *v2 = tmp_edge->ref_volume();
+
+ bool check_distance = true;
+ if(filter_same_volume_cases && v1 && v2 && v1 == v2)
+ check_distance = false;
+ if(check_distance)
+ {
+ CubitVector closest_location;
+ tmp_edge->closest_point_trimmed( vertex_xyz, closest_location );
+ double distance = closest_location.distance_between( vertex_xyz );
+
+ if( distance >= low_tol && distance <= high_tol )
+ {
+ dist_vert_curve_struct tmp_struct;
+ tmp_struct.dist = distance;
+ tmp_struct.vert = tmp_vert;
+ tmp_struct.edge = tmp_edge;
+
+ distance_vertex_curve_map.insert( std::multimap<double, dist_vert_curve_struct>::
+ value_type( distance, tmp_struct ));
+ }
+ }
+ }
+ }
+
+ if ( progress_ptr != NULL )
+ progress_ptr->end();
+
+ //std::set<dist_vert_curve_struct, vert_curve_dist_sort>::iterator iter, upper_iter;
+ std::multimap<double, dist_vert_curve_struct>::reverse_iterator iter;
+
+ iter = distance_vertex_curve_map.rbegin();
+ for(; iter!=distance_vertex_curve_map.rend(); iter++ )
+ {
+ distances.append( (*iter).second.dist );
+ ref_verts.append( (*iter).second.vert );
+ ref_edges.append( (*iter).second.edge );
+ }
+
+ return CUBIT_SUCCESS;
+}
+
+
+struct dist_vert_surf_struct
+{
+ double dist;
+ RefVertex *vert;
+ RefFace *face;
+};
+
+struct vert_surf_dist_sort
+{
+ bool operator()( dist_vert_surf_struct a, dist_vert_surf_struct b ) const
+ {
+ if( a.dist < b.dist )
+ return true;
+ else if( a.dist > b.dist )
+ return false;
+ else
+ {
+ if( a.vert < b.vert )
+ return true;
+ else if( a.vert > b.vert )
+ return false;
+ else if( a.face < b.face )
+ return true;
+ else if( a.face > b.face )
+ return false;
+ }
+ return false;
+ }
+};
+
+
+CubitStatus GeomMeasureTool::find_near_coincident_vertex_surface_pairs(
+ DLIList<RefVolume*> &ref_vols,
+ DLIList<RefFace*> &ref_faces,
+ DLIList<RefVertex*> &ref_verts,
+ DLIList<double> &distances,
+ double low_tol,
+ double high_tol,
+ bool filter_same_volume_cases)
+{
+ //get all the curves and vertices of volumes in list
+ DLIList<RefVertex*> verts;
+ DLIList<RefFace*> faces;
+
+ AbstractTree<RefFace*> *a_tree = new RTree<RefFace*>( high_tol );
+
+ int i,j;
+ for( i=ref_vols.size(); i--; )
+ {
+ RefVolume *tmp_vol = ref_vols.get_and_step();
+ tmp_vol->ref_vertices( verts );
+
+ faces.clean_out();
+ tmp_vol->ref_faces( faces );
+ // Populate the Surface AbstractTree
+ for( j=faces.size(); j--; )
+ {
+ RefFace *tmp_face = faces.get_and_step();
+ a_tree->add( tmp_face );
+ }
+ }
+
+ ProgressTool *progress_ptr = NULL;
+ int total_verts = verts.size();
+ if (total_verts > 50)
+ {
+ progress_ptr = AppUtil::instance()->progress_tool();
+ assert(progress_ptr != NULL);
+ progress_ptr->start(0, 100, "Finding Near Coincident Vertex-Surface Pairs",
+ NULL, CUBIT_TRUE, CUBIT_TRUE);
+ }
+ double curr_percent = 0.0;
+ int processed_verts = 0;
+
+ std::multimap<double, dist_vert_surf_struct> distance_vertex_surface_map;
+
+ //for each vertex
+ for( i=verts.size(); i--; )
+ {
+ processed_verts++;
+ if ( progress_ptr != NULL )
+ {
+ curr_percent = ((double)(processed_verts))/((double)(total_verts));
+ progress_ptr->percent(curr_percent);
+ }
+
+ RefVertex *tmp_vert = verts.get_and_step();
+ RefVolume *v1 = tmp_vert->ref_volume();
+ CubitBox vertex_box ( tmp_vert->coordinates(), tmp_vert->coordinates() );
+ DLIList<RefFace*> close_faces;
+ a_tree->find( vertex_box, close_faces);
+
+ CubitVector vertex_xyz = tmp_vert->coordinates();
+
+ for( j=close_faces.size(); j--; )
+ {
+ RefFace *tmp_face = close_faces.get_and_step();
+ RefVolume *v2 = tmp_face->ref_volume();
+
+ bool check = true;
+ if(filter_same_volume_cases && v1 && v2 && v1 == v2)
+ check = false;
+
+ if(check)
+ {
+ DLIList<RefVertex*> tmp_verts;
+ tmp_face->ref_vertices( tmp_verts );
+ if( tmp_verts.is_in_list( tmp_vert ) )
+ continue;
+
+ CubitVector closest_location;
+ tmp_face->find_closest_point_trimmed( vertex_xyz, closest_location );
+ double distance = closest_location.distance_between( vertex_xyz );
+
+ if( distance > low_tol && distance < high_tol )
+ {
+ dist_vert_surf_struct tmp_struct;
+ tmp_struct.dist = distance;
+ tmp_struct.vert = tmp_vert;
+ tmp_struct.face = tmp_face;
+ distance_vertex_surface_map.insert( std::multimap<double, dist_vert_surf_struct>::
+ value_type( distance, tmp_struct ));
+ }
+ }
+ }
+ }
+
+ if ( progress_ptr != NULL )
+ progress_ptr->end();
+
+ std::multimap<double, dist_vert_surf_struct>::reverse_iterator iter;
+
+ iter = distance_vertex_surface_map.rbegin();
+ for(; iter!=distance_vertex_surface_map.rend(); iter++ )
+ {
+ distances.append( (*iter).second.dist );
+ ref_verts.append( (*iter).second.vert );
+ ref_faces.append( (*iter).second.face);
+ }
+
+ delete a_tree;
+
+ return CUBIT_SUCCESS;
+}
+
+
+
+
+
Modified: cgm/branches/cubit/geom/GeomMeasureTool.hpp
===================================================================
--- cgm/branches/cubit/geom/GeomMeasureTool.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/GeomMeasureTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -20,6 +20,8 @@
class GeomPoint;
class GeomSeg;
#include "CubitGeomConfigure.h"
+#include <vector>
+#include <map>
typedef DLIList <GeomPoint*> PointList;
typedef DLIList <PointList*> PointLoopList;
@@ -34,6 +36,14 @@
const double GEOM_CORNER_UPPER = 273.0;
const double GEOM_REVERSAL_LOWER = 355.0;
+struct dist_vert_struct
+{
+ double dist;
+ RefVertex *v1;
+ RefVertex *v2;
+ RefVolume *vol2;
+};
+
class AreaHashTuple
{
public:
@@ -45,6 +55,7 @@
double myArea;
};
+//! Calculates measurements and statistics for a given entity.
class CUBIT_GEOM_EXPORT GeomMeasureTool
{
private:
@@ -56,10 +67,10 @@
DLIList <RefVolume*> &ref_volumes );
static void get_bodies_from_list(DLIList <RefVolume*> &entity_list,
DLIList <Body*> &ref_bodies );
- ///
- ///converts the entity list, and expands the list to get the edges,
- ///faces or volumes of the entities.
- ///
+ ///
+ ///converts the entity list, and expands the list to get the edges,
+ ///faces or volumes of the entities.
+ ///
static double dist_sq_point_data( CubitVector &curr_point,
GeomSeg *&curr_seg );
@@ -112,6 +123,11 @@
/// Returns TRUE if they are, false if they aren't.
///
+ static RefFace* valid_start( DLIList <RefFace*> &all_faces );
+
+ static void face_list_from_volume_list( DLIList <RefVolume*> &input_vols,
+ DLIList <RefFace*> &all_faces );
+
public:
GeomMeasureTool()
{}
@@ -119,6 +135,17 @@
~GeomMeasureTool()
{}
+ //! Determines if a surface is narrow.
+ static bool is_surface_narrow(RefFace *face, double small_curve_size);
+
+ //! Determines points along which to make a curve for splitting a narrow surface.
+ static void find_split_points_for_narrow_regions(RefFace *face,
+ double size,
+ DLIList<CubitVector> &split_pos1_list,
+ DLIList<CubitVector> &split_pos2_list);
+
+ //! Find the smallest, longest and average size of the curves. Also
+ //! compute the sum of all the curve. Do that for a list of RefEntity pointers.
static void measure_curve_length(DLIList <RefEntity*> &entity_list,
double &smallest,
RefEdge *&smallest_edge,
@@ -126,11 +153,9 @@
RefEdge *&largest_edge,
double &average,
double &sum);
- ///
- ///Find the smallest, longest and average size of the curves. Also
- ///compute the sum of all the curve. Do that for a list of RefEntity pointers.
- ///
+ //! Find the smallest, longest and average size of the curves. Also
+ //! compute the sum of all the curve. Do that for a list of RefEdge pointers.
static void measure_curve_length(DLIList <RefEdge*> &ref_edges,
double &smallest,
RefEdge *&smallest_edge,
@@ -138,35 +163,74 @@
RefEdge *&largest_edge,
double &average,
double &sum);
- ///
- ///Find the smallest, longest and average size of the curves. Also
- ///compute the sum of all the curve. Do that for a list of RefEdge pointers.
- ///
-
+ //! Finds the curve with the smallest length on the surface.
+ //! Also find the biggest change in curve lengths where
+ //! the ratio is the largest curve divided by the smallest curve.
static void measure_face_curves( RefFace *ref_face,
double &min_curve_length,
double &max_curve_ratio,
RefEdge *&min_ref_edge);
- ///
- /// Finds the curve with the smallest length on the surface.
- /// Also find the biggest change in curve lengths where
- /// the ratio is the largest curve divided by the smallest curve.
- ///
+ //! Determines if a narrow region exists between the
+ //! passed-in edge and any other edge in the passed-in
+ //! face. 'tol' defines what is 'narrow'. A non-zero
+ //! int is returned if a narrow region exists.
+ static int narrow_region_exists(RefFace *face,
+ RefEdge *edge,
+ const double &tol);
+ //! Determines whether a narrow region exists between the two
+ //! passed-in edges on the passed-in face. 'tol' specifies what
+ //! 'narrow' is. The four lists that are returned contain points
+ //! at which the face can be split in order to separate off the
+ //! narrow region. The 'pos' lists contain split points on the
+ //! edges that are not on pre-existing vertices. If a split point
+ //! falls on a pre-existing vertex it will show up in the 'vert' list.
+ //! The points/vertices in the lists are ordered so that a point/vertex
+ //! in an 'e1' list will correspond with a point/vertex in an 'e2' list.
+ //! If a narrow region exists between the edges a non-zero value will
+ //! be returned.
+ static int narrow_region_exists(
+ RefEdge *e1,
+ RefEdge *e2,
+ RefFace *face,
+ const double &tol,
+ DLIList<CubitVector*> &e1_pos_list,
+ DLIList<CubitVector*> &e2_pos_list,
+ DLIList<RefVertex*> &e1_vert_list,
+ DLIList<RefVertex*> &e2_vert_list);
+ //! Determine if a narrow region exists on the given face. The passed-in
+ //! tolerance defines the narrow size. Returns a non-zero value
+ //! if a narrow region exists.
+ static int narrow_region_exists(RefFace *face,
+ const double &tol);
+ //! Checks to see if at the given position the two edges are close together and
+ //! have the same tangent. 'e1' is one of the edges. 'face' is the face that
+ //! the edges are on. 'pt_on_e1' is a position on 'e1'. 'pt_on_e1' will be
+ //! projected onto the other edge, 'e2', to look for closeness. 'tol_sq' is
+ //! the squared distance defining what is 'close'. The closest pt on 'e2' to
+ //! 'pt_on_e1' is returned. Returns a non-zero int if the two edges form a narrow region
+ //! at the given point.
+ static int is_narrow_region_at_point(RefEdge *e1,
+ RefFace *face,
+ const CubitVector &pt_on_e1,
+ RefEdge *e2,
+ const double &tol_sq,
+ CubitVector &closest);
+
+ //! Find the smallest distance between multiple loops on the surface.
+ //! Find the smallest distance between two curves. This could be the length
+ //! of the smallest curve...
+ //! Also calculate the angles between curves on the faces.
+ //! The tolerance is used to specify the faceting to approximate the boundaries.
static CubitStatus measure_face_loops(RefFace *face,
double &min_distance_between_loops,
double &min_distance_in_one_loop,
double &min_angle, double &max_angle,
double tolerance);
- ///
- ///Find the smallest distance between multiple loops on the surface.
- ///Find the smallest distance between two curves. This could be the length
- ///of the smallest curve...
- ///Also calculate the angles between curves on the faces.
- ///The tolerance is used to specify the faceting to approximate the boundaries.
- ///
+ //! Find the smallest, largest and average area of the faces contained
+ //! in the entity list.. Also compute the sum of all the face area.
static void measure_face_area (DLIList <RefEntity*> &entity_list,
double &smallest,
RefFace *&smallest_face,
@@ -174,11 +238,9 @@
RefFace *&largest_face,
double &average,
double &sum);
- ///
- ///Find the smallest, largest and average area of the faces contained
- ///in the entity list.. Also compute the sum of all the face area.
- ///
+ //! Find the smallest, largest and average area of the faces
+ //! in the face list.. Also compute the sum of all the face area.
static void measure_face_area (DLIList <RefFace*> &ref_faces,
double &smallest,
RefFace *&smallest_face,
@@ -186,11 +248,9 @@
RefFace *&largest_face,
double &average,
double &sum);
- ///
- ///Find the smallest, largest and average area of the faces
- ///in the face list.. Also compute the sum of all the face area.
- ///
+ //! Find the smallest, largest, and average volume. Compute the sum of all
+ //! the volumes for the volumes contained by the entities in the entity list.
static void measure_volume_volume (DLIList <RefEntity*> &entity_list,
double &smallest,
RefVolume *&smallest_volume,
@@ -198,11 +258,9 @@
RefVolume *&largest_volume,
double &average,
double &sum);
- ///
- ///Find the smallest, largest, and average volume. Compute the sum of all
- ///the volumes for the volumes contained by the entities in the entity list.
- ///
+ //! Find the smallest, largest, and average volume. Compute the sum of all
+ //! the volumes in the list.
static void measure_volume_volume (DLIList <RefVolume*> &ref_volumes,
double &smallest,
RefVolume *&smallest_volume,
@@ -210,10 +268,6 @@
RefVolume *&largest_volume,
double &average,
double &sum);
- ///
- ///Find the smallest, largest, and average volume. Compute the sum of all
- ///the volumes in the list.
- ///
#ifdef BOYD14
static void measure_face_hydraulic_radius( DLIList <RefEntity*> &entity_list,
@@ -274,69 +328,53 @@
double &average_curvature_change);
#endif
+ //! Given a list of volumes, return number of surface merged, unmerged,
+ //! and ratio between the two.
static void merged_unmerged_surface_ratio(DLIList <RefVolume*> &ref_volumes,
int &merged, int &unmerged,
double &ratio);
- static void report_intersected_bodies(DLIList <RefVolume*> &volume_list,
- DLIList <Body*> &intersection_list);
+ //! From a list of volumes, find ones that intersect.
+ static void report_intersected_volumes(DLIList <RefVolume*> &volume_list,
+ DLIList <RefVolume*> &intersection_list);
+ //! From a list of bodies, find ones that intersect.
static void report_intersected_bodies(DLIList <Body*> &ref_bodies,
DLIList <Body*> &intersection_list);
-
- static RefFace* valid_start( DLIList <RefFace*> &all_faces );
-
- static void face_list_from_volume_list( DLIList <RefVolume*> &input_vols,
- DLIList <RefFace*> &all_faces );
+ //! Finds lists of surfaces sharing common curves. Lists are found in the returned RefGroup.
static void find_shells( DLIList <RefVolume*> &input_vols,
RefGroup *&owner_groups,
int &number_of_shells);
-
- static void ratio_of_shells_to_volumes(int number_of_shells,
- DLIList <RefVolume*> &ref_volumes,
- int &number_of_volumes,
- double &ratio);
-
+ //! Gets the points in ordered loops that are used to facet the boundary
+ //! of the surface.
static CubitStatus get_boundary_points( RefFace *ref_face,
PointLoopList &boundary_point_loops,
double seg_length_tol);
- ///
- ///Gets the points in ordered loops that are used to facet the boundary
- ///of the surface.
- ///
+ //! Get the points that approximate the curve, use the graphics facets.
static CubitStatus get_curve_facets( RefEdge* curve,
PointList &segments,
double seg_length_tol );
- ///
- ///Get the points that approximate the curve, use the graphics facets.
- ///
+ //! Converts the loops of points to line segments. Can fail if it
+ //! can't determine the owner of the line segment. The refface may
+ //! be needed to help determine ownership.
static CubitStatus convert_to_lines(PointLoopList &boundary_point_loops,
SegLoopList &boundary_line_loops,
RefFace *ref_face );
- ///
- ///Converts the loops of points to line segments. Can fail if it
- ///can't determine the owner of the line segment. The refface may
- ///be needed to help determine ownership.
- ///
+ //! Prints a summary of all of the surface information.
+ //! min curve length, max adjacent curve ratios, min angle, max angle,
+ //! min area, max area, min hydraulic radius, min distance between loops,
+ //! min distance between a single loop.
static void print_surface_measure_summary( DLIList <RefFace*> &ref_faces );
- ///
- ///Prints a summary of all of the surface information.
- ///min curve length, max adjacent curve ratios, min angle, max angle,
- ///min area, max area, min hydraulic radius, min distance between loops,
- ///min distance between a single loop.
- ///
+ //! Prints summary of all the volume information, including the
+ //! information of the
+ //! surfaces in the volumes.
static void print_volume_measure_summary(DLIList <RefVolume*> &ref_volumes);
- ///
- /// Prints summary of all the volume information, including the
- /// information of the
- /// surfaces in the volumes.
- ///
#ifdef BOYD14
static void print_body_measure_summary(DLIList <Body*> &bodies);
@@ -346,64 +384,74 @@
///
#endif
+ //! Finds the max ratio of adjacent face areas (big face area
+ //! divided by small face area);
static void find_adjacent_face_ratios(RefVolume *curr_volume,
double &max_face_ratio,
RefFace *&big_face,
RefFace *&small_face);
- ///
- /// Finds the max ratio of adjacent face areas (big face area
- /// divided by small face area);
- ///
+
+ //! Finds narrow surfaces in the specified volumes.
+ static void find_narrow_faces(DLIList<RefVolume*> &ref_vols,
+ double small_curve_size,
+ DLIList<RefFace*> &narrow_faces,
+ DLIList<RefFace*> &surfs_to_ignore);
+ //! Finds the curves with lengths less than the given tol in specified volume.
+ static RefEdge* find_first_small_curve(RefVolume* vol,
+ double tol);
+
+ //! Finds the curves with lengths less than the given tol.
static void find_small_curves( DLIList <RefVolume*> &ref_vols,
double tol,
DLIList <RefEdge*> &small_curves,
DLIList <double> &small_lengths);
- ///
- /// Finds the curves with lengths less than the given tol.
- ///
+ //! Finds the curves with lengths less than the given tol.
+ static void find_surfs_with_narrow_regions( DLIList <RefVolume*> &ref_vols,
+ double tol,
+ DLIList <RefFace*> &surfs_with_narrow_regions);
+
+ //! Finds the faces with areas less than the given ammount.
static void find_small_faces( DLIList <RefVolume*> &ref_vols,
double tol,
DLIList <RefFace*> &small_faces);
- ///
- /// Finds the faces with areas less than the given ammount.
- ///
+ //! Finds the faces with hydraulic radii less than tol.
+ //! The hydraulic radus is defined by 4*(A/P) where
+ //! A is the area of the surface and P is the total perimiter
+ //! length around the surface.
+ //! Also finds the % surfaces that are planar. And finds
+ //! the % surfaces that are planar and conical.
+ //! This is based on the geometry type, not some actual measurement.
static void find_small_faces_hydraulic_radius( DLIList <RefVolume*> &ref_vols,
double tol,
DLIList <RefFace*> &small_faces,
DLIList <double> &small_hyd_rad,
double &percent_planar,
double &percent_pl_co);
- ///
- /// Finds the faces with hydraulic radii less than tol.
- /// The hydraulic radus is defined by 4*(A/P) where
- /// A is the area of the surface and P is the total perimiter
- /// length around the surface.
- /// Also finds the % surfaces that are planar. And finds
- /// the % surfaces that are planar and conical.
- /// This is based on the geometry type, not some actual measurement.
- ///
+ //! Finds the volumes with volumes less than tol.
static void find_small_volumes( DLIList <RefVolume*> &ref_vols,
double tol,
DLIList <RefVolume*> &small_volumes);
- ///
- /// Finds the volumes with volumes less than tol.
- ///
+ //! Measures the hydraulic radii for the volumes by 6*(V/A) where
+ //! V is the volume of the volume and A is the total area of all
+ //! the volume's surfaces. Volumes with small hydraulic radii (compared
+ //! to tol) are stored in the small_volumes list.
static void find_small_volumes_hydraulic_radius( DLIList <RefVolume*> &ref_vols,
double tol,
DLIList <RefVolume*> &small_volumes,
DLIList <double> &small_hyd_rad);
- ///
- /// Measures the hydraulic radii for the volumes by 6*(V/A) where
- /// V is the volume of the volume and A is the total area of all
- /// the volume's surfaces. Volumes with small hydraulic radii (compared
- /// to tol) are stored in the small_volumes list.
- ///
+ //! For each surface in the volume, find the interior angles
+ //! defined by the curves in the surfaces that are either below or
+ //! greater than the the upper and lower bounds. The angles
+ //! and therefor bounds, are tracked in degrees.
+ //! Curves that fit into these categories are stored pairwise in the
+ //! large or small edge_angles lists. The corresponding angle
+ //! measurements are stored in the respective small and large angles lists.
static void find_interior_curve_angles( RefVolume* ref_volume,
double upper_bound,
double lower_bound,
@@ -414,34 +462,24 @@
int &total_interior,
int &total_fuzzy);
- ///
- /// For each surface in the volume, find the interior angles
- /// defined by the curves in the surfaces that are either below or
- /// greater than the the upper and lower bounds. The angles
- /// and therefor bounds, are tracked in degrees.
- /// Curves that fit into these categories are stored pairwise in the
- /// large or small edge_angles lists. The corresponding angle
- /// measurements are stored in the respective small and large angles lists.
- ///
-
+ //! Find the tangential meetings in the volume.
+ //! This specifically looks for surfaces that meet tangentially
+ //! that would be a problem. Usually these are surfaces that
+ //! come into a side 180 degrees and on top there is a
+ //! sharpe angle. Usually if there isn't a sharpe curve
+ //! angle these meetings are not bad.
+ //! Note that this function assumes that you are passing
+ //! in sets of curve edges that have small interior angles between them.
+ //! It also assumes that the edge pairs are ordered as they would
+ //! be found in the surfaces (first edge then next edge).
+ //! Basically, call the funciton, find_interior_curve_angles
+ //! before calling this function, and pass this function those results.
static void find_sharp_tangential_meets( RefVolume *ref_volume,
DLIList <RefEdge*> &small_angle_edge_pairs,
DLIList <RefFace*> &tangential_surface_pairs );
- ///
- /// Find the tangential meetings in the volume.
- /// This specifically looks for surfaces that meet tangentially
- /// that would be a problem. Usually these are surfaces that
- /// come into a side 180 degrees and on top there is a
- /// sharpe angle. Usually if there isn't a sharpe curve
- /// angle these meetings are not bad.
- /// Note that this function assumes that you are passing
- /// in sets of curve edges that have small interior angles between them.
- /// It also assumes that the edge pairs are ordered as they would
- /// be found in the surfaces (first edge then next edge).
- /// Basically, call the funciton, find_interior_curve_angles
- /// before calling this function, and pass this function those results.
- ///
+ //! Finds the large and small angles or rather the surfaces on the volumes
+ //! that make them.
static void find_dihedral_angles( DLIList<RefVolume*> &ref_vols,
double upper_bound,
double lower_bound,
@@ -452,12 +490,12 @@
int &total_interior,
int &total_fuzzy,
int &total_not_flat);
- ///
- /// Finds the large and small angles or rather the surfaces on the volumes
- /// that make them.
- ///
+ //! Finds the surfaces that have big and small angles compared to the upper
+ //! and lower bounds (these should be in degrees...).
+ //! The faces that make these angles are paired (one after the other)
+ //! in the lists large and small angles.
static void find_dihedral_angles( RefVolume *curr_volume,
double lower_bound,
double upper_bound,
@@ -468,40 +506,30 @@
int &total_interior,
int &total_fuzzy,
int &total_not_flat);
- ///
- /// Finds the surfaces that have big and small angles compared to the upper
- /// and lower bounds (these should be in degrees...).
- /// The faces that make these angles are paired (one after the other)
- /// in the lists large and small angles.
- ///
+ //! Finds the surfaces with multiple loops that have small, relative
+ //! to tol, distances between the loops.
+ //! Note that all the lists are syncronized to be connected.
+ //! The pairs of close edges with the small_lengths and
+ //! the surfaces that they are on. The close_loop_faces list
+ //! may not contain distinct instances of faces, as they
+ //! may be repeated. Note that this will only find the
+ //! closest edge pair, within tol, for each loop.
static void find_close_loops(DLIList <RefVolume*> &ref_vols,
DLIList <RefEdge*> &close_edges,
DLIList <RefFace*> &close_loop_faces,
DLIList <double> &small_lengths,
double tol);
- ///
- /// Finds the surfaces with multiple loops that have small, relative
- /// to tol, distances between the loops.
- /// Note that all the lists are syncronized to be connected.
- /// The pairs of close edges with the small_lengths and
- /// the surfaces that they are on. The close_loop_faces list
- /// may not contain distinct instances of faces, as they
- /// may be repeated. Note that this will only find the
- /// closest edge pair, within tol, for each loop.
- ///
+ //! Finds the edges of the loops that are within some tol. The
+ //! edges are stored in successive pairs in close_edges while
+ //! the actual distances are stored in the small_lengths list.
+ //! These lists are syncronized (and are assumed to be empty upon
+ //! entrance to the function).
static void find_close_loops(RefFace *face,
DLIList <RefEdge*> &close_edges,
DLIList <double> &small_lengths,
double tol);
- ///
- /// Finds the edges of the loops that are within some tol. The
- /// edges are stored in successive pairs in close_edges while
- /// the actual distances are stored in the small_lengths list.
- /// These lists are syncronized (and are assumed to be empty upon
- /// entrance to the function).
- ///
#ifdef BOYD14
static void count_entities(DLIList<RefVolume*> &ref_vols,
@@ -514,69 +542,139 @@
///
#endif
+ //! Measures the area of the curr_face. Uses
+ //! the GeomDataObserver class to cache the area on the face.
+ //! After calling this function, curr_face will have
+ //! a GeomDataObserver observing it. It will get removed if
+ //! the surface is altered or changed.
static double measure_area(RefFace* curr_face);
- ///
- /// Measures the area of the curr_face. Uses
- /// the GeomDataObserver class to cache the area on the face.
- /// After calling this function, curr_face will have
- /// a GeomDataObserver observing it. It will get removed if
- /// the surface is altered or changed.
- ///
+ //! This function simply gets the bad entities of the volume. This
+ //! assumes the volume is from some solid modelar where this function
+ //! is defined. If not, it will just be empty...
static void find_bad_geometry(RefVolume *volume,
DLIList <RefEntity*> &bad_ents);
- ///
- /// This function simply gets the bad entities of the volume. This
- /// assumes the volume is from some solid modelar where this function
- /// is defined. If not, it will just be empty...
- ///
+ //@{
+ //! Find the irregular vertex valences.
+ //! Find things like vertices with valences greater than 4.
+ //! Assume for now that the volumes are not merged..
static void find_irregular_valence( DLIList <RefVolume*> &ref_volumes,
DLIList <RefVertex*> &irregular_vertices);
static void find_irregular_valence( RefVolume* ref_volume,
DLIList <RefVertex*> &irregular_vertices);
- ///
- /// Find the irregular vertex valences.
- /// Find things like vertices with valences greater than 4.
- /// Assume for now that the volumes are not merged..
- ///
+ //@}
+ //! Find fillets and rounds.
+ //!
+ //! ====IMPORTANT====
+ //! Calling functions BEWARE, YOU MUST DELETE THE LISTS OF
+ //! BLEND SURFACES IN THE BLEND GROUPS AFTER CALLING THIS FUNCTION!!!!
+ //! ====IMPORTANT====
static void find_blends( RefVolume *ref_volume,
DLIList <RefFace*> &blend_faces,
DLIList<DLIList<RefFace*>*> &blend_groups);
- ///
- /// Find fillets and rounds.
- ///
- /// ====IMPORTANT====
- /// Calling functions BEWARE, YOU MUST DELETE THE LISTS OF
- /// BLEND SURFACES IN THE BLEND GROUPS AFTER CALLING THIS FUNCTION!!!!
- /// ====IMPORTANT====
- ///
- ///
+ //! Determines if a face is a blend surface, returns the
+ //! ref_edge on one side of the blend and other_edge on
+ //! the opposite side. For this type of blend, only ref_edge
+ //! must be tangentially meeting with another surface.
+ //! Other_edge must be oriented orthogonally to it and may
+ //! or may not blend with another surface. This assumes a
+ //! rectangular blend surface, without holes.
static CubitBoolean is_face_blend(RefFace *ref_face,
RefVolume *ref_volume,
RefEdge *&ref_edge,
RefEdge *&other_edge);
- ///
- /// Determines if a face is a blend surface, returns the
- /// ref_edge on one side of the blend and other_edge on
- /// the opposite side. For this type of blend, only ref_edge
- /// must be tangentially meeting with another surface.
- /// Other_edge must be oriented orthogonally to it and may
- /// or may not blend with another surface. This assumes a
- /// rectangular blend surface, without holes.
- ///
+
+ //! Determines if a face is a vertex blend surface. It
+ //! assumes that a vertex blend will be tangent to all
+ //! adjoining surfaces and that the curvatures will be
+ //! shared at the edges.
+ static CubitBoolean is_vertex_blend(RefFace *ref_face,
+ RefVolume *ref_volume);
+
+ //! Given a starting blend surface find a chain of blends from
+ //! that surface.
+ //!
+ //! Note that this function intentionally does _not_
+ //! clear the blend_face list so that additional chains can be added.
+ static CubitStatus find_blend_chains( RefFace *start_face,
+ std::vector<std::vector< RefFace*> > &blend_chains);
+
+ //! should this one be private?
+ //! Given a blend surface and one of the cross curves, find the
+ //! blends connected along the edge in the one direction.
+ static void find_blends_from_edge( RefVolume* ref_volume,
+ RefFace *start_face,
+ RefEdge* start_edge,
+ std::vector <RefFace*> &blend_faces);
+
+ //! Takes the area-weighted average of all display facet
+ //! centroids and updates the passed in CubitVector to be
+ //! that location. Also updates the tot_area variable to
+ //! give the total facet area for the passed in ref_face.
+ static CubitStatus get_centroid( RefFace *ref_face,
+ CubitVector ¢roid, double &tot_area );
+
+ //! Finds averge center of specified surfaces.
+ static CubitStatus center( DLIList<RefFace*> ref_faces );
- static CubitStatus get_centroid( RefFace *ref_face, CubitVector ¢roid, double &tot_area );
- ///
- /// Takes the area-weighted average of all display facet
- /// centroids and updates the passed in CubitVector to be
- /// that location. Also updates the tot_area variable to
- /// give the total facet area for the passed in ref_face.
- ///
+ //! Finds the 'n' closest vertex-vertex pairs and their distances apart.
+ static CubitStatus find_closest_vertex_vertex_pairs(
+ DLIList<RefVolume*> &vol_list,
+ int &num_to_return,
+ DLIList<RefVertex*> &vert_list1,
+ DLIList<RefVertex*> &vert_list2,
+ DLIList<double> &distances);
- static CubitStatus center( DLIList<RefFace*> ref_faces );
+ //! Finds the 'n' closest vertex-curve pairs and their distances apart.
+ static CubitStatus find_closest_vertex_curve_pairs(
+ DLIList<RefVolume*> &vol_list,
+ int &num_to_return,
+ DLIList<RefVertex*> &vert_list,
+ DLIList<RefEdge*> &curve_list,
+ DLIList<double> &distances);
+
+ //! Finds coincident vertex-vertex pairs where each vertex is in a separate volume.
+ //! The two vertices in a vertex-vertex pairs are within high_tol of each other.
+ static CubitStatus find_near_coincident_vertices_unique(
+ DLIList<RefVolume*> &ref_volumes,
+ double high_tol,
+ std::map <RefVertex*, DLIList<dist_vert_struct*>*> &vert_dist_map);
+
+ //! Finds coincident vertex-vertex pairs where the vertices in the pair are
+ //! between low_tol and high_tol of one another.
+ static CubitStatus find_near_coincident_vertices(
+ DLIList<RefVolume*> &ref_volumes,
+ DLIList<RefVertex*> &ref_vertices_out,
+ DLIList<double> &distances,
+ double low_tol,
+ double high_tol,
+ bool filter_same_volume_cases = false);
+
+ //! Finds coincident vertex-curve pairs where with distance between the
+ //! vertex and curve is greater than low_tol but less than high_tol.
+ static CubitStatus find_near_coincident_vertex_curve_pairs(
+ DLIList<RefVolume*> &ref_vols,
+ DLIList<RefEdge*> &ref_edges,
+ DLIList<RefVertex*> &ref_verts,
+ DLIList<double> &distances,
+ double low_tol,
+ double high_tol,
+ bool filter_same_volume_cases = false);
+
+ //! Finds coincident vertex-surface pairs where with distance between the
+ //! vertex and surface is greater than low_tol but less than high_tol.
+ static CubitStatus find_near_coincident_vertex_surface_pairs(
+ DLIList<RefVolume*> &ref_vols,
+ DLIList<RefFace*> &ref_faces,
+ DLIList<RefVertex*> &ref_verts,
+ DLIList<double> &distances,
+ double low_tol,
+ double high_tol,
+ bool filter_same_volume_cases = false);
+
};
#endif
Modified: cgm/branches/cubit/geom/GeometryFeatureTool.hpp
===================================================================
--- cgm/branches/cubit/geom/GeometryFeatureTool.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/GeometryFeatureTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -30,6 +30,8 @@
//! destructor
~GeometryFeatureTool();
+ static void delete_instance() { if(instance_) delete instance_;};
+
//! add a feature engine to the list
void add_gfe( GeometryFeatureEngine *gfe_ptr );
Modified: cgm/branches/cubit/geom/GeometryHealerTool.cpp
===================================================================
--- cgm/branches/cubit/geom/GeometryHealerTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/GeometryHealerTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -294,8 +294,15 @@
GeometryHealerEngine* GHEPtr = get_engine(body_list.get());
if (GHEPtr)
- return GHEPtr->auto_heal_bodies(body_list, new_body_list, bad_geometry,
+ {
+ CubitStatus healer_status = GHEPtr->auto_heal_bodies(body_list, new_body_list, bad_geometry,
rebuild, keep_old, make_tolerant, logfile_ptr);
+
+ // if( healer_status == CUBIT_SUCCESS )
+ CubitObserver::notify_static_observers(NULL, HEALER_COMPLETED);
+
+ return healer_status;
+ }
else
PRINT_ERROR( "Bodies are of a geometry engine without a healer\n"
" and cannot be healed.\n");
Modified: cgm/branches/cubit/geom/GeometryHealerTool.hpp
===================================================================
--- cgm/branches/cubit/geom/GeometryHealerTool.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/GeometryHealerTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -35,9 +35,9 @@
class RefEdge;
class Body;
-
// *** END FORWARD DECLARATIONS *** //
+//! Class used for healing geometry. ACIS-specific.
class CUBIT_GEOM_EXPORT GeometryHealerTool
{
public:
@@ -45,6 +45,15 @@
// singleton pattern class instance interface
static GeometryHealerTool* instance( GeometryHealerEngine* GHEPtr = NULL );
+ static void delete_instance()
+ {
+ if (instance_)
+ {
+ delete instance_;
+ instance_ = NULL;
+ }
+ };
+
// destructor
~GeometryHealerTool();
@@ -53,7 +62,7 @@
// set the default healer engine
// void set_default_engine( GeometryHealerEngine *ghe_ptr );
- // add a healer engine to the list
+ //! add a healer engine to the list
void add_ghe( GeometryHealerEngine *ghe_ptr );
// remove a healer engine from the list
@@ -76,6 +85,9 @@
// *** BEGIN HEALER FUNCTIONS *** //
public:
+ //! Uses the autohealer to heal the given body list. The rebuild option
+ //! can be used for more rigorous healing, where each surface is pulled off,
+ //! healed, and then stitched back into a body.
CubitStatus auto_heal_bodies( DLIList<Body*> &body_list,
DLIList<Body*> &new_body_list,
DLIList<TopologyEntity*> &bad_geometry,
@@ -83,10 +95,10 @@
CubitBoolean keep_old = CUBIT_FALSE,
CubitBoolean make_tolerant = CUBIT_FALSE,
FILE* logfile_ptr = NULL );
- // Uses the autohealer to heal the given body list. The rebuild option
- // can be used for more rigorous healing, where each surface is pulled off,
- // healed, and then stitched back into a body.
+ //! Heals the input bodies, using either autoheal or incremental,
+ //! depending on the switches that are setup. Writes to the logfile
+ //! if it's been opened.
CubitStatus heal_bodies( DLIList<Body*> &body_list,
DLIList<Body*> &new_body_list,
DLIList<TopologyEntity*> &bad_geometry,
@@ -94,29 +106,74 @@
CubitBoolean keep_old = CUBIT_FALSE,
CubitBoolean make_tolerant = CUBIT_FALSE,
FILE* logfile_ptr = NULL );
- // Heals the input bodies, using either autoheal or incremental,
- // depending on the switches that are setup. Writes to the logfile
- // if it's been opened.
+ //! Uses the healing husk to find bad geometry and give feedback to
+ //! the user. A lot more could be done here - this is just a quick
+ //! overview for the user (the user will have no idea why the identified
+ //! geometry is bad). A logfile can give a little more information.
CubitStatus analyze_badgeom( DLIList<Body*> &body_list,
DLIList<TopologyEntity*> &bad_geometry,
FILE* logfile = NULL );
- // Uses the healing husk to find bad geometry and give feedback to
- // the user. A lot more could be done here - this is just a quick
- // overview for the user (the user will have no idea why the identified
- // geometry is bad). A logfile can give a little more information.
+ //! Shows the bad geometry. The geometry must have been analyzed first.
+ //! If body_list is empty, shows only for those bodies that have been
+ //! analyzed.
CubitStatus get_badgeom( DLIList<Body*> &body_list,
DLIList<TopologyEntity*> &bad_geometry );
- // Shows the bad geometry. The geometry must have been analyzed first.
- // If body_list is empty, shows only for those bodies that have been
- // analyzed.
+ //! Get tolerant curves. If the body list is empty, all tolerant
+ //! curves are retrieved.
CubitStatus get_tcurves( DLIList<Body*> &body_list,
DLIList<RefEdge*> &t_curves );
- // Get tolerant curves. If the body list is empty, all tolerant
- // curves are retrieved.
+ //! Uses the healing husk to perform one or more healing operations.
+ //! Which operations are performed is determined by switches in the
+ //! healer. The user can set default tolerances (separate from this
+ //! function, override the defaults with this function, or just use the
+ //! tolerances calculated by the healer (preferred).
+ //!
+ //! The possible healing steps are:
+ //! 1) preprocess - removes zero-length edges, sliver faces, duplicate
+ //! vertices. This is the first step which is always
+ //! done (user shouldn't suppress this). Tolerance is resabs.
+ //! 2) simplify - simplify NURBS into analytic.
+ //! Default simplify_tol = .0001
+ //! 3) stitch - stitch geometry together. Iterative from min to max
+ //! tolerance.
+ //! Default min tol = 10e-5
+ //! Default max tol = 1
+ //! 4) geombuild - geometry-related healing.
+ //! Default geombuild_tol = .01
+ //! Default analytic_tangency_tol = .01
+ //! Default isolspline_solver_tol = .01
+ //! Individual geombuild steps can be (instead of doing all):
+ //! analytic - performs all of the stages of the analytic solver
+ //! subphase of the geometry building phase. The analytic
+ //! solver subphase attempts to heal all edges and
+ //! vertices shared by analytic surfaces.
+ //! isospline - performs all of the stages of the isospline solver
+ //! subphase of the geometry building phase. The
+ //! isospline solver attempts to heal all edges shared
+ //! by tangential isoparametric surfaces (e.g., the
+ //! intersection curve is an isoparametric curve of
+ //! both splines in the intersection).
+ //! reblend - future option
+ //! sharpedge - performs all of the stages of the sharp edge solver
+ //! subphase of the geometry building phase. The sharp
+ //! edge solver attempts to heal all edges and vertices
+ //! that are shared by surfaces that intersect sharply.
+ //! This includes nontangential surface junctions.
+ //! genericspline - performs all of the stages of the generic spline
+ //! solver subphase of the geometry building phase.
+ //! The generic spline solver attempts to heal
+ //! generic tangential spline junctions, (e.g., the
+ //! intersection curve is not an isoparametric curve
+ //! of both splines in the intersection).
+ //! wrapup - handles remaining pcurves, wraps up
+ //! geometry buiilding phase (user shouldn't suppress)
+ //! 5) postprocess - correction of neg-area faces, duplicate vertices, edge groups;
+ //! last step - always done (user shouldn't suppress)
+ //! \brief Uses the healing husk to perform one or more healing operations.
CubitStatus heal_incremental( DLIList<Body*> &body_list,
DLIList<Body*> &new_bodies,
DLIList<TopologyEntity*> &bad_geometry,
@@ -131,60 +188,20 @@
CubitBoolean keep_old = CUBIT_FALSE,
CubitBoolean make_tolerant = CUBIT_FALSE,
FILE* logfile_ptr = NULL);
- // Uses the healing husk to perform one or more healing operations.
- // Which operations are performed is determined by switches in the
- // healer. The user can set default tolerances (separate from this
- // function, override the defaults with this function, or just use the
- // tolerances calculated by the healer (preferred).
- //
- // The possible healing steps are:
- // 1) preprocess - removes zero-length edges, sliver faces, duplicate
- // vertices. This is the first step which is always
- // done (user shouldn't suppress this). Tolerance is resabs.
- // 2) simplify - simplify NURBS into analytic.
- // Default simplify_tol = .0001
- // 3) stitch - stitch geometry together. Iterative from min to max
- // tolerance.
- // Default min tol = 10e-5
- // Default max tol = 1
- // 4) geombuild - geometry-related healing.
- // Default geombuild_tol = .01
- // Default analytic_tangency_tol = .01
- // Default isolspline_solver_tol = .01
- // Individual geombuild steps can be (instead of doing all):
- // analytic - performs all of the stages of the analytic solver
- // subphase of the geometry building phase. The analytic
- // solver subphase attempts to heal all edges and
- // vertices shared by analytic surfaces.
- // isospline - performs all of the stages of the isospline solver
- // subphase of the geometry building phase. The
- // isospline solver attempts to heal all edges shared
- // by tangential isoparametric surfaces (e.g., the
- // intersection curve is an isoparametric curve of
- // both splines in the intersection).
- // reblend - future option
- // sharpedge - performs all of the stages of the sharp edge solver
- // subphase of the geometry building phase. The sharp
- // edge solver attempts to heal all edges and vertices
- // that are shared by surfaces that intersect sharply.
- // This includes nontangential surface junctions.
- // genericspline - performs all of the stages of the generic spline
- // solver subphase of the geometry building phase.
- // The generic spline solver attempts to heal
- // generic tangential spline junctions, (e.g., the
- // intersection curve is not an isoparametric curve
- // of both splines in the intersection).
- // wrapup - handles remaining pcurves, wraps up
- // geometry buiilding phase (user shouldn't suppress)
- // 5) postprocess - correction of neg-area faces, duplicate vertices, edge groups;
- // last step - always done (user shouldn't suppress)
+ //! Lists the current settings for incremental healing
void list_incremental();
- // Lists the current settings for incremental healing
+ //! Lists out the tolerances of each body, separately
void list_tolerances( DLIList<Body*> &body_list );
- // Lists out the tolerances of each body, separately
-
+
+ //@{
+ //! Functions to set the default tolerances used. The healer calculates
+ //! the default tolerance per body. These functions allow the user to override
+ //! these defaults for all bodies healed. In incremental healing, the user can
+ //! override these defaults by sending-in tolerances. For autoheal, these
+ //! defaults are used if they are set, otherwise the healer calculates
+ //! intelligent defaults.
double get_default_simplify_tol();
void set_default_simplify_tol( double tol );
double get_default_stitch_min_tol();
@@ -203,56 +220,69 @@
void set_default_reblend_tol( double tol );
void reset_default_tolerances();
void list_default_tolerances();
- // Functions to set the default tolerances used. The healer calculates
- // the default tolerance per body. These functions allow the user to override
- // these defaults for all bodies healed. In incremental healing, the user can
- // override these defaults by sending-in tolerances. For autoheal, these
- // defaults are used if they are set, otherwise the healer calculates
- // intelligent defaults.
+ //@}
+ //! Cleans healer attributes from the bodies. These can be left if the
+ //! CleanAtt setting was used when doing analysis or healing.
void clean_attributes( DLIList<Body*>& body_list );
- // Cleans healer attributes from the bodies. These can be left if the
- // CleanAtt setting was used when doing analysis or healing.
+ //@{
+ //! Get/set flags which determine whether to clean attributes after
+ //! analysis and healing.
CubitBoolean get_cleanatt_flg();
void set_cleanatt_flg( CubitBoolean flg );
- // Get/set flags which determine whether to clean attributes after
- // analysis and healing.
+ //@}
+ //@{
+ //! Method determines how bad geometry is displayed
int get_show_method(); // 0-none, 1-highlight, 2-draw
void set_show_method( int method );
- // Method determines how bad geometry is displayed
+ //@}
+ //@{
+ //! Flag to determine whether to list a summary when showing bad geometry
CubitBoolean get_show_summary_flg();
void set_show_summary_flg( CubitBoolean flg );
- // Flag to determine whether to list a summary when showing bad geometry
+ //@}
+ //@{
+ //! Flag to determine whether to list details when showing bad geometry
CubitBoolean get_show_details_flg();
void set_show_details_flg( CubitBoolean flg );
- // Flag to determine whether to list details when showing bad geometry
+ //@}
+ //@{
+ //! Flag to determine whether to show bad geometry after healing
CubitBoolean get_show_on_heal_flg();
void set_show_on_heal_flg( CubitBoolean flg );
- // Flag to determine whether to show bad geometry after healing
+ //@}
+ //@{
+ //! Allow for checking of short curves after healing
CubitBoolean get_check_vol_on_heal_flg();
void set_check_vol_on_heal_flg( CubitBoolean flg );
double get_vol_on_heal_limit();
void set_vol_on_heal_limit( double limit );
- // Allow for checking of short curves after healing
+ //@}
+ //@{
+ //! Allow for checking of small surfaces after healing
CubitBoolean get_check_surf_on_heal_flg();
void set_check_surf_on_heal_flg( CubitBoolean flg );
double get_surf_on_heal_limit();
void set_surf_on_heal_limit( double limit );
- // Allow for checking of small surfaces after healing
-
+ //@}
+
+ //@{
+ //! Allow for checking of short curves after healing
CubitBoolean get_check_curve_on_heal_flg();
void set_check_curve_on_heal_flg( CubitBoolean flg );
double get_curve_on_heal_limit();
void set_curve_on_heal_limit( double limit );
- // Allow for checking of short curves after healing
-
+ //@}
+
+ //@{
+ //! Get/set for flags for what to show during analysis/show
CubitBoolean get_show_bad_vertices_flg();
void set_show_bad_vertices_flg( CubitBoolean flg );
CubitBoolean get_show_bad_curves_flg();
@@ -269,11 +299,13 @@
void set_show_bad_volumes_flg( CubitBoolean flg );
CubitBoolean get_show_bad_bodies_flg();
void set_show_bad_bodies_flg( CubitBoolean flg );
- // Get/set for flags for what to show during analysis/show
+ //@}
+ //! Function to list to user what the current onshow flags are
void list_onshow_flgs();
- // Function to list to user what the current onshow flags are
-
+
+ //@{
+ // Functions for controlling incremental healing
CubitBoolean get_inc_preprocess_flg();
void set_inc_preprocess_flg( CubitBoolean flg );
CubitBoolean get_inc_simplify_flg();
@@ -296,8 +328,10 @@
void set_inc_wrapup_flg( CubitBoolean flg );
CubitBoolean get_inc_postprocess_flg();
void set_inc_postprocess_flg( CubitBoolean flg );
- // Functions for controlling incremental healing
+ //@}
+ //@{
+ //! Forces a spline surface to be an analytical of the type specified.
CubitStatus force_simplify_to_plane( DLIList<RefFace*> &ref_face_list, DLIList<Body*>& new_body_list,
CubitBoolean keep = CUBIT_FALSE );
CubitStatus force_simplify_to_cylinder( DLIList<RefFace*> &ref_face_list, DLIList<Body*>& new_body_list,
@@ -308,7 +342,7 @@
CubitBoolean keep = CUBIT_FALSE );
CubitStatus force_simplify_to_torus( DLIList<RefFace*> &ref_face_list, DLIList<Body*>& new_body_list,
CubitBoolean keep = CUBIT_FALSE );
- // Forces a spline surface to be an analytical of the type specified.
+ //@}
// *** END HEALER FUNCTIONS *** //
Modified: cgm/branches/cubit/geom/GeometryModifyEngine.cpp
===================================================================
--- cgm/branches/cubit/geom/GeometryModifyEngine.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/GeometryModifyEngine.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -4,4 +4,12 @@
#include "GeometryModifyEngine.hpp"
-
+
+
+CubitStatus GeometryModifyEngine::split_free_curve( Curve *curve,
+ CubitVector &split_location,
+ DLIList<Curve*> &new_curves )
+{
+ return CUBIT_FAILURE;
+}
+
Modified: cgm/branches/cubit/geom/GeometryModifyEngine.hpp
===================================================================
--- cgm/branches/cubit/geom/GeometryModifyEngine.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/GeometryModifyEngine.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -1,5 +1,5 @@
//-------------------------------------------------------------------------
-// Filename : GeoemtricModifyEngine.hpp
+// Filename : GeometryModifyEngine.hpp
//
// Purpose : Define the interface for all solid model modify
// engines.
@@ -24,7 +24,6 @@
class CubitPlane;
template <class X> class DLIList;
-
class TopologyBridge;
class Point;
class Curve;
@@ -34,6 +33,7 @@
class LoopSM;
class GeometryEntity;
class GeometryQueryEngine;
+class CubitBox;
class CUBIT_GEOM_EXPORT GeometryModifyEngine
{
@@ -43,6 +43,10 @@
virtual ~GeometryModifyEngine() {}
//- virtual destructor
+ virtual bool supports_interoperability() = 0;
+ //- Returns whether intermixing of real and virtual geometry operations
+ //- is supported for the current geometry kernel.
+
virtual Point* make_Point( CubitVector const& position ) const = 0;
//R Point*
//R- Returned pointer to a Point object.
@@ -64,7 +68,10 @@
const CubitVector *third_point = NULL) const = 0;
//- Create a curve exactly on the give ref_face.
//- Make sure the points are on the underlying surface.
-
+
+ virtual Curve* make_Curve( DLIList<CubitVector*>& point_list,
+ DLIList<CubitVector*>& point_tangents) const = 0;
+
virtual Curve* make_Curve( GeometryType curve_type,
Point const* point1_ptr,
Point const* point2_ptr,
@@ -133,6 +140,21 @@
//- This function creates a new surface from an existing one.
//- 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 = 0;
+ //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 extended 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,
@@ -298,6 +320,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 = 0;
//- Imprints a list of Bodies with a list of RefEdges. All
@@ -307,6 +330,7 @@
virtual CubitStatus imprint( DLIList<Surface*> &ref_face_list,
DLIList<Curve*> &ref_edge_list,
+ DLIList<TopologyBridge*> &temporary_bridges,
DLIList<BodySM*>& new_body_list,
bool keep_old_body ) const = 0;
//- Imprints a list of Surfaces with a list of RefEdges. This is
@@ -317,7 +341,10 @@
virtual CubitStatus imprint( DLIList<Surface*> &surface_list,
DLIList<DLIList<Curve*>*> &curve_lists_list,
BodySM*& new_body,
- bool keep_old_body ) const = 0;
+ bool keep_old_body,
+ bool expand = true,
+ DLIList<TopologyBridge*> *new_tbs = NULL,
+ DLIList<TopologyBridge*> *att_tbs = NULL ) const = 0;
//- Imprints a list of Surfaces with list of Curves, sorted per
//- Surface (ie., curve_lists_list is same length as surface_list).
//- All input surfaces must be from the same body.
@@ -327,10 +354,22 @@
DLIList<BodySM*>& new_body_list,
bool keep_old_body,
DLIList<TopologyBridge*> *new_tbs = NULL,
- DLIList<TopologyBridge*> *att_tbs = NULL ) const = 0;
+ DLIList<TopologyBridge*> *att_tbs = NULL,
+ double *tol_in = NULL,
+ bool clean_up_slivers = true) const = 0;
//- Imprints a list of bodies with a list of vectors. Useful for
//- splitting curves and creating hardpoints on surfaces.
+ virtual CubitStatus tolerant_imprint(DLIList<Surface*> &surfs_in,
+ DLIList<BodySM*> &new_bodysm_list) const = 0;
+ 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 = 0;
+
virtual CubitStatus tolerant_imprint( DLIList<BodySM*> &bodies_in,
DLIList<BodySM*> &new_bodies,
DLIList<TopologyBridge*> *new_tbs = NULL,
@@ -353,6 +392,12 @@
bool keep_free_edges) const = 0;
//- Imprints a list of Bodies with a list of RefEdges which are projected
//- to a list of Surfaces
+ 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 = 0;
virtual CubitStatus project_edges(
DLIList<Surface*> &ref_face_list,
@@ -360,6 +405,10 @@
DLIList<Curve*> &ref_edge_list_new,
bool print_error = true ) const = 0;
//- Projects list RefEdges to a list of Surfaces
+
+ virtual CubitStatus curve_surface_intersection( Surface *surface,
+ Curve* curve,
+ DLIList<Curve*> &new_curves ) const = 0;
virtual CubitStatus intersect(BodySM* tool_body_ptr,
DLIList<BodySM*> &from_bodies,
@@ -419,9 +468,8 @@
//- argument is assigned a NULL value and the function returns
//- CUBIT_FAILURE.
-
virtual CubitStatus flip_normals( DLIList<Surface*>& face_list ) const = 0;
- //R CubitStatus
+ //R CubitStatus
//R-the result of the flip_normal operation: Success or Failure
//I bodies
//I-DLIList<Surface*>: a list of Face pointers that will be fliped
@@ -429,7 +477,8 @@
//- for some reason, the flip operation did not go well, the output
//- returns CUBIT_FAILURE.
-
+ virtual void get_possible_invalid_tbs(DLIList<TopologyBridge*> &bridges_in,
+ DLIList<TopologyBridge*> &bridges_out) = 0;
virtual CubitStatus unite( DLIList<BodySM*> &bodies,
DLIList<BodySM*> &newBodies,
bool keep_old = false) const = 0;
@@ -489,6 +538,17 @@
double draft_angle = 0.0,
int draft_type = 0,
bool rigid = false ) const= 0;
+ virtual CubitStatus sweep_to_body(
+ DLIList<Curve*> curve_list,
+ BodySM *target_body,
+ CubitVector distance,
+ DLIList<BodySM*> &new_bodies,
+ bool unite) const = 0;
+ virtual CubitStatus sweep_to_body(
+ Surface *source_surface,
+ BodySM *target_body,
+ CubitVector distance,
+ DLIList<BodySM*> &new_bodies) const = 0;
virtual CubitStatus scale( BodySM *&body, const CubitVector& factors ) = 0;
@@ -498,8 +558,10 @@
const CubitVector &v1,
const CubitVector &v2,
const CubitVector &v3,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*>& results_list,
- bool imprint = false ) const = 0;
+ ImprintType imprint_type = NO_IMPRINT,
+ bool preview = false) const = 0;
//R int
//R- Number of bodies that were webcut ( >= 0 )
//I webcut_body_list
@@ -518,8 +580,10 @@
virtual CubitStatus webcut(DLIList<BodySM*>& webcut_body_list,
BodySM const* tool_body,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*>& results_list,
- bool imprint = false ) const = 0 ;
+ ImprintType imprint_type = NO_IMPRINT,
+ bool preview = false) const = 0 ;
//R int
//R- Number of bodies that were webcut ( >= 0 )
//I webcut_body_list
@@ -535,23 +599,29 @@
//- This function webcuts a list of bodies using another body
//- as the webcutting tool. The newly created bodies are
//- merged and imprinted depeding on the respective flags.
+
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 = 0;
+ ImprintType imprint_type = NO_IMPRINT,
+ bool preview = false) const = 0;
- //- R status
+ //- R status
//- R-results_list of bodies affected, or created from webcut.
//- I- Bodies to be webcut, plane to define cuts, and imprint merge flags.
- //- This is an experimental function, hooked to the GUI for making
+ //- This is an experimental function, hooked to the Cat GUI for making
//- bodies one to one sweeps.
+
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) = 0;
+ ImprintType imprint_type = NO_IMPRINT,
+ bool preview = false) = 0;
//- webcuts a body using a sheet body.
//- It splits the sheet into two single sided bodies.
//- it then subtracts this with the webcut body.
@@ -559,14 +629,16 @@
//- if the webcut body is a topological torus, this routine
//- will fail...
- virtual CubitStatus webcut_with_extended_surf(
+ virtual CubitStatus webcut_with_extended_sheet(
DLIList<BodySM*> &webcut_body_list,
- Surface *extend_from,
+ DLIList<Surface*> &surface_list,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*> &new_bodies,
int &num_cut,
- bool imprint = false ) = 0;
- //- creates a surface by extending one from the given surface then
- //- webcuts using the this sheet.(see webcut_with_sheet.
+ ImprintType imprint_type = NO_IMPRINT,
+ bool preview = false) = 0;
+ //- creates a sheet by extending the given surfaces then webcuts using
+ //- this sheet.(see webcut_with_sheet).
virtual CubitStatus webcut_with_sweep_surfaces(
DLIList<BodySM*> &blank_bodies,
@@ -578,8 +650,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) = 0;
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean preview = false) = 0;
virtual CubitStatus webcut_with_sweep_curves(
DLIList<BodySM*> &blank_bodies,
@@ -588,8 +662,10 @@
bool through_all,
Surface *stop_surf,
Curve *curve_to_sweep_along,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*> &results_list,
- CubitBoolean imprint = false) = 0;
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean preview = false) = 0;
virtual CubitStatus webcut_with_sweep_curves_rotated(
DLIList<BodySM*> &blank_bodies,
@@ -598,8 +674,10 @@
const CubitVector &sweep_axis,
double angle,
Surface *stop_surf,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*> &results_list,
- CubitBoolean imprint = false) = 0;
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean preview = false) = 0;
virtual CubitStatus webcut_with_sweep_surfaces_rotated(
DLIList<BodySM*> &blank_bodies,
@@ -609,16 +687,19 @@
double angle,
Surface *stop_surf,
bool up_to_next,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*> &results_list,
- CubitBoolean imprint = false) = 0;
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean preview = false) = 0;
virtual CubitStatus webcut_with_cylinder(
- DLIList<BodySM*> &webcut_body_list,
- double radius,
+ DLIList<BodySM*> &webcut_body_list, double radius,
const CubitVector &axis,
const CubitVector ¢er,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*>& results_list,
- bool imprint = false) = 0;
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean preview = false) = 0;
//- webcuts a body using a cylinder give the input parameters.
virtual CubitStatus webcut_with_brick(
@@ -626,8 +707,10 @@
const CubitVector ¢er,
const CubitVector axes[3],
const CubitVector &extension,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*> &results_list,
- bool imprint = false ) = 0;
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean preview = false) = 0;
/**< Webcuts the bodies in the list with a cutting brick.
* The brick is created by the given parameters - center of
* brick, xyz axes, and extension. Extension is 1/2 width,
@@ -642,8 +725,10 @@
const CubitVector ¢er,
const CubitVector axes[2],
double width, double height,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*> &results_list,
- bool imprint = false ) = 0;
+ ImprintType imprint_type = NO_IMPRINT,
+ bool preview = false) = 0;
/**< Webcuts the bodies in the list with a cutting planar sheet.
* The sheet is created by the given parameters - center of
* sheet, xy axes, and width and height. Sheet creation is done
@@ -653,8 +738,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) = 0;
+ ImprintType imprint_type = NO_IMPRINT,
+ bool preview = false) = 0;
//- webcuts a body list using a temp sheet body created from the curve loop
@@ -673,6 +760,15 @@
DLIList<BodySM*> &new_bodies ) = 0;
//- Splits a body with multiple volumes into multiple bodies
//- each having only one volume.
+
+ virtual CubitStatus split_free_curve( Curve *curve,
+ CubitVector &split_location,
+ DLIList<Curve*> &new_curves );
+
+ virtual CubitStatus separate_surfaces( DLIList<Surface*> &surf_list,
+ DLIList<BodySM*> &new_bodies ) = 0;
+ //- Separates surfaces from sheet bodies into separate bodies. Connected
+ //- surfaces will remain connected but be placed in a new body.
virtual CubitStatus reverse_body( BodySM *body_to_reverse ) = 0;
//- Reverse body (turn it inside-out).
@@ -686,12 +782,11 @@
//- Removes all unnecessary faces, edges and vertices from the body.
virtual CubitStatus regularize_entity( GeometryEntity *old_entity_ptr,
- BodySM *&new_body_ptr ) = 0;
+ BodySM *&new_body_ptr) = 0;
//- Removes all all unnessesary faces, curves, vertices and associated
//- data from a refentity.
+ virtual CubitStatus test_regularize_entity( GeometryEntity *old_entity_ptr) = 0;
-
- // Added by CAT
virtual CubitStatus offset_curves( DLIList<Curve*>& ref_edge_list,
DLIList<Curve*>& result_curve_list,
double offset_distance,
@@ -702,7 +797,15 @@
//- 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.
- virtual Curve* trim_curve( Curve* trim_curve,
+ virtual CubitStatus split_curve( Curve* curve_to_split,
+ const CubitVector& split_location,
+ DLIList<Curve*>& created_curves ) = 0;
+ //- 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
+
+
+ virtual Curve* trim_curve( Curve* trim_curve,
const CubitVector& trim_vector,
const CubitVector& keep_vector,
bool keep_old = false ) = 0;
@@ -711,11 +814,12 @@
//- is not free, the curve is automatically copied before trimming (so
//- a new curve results).
- virtual CubitStatus create_body_from_surfs(
+ virtual CubitStatus create_solid_bodies_from_surfs(
DLIList<Surface*> &ref_face_list,
- BodySM *&new_body,
+ DLIList<BodySM*> &new_bodies,
bool keep_old = false,
- bool heal = true) const = 0;
+ bool heal = true,
+ bool sheet = false ) const = 0;
//- Creates a single body from a set of faces. The faces can only be attached
//- to bodies if they are sheet bodies. It is assumed that the calling code will
//- check for this, ie GeometryTool.
@@ -813,6 +917,20 @@
BodySM *body_to_trim_to,
BodySM *&midsurface_body ) const = 0;
+ 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 ) const = 0;
+
virtual CubitStatus tweak_chamfer( DLIList<Curve*> &curve_list,
double left_offset,
DLIList<BodySM*> &new_bodysm_list,
@@ -886,26 +1004,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 = 0;
/**< 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 = 0;
/**< 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 = 0;
/**< Remove surfaces from a body or bodies and then extend the adjoining
@@ -924,37 +1045,83 @@
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 = 0;
/**< 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 = 0;
+ CubitBoolean preview = CUBIT_FALSE,
+ double max_area_increase = 0 ) const = 0;
/**< Tweak specified edges of a surface or set of surfaces (in sheet
* bodies) up to a set of connected target surfaces. This essentially
- * extends or trims the attached surfaces of the sheet body.
+ * extends or 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. The max_area_increase is a percentage increase for
+ * which the geometry will not be tweaked if the resulting surface area surpasses.
*/
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 = 0;
+ CubitBoolean preview = CUBIT_FALSE,
+ double max_area_increase = 0) const = 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 surface created
- * by thickening the owning surface of the target curve.
+ * by thickening the owning surface of the target curve. 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 = 0;
+ /**< 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 *bodies, double lengthlimit ) const = 0;
-
virtual CubitStatus create_net_surface( DLIList<Surface*>& ref_face_list, BodySM *& new_body,
DLIList<DLIList<CubitVector*>*> &vec_lists_u,
DLIList<DLIList<CubitVector*>*> &vec_lists_v,
@@ -966,9 +1133,24 @@
virtual CubitStatus create_offset_surface( Surface* ref_face_ptr, BodySM*& new_body, double offset_distance ) const = 0;
+ 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 = 0;
+ /**< 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 = 0;
- virtual CubitStatus create_skin_surface( DLIList<Curve*>& curves, BodySM*& new_body ) const = 0;
+ virtual CubitStatus create_skin_surface( DLIList<Curve*>& curves, BodySM*& new_body,
+ DLIList<Curve*>& guides) const = 0;
virtual CubitStatus loft_surfaces( Surface *face1, const double &takeoff1,
Surface *face2, const double &takeoff2,
@@ -980,22 +1162,32 @@
CubitBoolean simplify_option = CUBIT_FALSE) const = 0;
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 = 0;
+ Surface *face2, const double &takeoff2,
+ BodySM*& new_body,
+ CubitBoolean arc_length_option,
+ CubitBoolean twist_option,
+ CubitBoolean align_direction,
+ CubitBoolean perpendicular,
+ CubitBoolean simplify_option) const = 0;
virtual CubitStatus create_surface( DLIList<CubitVector*>& vec_list,
BodySM *&new_body, Surface *ref_face_ptr,
CubitBoolean project_points ) const = 0;
+ virtual CubitStatus create_surface( DLIList<Point*> &points,
+ BodySM *&new_body ) const = 0;
+
virtual CubitStatus create_weld_surface( CubitVector &root,
Surface *ref_face1, double leg1, Surface *ref_face2, double leg2,
BodySM *&new_body ) const = 0;
+ virtual CubitBoolean bodies_interfering( BodySM *body1, BodySM *body2 ) const {return CUBIT_FALSE;}
+
+ virtual CubitStatus stitch( DLIList<BodySM*> &bodies_to_stitch,
+ DLIList<BodySM*> &new_bodies,
+ bool tighten_gaps,
+ double tolerance )const = 0;
+
protected:
private:
@@ -1003,4 +1195,3 @@
};
#endif
-
Modified: cgm/branches/cubit/geom/GeometryModifyTool.cpp
===================================================================
--- cgm/branches/cubit/geom/GeometryModifyTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/GeometryModifyTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -1,4 +1,3 @@
-
//-------------------------------------------------------------------------
// Filename : GeometryModifyTool.cpp
//
@@ -12,11 +11,12 @@
//
//-------------------------------------------------------------------------
-
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <math.h>
+#include <sstream>
+//#include <iostream>
#include "GeometryModifyTool.hpp"
#include "CubitDefines.h"
@@ -32,6 +32,7 @@
#include "TopologyBridge.hpp"
#include "ModelQueryEngine.hpp"
#include "CADefines.hpp"
+#include "GeomMeasureTool.hpp"
#include "RefEntity.hpp"
#include "RefEntityFactory.hpp"
@@ -65,6 +66,7 @@
#include "CubitVector.hpp"
#include "CubitPlane.hpp"
#include "CubitTransformMatrix.hpp"
+#include "GfxPreview.hpp"
#include "DLIList.hpp"
@@ -82,22 +84,30 @@
#include "BridgeManager.hpp"
#include "SplitSurfaceTool.hpp"
#include "OffsetSplitTool.hpp"
+#include "AutoMidsurfaceTool.hpp"
+#include "TDSurfaceOverlap.hpp"
+#include "GfxDebug.hpp"
+#include "CubitUndo.hpp"
-
-
/* Work around stupid #define hz equal to HZ on IBM */
#ifdef hz
# undef hz
#endif
+#ifdef PROE
+#include "CompositeTool.hpp"
+#endif
GeometryModifyTool* GeometryModifyTool::instance_ = 0;
CubitBoolean GeometryModifyTool::allEdgesImprint = CUBIT_TRUE;
CubitBoolean GeometryModifyTool::groupImprint = CUBIT_TRUE;
CubitBoolean GeometryModifyTool::newIds = CUBIT_FALSE;
CubitBoolean GeometryModifyTool::sepAfterWebcut = CUBIT_TRUE;
-CubitBoolean GeometryModifyTool::booleanRegularize= CUBIT_TRUE;
+CubitBoolean GeometryModifyTool::booleanRegularize = CUBIT_TRUE;
+CubitBoolean GeometryModifyTool::uniteMixedModels = CUBIT_TRUE;
CubitBoolean GeometryModifyTool::oldNames = CUBIT_FALSE;
+CubitBoolean GeometryModifyTool::meshAutodelete = CUBIT_TRUE;
+CubitBoolean GeometryModifyTool::meshAutodeleteRemesh = CUBIT_FALSE;
RefEntity* GeometryModifyTool::copyingEntity = NULL;
//-------------------------------------------------------------------------
@@ -164,6 +174,24 @@
}
//-------------------------------------------------------------------------
+// Purpose : Deletes instance variable
+//
+// Special Notes :
+//
+// Creator : Corey Ernst
+//
+// Creation Date : 12/31/07
+//-------------------------------------------------------------------------
+void GeometryModifyTool::delete_instance()
+{
+ if( NULL != instance_ )
+ {
+ delete instance_;
+ instance_ = NULL;
+ }
+}
+
+//-------------------------------------------------------------------------
// Purpose : Creates a Body corresponding to a sphere with the
// given radius
//
@@ -173,7 +201,12 @@
//
// Creation Date : 09/18/96
//-------------------------------------------------------------------------
-Body* GeometryModifyTool::sphere(double radius)
+Body* GeometryModifyTool::sphere(double radius,
+ int x_shift,
+ int y_shift,
+ int z_shift,
+ double inner_radius,
+ bool delete_side )
{
if (0 == gmeList.size())
{
@@ -190,15 +223,98 @@
return NULL ;
}
- BodySM* body_sm = gmeList.get()->sphere(radius);
- if (!body_sm)
- {
- PRINT_ERROR("In GeometryModifyTool::sphere\n"
- " Problems building a volume from the sphere.\n");
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state();
+
+ GeometryModifyEngine *gme = gmeList.get();
+
+ BodySM* body_sm = gme->sphere(radius);
+
+ if (x_shift != 0 || y_shift != 0 || z_shift != 0)
+ {
+ BodySM *brick = gme->brick( 2.0 * radius,
+ 2.0 * radius,
+ 2.0 * radius);
+
+ CubitVector delta( x_shift * radius,
+ y_shift * radius,
+ z_shift * radius );
+
+ gme->get_gqe()->translate( brick, delta );
+
+ DLIList<BodySM*> new_sms;
+ DLIList<BodySM*> from_bodies(1);
+ from_bodies.append( body_sm );
+ bool keep_old = true;
+ CubitStatus bool_status;
+ if( delete_side == false )
+ bool_status = gme->intersect( brick, from_bodies, new_sms, keep_old );
+ else
+ {
+ DLIList<BodySM*> tool_bodies(1);
+ tool_bodies.append( brick );
+ bool imprint = false;
+ bool_status = gme->subtract( tool_bodies, from_bodies, new_sms, imprint, keep_old );
+ }
+
+ //delete the old bodies
+ gme->get_gqe()->delete_solid_model_entities( body_sm );
+ gme->get_gqe()->delete_solid_model_entities( brick );
+
+ if( bool_status == CUBIT_FAILURE || new_sms.size() == 0 )
+ {
+ PRINT_ERROR("Problems creating sphere.\n" );
return NULL ;
- }
+ }
- return GeometryQueryTool::instance()->make_Body(body_sm);
+ body_sm = new_sms.get();
+ }
+
+ Body *new_body = NULL;
+ BodySM* inner_body_sm = NULL;
+ if( inner_radius )
+ {
+ inner_body_sm = gme->sphere(inner_radius);
+ DLIList<BodySM*> new_sms;
+ DLIList<BodySM*> from_bodies(1);
+ DLIList<BodySM*> tool_bodies(1);
+ from_bodies.append( body_sm );
+ tool_bodies.append( inner_body_sm );
+ bool imprint = false;
+ bool keep_old = true;
+ CubitStatus subtract_status =
+ gme->subtract( tool_bodies, from_bodies, new_sms, imprint, keep_old );
+
+ //delete the old bodies
+ gme->get_gqe()->delete_solid_model_entities( body_sm );
+ gme->get_gqe()->delete_solid_model_entities( inner_body_sm );
+
+ if( subtract_status == CUBIT_FAILURE || new_sms.size() == 0 )
+ {
+ PRINT_ERROR("Problems creating sphere with inner radius.\n" );
+ return NULL ;
+ }
+
+ body_sm = new_sms.get();
+ }
+
+ if (!body_sm)
+ {
+ PRINT_ERROR("In GeometryModifyTool::sphere\n"
+ " Problems building a volume from the sphere.\n");
+ }
+ else
+ new_body = GeometryQueryTool::instance()->make_Body(body_sm);
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( new_body )
+ CubitUndo::note_result_body( new_body );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
+ return new_body;
}
//-------------------------------------------------------------------------
@@ -229,16 +345,29 @@
return NULL;
}
- BodySM* bodyPtr = gmeList.get()->brick(width, depth, height) ;
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state();
+ Body *new_body = NULL;
+ BodySM* bodyPtr = gmeList.get()->brick(width, depth, height);
+
if (bodyPtr == NULL)
{
PRINT_ERROR("In GeometryModifyTool::brick\n"
" Problem creating a brick.\n") ;
- return NULL ;
}
+ else
+ new_body = GeometryQueryTool::instance()->make_Body(bodyPtr);
- return GeometryQueryTool::instance()->make_Body(bodyPtr);
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( new_body )
+ CubitUndo::note_result_body( new_body );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
+ return new_body;
}
//-------------------------------------------------------------------------
@@ -309,19 +438,30 @@
return planar_sheet( center, sheet_axes, width, height );
}
}
-
else
{
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state();
+
BodySM* bodyPtr = gmeList.get()->brick(center, axes, extension) ;
-
+ Body *new_body = NULL;
if (bodyPtr == NULL)
{
PRINT_ERROR("In GeometryTool::brick\n"
" Problem creating a brick.\n") ;
- return NULL;
}
+ else
+ new_body = GeometryQueryTool::instance()->make_Body(bodyPtr);
- return GeometryQueryTool::instance()->make_Body(bodyPtr);
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( new_body )
+ CubitUndo::note_result_body( new_body );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
+ return new_body;
}
}
@@ -361,17 +501,29 @@
return NULL;
}
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state();
+
// Create a Body that represents the prism
BodySM* bodyPtr = gmeList.get()->prism(height, sides, major, minor) ;
-
+ Body *new_body = NULL;
if (bodyPtr == NULL)
{
PRINT_ERROR("In GeometryModifyTool::prism\n"
" Problems building a volume from the prism.\n") ;
- return NULL;
}
+ else
+ new_body = GeometryQueryTool::instance()->make_Body(bodyPtr);
- return GeometryQueryTool::instance()->make_Body(bodyPtr);
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( new_body )
+ CubitUndo::note_result_body( new_body );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
+ return new_body;
}
//-------------------------------------------------------------------------
@@ -409,16 +561,29 @@
return NULL;
}
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state();
+
// Create a Body that represents the prism
BodySM* bodyPtr = gmeList.get()->pyramid ( height, sides, major, minor, top);
+ Body *new_body = NULL;
if (bodyPtr == NULL)
{
PRINT_ERROR("In GeometryModifyTool::pyramid\n"
" Problems building a volume from the pyramid.\n");
- return NULL;
}
+ else
+ new_body = GeometryQueryTool::instance()->make_Body(bodyPtr);
- return GeometryQueryTool::instance()->make_Body(bodyPtr);
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( new_body )
+ CubitUndo::note_result_body( new_body );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
+ return new_body;
}
//-------------------------------------------------------------------------
@@ -456,17 +621,30 @@
return NULL;
}
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state();
+
// Create a Body that represents the prism
BodySM* bodyPtr = gmeList.get()->cylinder( hi, r1, r2, r3);
+ Body *new_body = NULL;
if (bodyPtr == NULL)
{
PRINT_ERROR("In GeometryModifyTool::cylinder\n"
" Problems building a volume from the conical frustum.\n");
- return NULL;
}
+ else
+ new_body = GeometryQueryTool::instance()->make_Body(bodyPtr);
- return GeometryQueryTool::instance()->make_Body(bodyPtr);
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( new_body )
+ CubitUndo::note_result_body( new_body );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
+ return new_body;
}
//-------------------------------------------------------------------------
@@ -498,17 +676,30 @@
return NULL;
}
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state();
+
// Create a Body that represents the torus
BodySM* bodyPtr = gmeList.get()->torus(r1, r2) ;
+ Body *new_body = NULL;
if (bodyPtr == NULL)
{
PRINT_ERROR("In GeometryModifyTool::torus\n"
" Problems building a volume from the torus.\n") ;
- return NULL ;
}
+ else
+ new_body = GeometryQueryTool::instance()->make_Body(bodyPtr);
- return GeometryQueryTool::instance()->make_Body(bodyPtr);
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( new_body )
+ CubitUndo::note_result_body( new_body );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
+ return new_body;
}
//-------------------------------------------------------------------------
@@ -531,17 +722,29 @@
return NULL;
}
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state();
+
// Create a Body that represents the sheet
BodySM* body_ptr = gmeList.get()->planar_sheet(p1, p2, p3, p4) ;
-
+ Body *new_body = NULL;
if( body_ptr == NULL )
{
PRINT_ERROR("In GeometryTool::planar_sheet\n"
" Problems building a volume from the sheet.\n") ;
- return NULL;
}
+ else
+ new_body = GeometryQueryTool::instance()->make_Body(body_ptr);
- return GeometryQueryTool::instance()->make_Body(body_ptr);
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( new_body )
+ CubitUndo::note_result_body( new_body );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
+ return new_body;
}
//-------------------------------------------------------------------------
@@ -573,17 +776,30 @@
p2.next_point( axes[0], -width, p3 );
p3.next_point( axes[1], -height, p4 );
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state();
+
// Create a Body that represents the sheet
BodySM* body_ptr = gmeList.get()->planar_sheet(p1, p2, p3, p4) ;
+ Body *new_body = NULL;
if( body_ptr == NULL )
{
PRINT_ERROR("In GeometryTool::planar_sheet\n"
" Problems building a volume from the sheet.\n") ;
- return NULL;
}
+ else
+ new_body = GeometryQueryTool::instance()->make_Body(body_ptr);
- return GeometryQueryTool::instance()->make_Body(body_ptr);
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( new_body )
+ CubitUndo::note_result_body( new_body );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
+ return new_body;
}
//-------------------------------------------------------------------------
@@ -617,19 +833,88 @@
extension, p1, p2, p3, p4 ) == CUBIT_FAILURE )
return NULL;
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state();
+
// Create a Body that represents the sheet
BodySM* body_ptr = gmeList.get()->planar_sheet(p1, p2, p3, p4) ;
+ Body *new_body = NULL;
if( body_ptr == NULL )
{
PRINT_ERROR("In GeometryModifyTool::planar_sheet\n"
" Problems building a volume from the sheet.\n") ;
- return NULL ;
}
+ else
+ new_body = GeometryQueryTool::instance()->make_Body(body_ptr);
- return GeometryQueryTool::instance()->make_Body(body_ptr);
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( new_body )
+ CubitUndo::note_result_body( new_body );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
+ return new_body;
}
+RefVertex* GeometryModifyTool::make_RefVertex( RefVertex *vertex ) const
+{
+ if ( vertex == NULL )
+ {
+ PRINT_ERROR("Vertex is NULL\n");
+ return NULL;
+ }
+
+ TopologyBridge* bridge = 0;
+ GeometryModifyEngine* engine = get_engine(vertex, &bridge);
+ if (engine == NULL)
+ {
+ PRINT_ERROR( "%s (vertex %d) does not have a modify engine.\n",
+ vertex->entity_name().c_str(),
+ vertex->id() );
+ return 0;
+ }
+
+ CubitVector point = vertex->coordinates();
+
+ // Call the default GeometryModifyEngine to create a new Point
+ Point* point_ptr = engine->make_Point(point);
+
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state();
+
+ // Use the Point to create a RefVertex
+ RefVertex* ref_vertex_ptr = RefEntityFactory::instance()->construct_RefVertex(point_ptr) ;
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( ref_vertex_ptr )
+ CubitUndo::note_result_entity( ref_vertex_ptr );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
+ //transfer the names
+ DLIList<CubitString*> names;
+ vertex->entity_names( names );
+
+ int i;
+ for( i=names.size(); i--; )
+ {
+ CubitString *tmp_name = names.get_and_step();
+ ref_vertex_ptr->entity_name( *tmp_name );
+ }
+
+ // Send a message to the model indicating the vertex was created
+ CubitObserver::notify_static_observers(ref_vertex_ptr, FREE_REF_ENTITY_GENERATED);
+
+ // Return the newly created RefVertex
+ return ref_vertex_ptr ;
+}
+
+
//-------------------------------------------------------------------------
// Purpose : This function takes a type information and a location
// to create a RefVertex. The underlying representation
@@ -665,9 +950,20 @@
return (RefVertex *)NULL ;
}
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state();
+
// Use the Point to create a RefVertex
RefVertex* ref_vertex_ptr = RefEntityFactory::instance()->construct_RefVertex(point_ptr) ;
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( ref_vertex_ptr )
+ CubitUndo::note_result_entity( ref_vertex_ptr );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
ref_vertex_ptr->color(color);
// Send a message to the model indicating the vertex was created
@@ -699,7 +995,8 @@
//
// Creation Date : 10/9/97
//-------------------------------------------------------------------------
-RefEdge* GeometryModifyTool::make_RefEdge(RefEdge *ref_edge_ptr, bool copy_attribs ) const
+RefEdge* GeometryModifyTool::make_RefEdge(RefEdge *ref_edge_ptr,
+ bool copy_attribs ) const
{
if ( ref_edge_ptr == NULL )
{
@@ -746,10 +1043,16 @@
new_curve = CAST_TO( new_curve_bridge, Curve);
}
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state();
+
// Complete the task of linking this new Curve into the rest of the
// geometry datastructures and return the new RefEdge.
RefEdge *new_ref_edge = GeometryQueryTool::instance()->make_free_RefEdge(new_curve);
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::note_result_entity( new_ref_edge );
+
return new_ref_edge;
}
@@ -907,7 +1210,220 @@
CGMApp::instance()->restore_previous_attribute_states();
return CUBIT_SUCCESS;
}
+#ifdef PROE
+CubitStatus GeometryModifyTool::prepare_for_topology_update( BodySM* old_bodysm )
+{
+ DLIList<BodySM*> old_bodysms;
+ old_bodysms.append(old_bodysm);
+ do_attribute_setup();
+ push_vg_attributes_before_modify( old_bodysms );
+
+ return CUBIT_SUCCESS;
+}
+CubitStatus GeometryModifyTool::finish_topology_update( BodySM* new_bodysm,
+ Body* old_body )
+{
+ DLIList<Body*> input_bodies,result_bodies;
+ DLIList<BodySM*> new_bodysms, old_bodysms;
+ input_bodies.append(old_body);
+ new_bodysms.append(new_bodysm);
+ old_bodysms.clean_out();
+
+ DLIList<int> merged_surface_ids;
+ DLIList<int> merged_curve_ids;
+
+
+ get_merged_curve_and_surface_ids( input_bodies, merged_surface_ids, merged_curve_ids );
+ ///*
+ //Store information about what surfaces were originally merged
+ //
+ //This fixes a problem caused by the lack of support
+ //for automatically remerging surfaces that contain any
+ //virtual geometry.
+ //This should be removed if this issue is ever fixed - AHH
+ std::map< int , DLIList<Surface*> > merged_map;
+ for(int i=0; i< merged_surface_ids.size(); i++ )
+ {
+ int refface_id = merged_surface_ids.get_and_step();
+ RefFace* old_merged_refface = RefEntityFactory::instance()->get_ref_face( refface_id );
+ if( old_merged_refface && old_merged_refface->bridge_manager()->number_of_bridges() > 1 )
+ {
+ DLIList<Surface*> merged_surfsms;
+ DLIList<TopologyBridge*> bridge_list;
+ old_merged_refface->bridge_manager()->get_bridge_list( bridge_list );
+ for(int j=0; j< bridge_list.size(); j++ )
+ {
+ Surface* merging_surf = CAST_TO(bridge_list.get_and_step(),Surface);
+ if( merging_surf )
+ merged_surfsms.append_unique( merging_surf );
+ }
+ merged_map[ refface_id ] = merged_surfsms;
+ }
+ }
+ //*/
+ /*
+ //check to see if any curves have been orphaned inside virtual geometry
+ DLIList<Point*> point_list;
+ new_bodysm->points( point_list );
+ CubitBoolean loop = CUBIT_TRUE;
+ while( loop )
+ {
+ for(i=0; i< point_list.size(); i++)
+ {
+ //loop all the points and see if any will be on only one live curve
+ Point* curr_point = point_list.get_and_step();
+ DLIList<Curve*> curves_on_point;
+ DLIList<Curve*> curves_to_keep;
+ curr_point->curves( curves_on_point );
+ for(int j=0; j< curves_on_point.size(); j++)
+ {
+ Curve* curr_curve = curves_on_point.get_and_step();
+ DLIList<CubitSimpleAttrib*> attrib_list;
+ CubitSimpleAttrib* attrib = CompositeEngine::find_attribute_by_name( curr_curve, "COMPOSITE_GEOM" );
+ if( attrib )
+ {
+ attrib_list.append(attrib);
+ }
+ else
+ curves_to_keep.append_unique( curr_curve );
+ //curr_curve->get_simple_attribute( "COMPOSITE_GEOM", attrib_list );
+ //if ( !attrib_list.size() )
+ //curves_to_keep.append_unique( curr_curve );
+ }
+ //if all but one curve on this point will be removed we need to remove the other one too
+ if( curves_to_keep.size() == 1 )
+ {
+ CubitString name("COMPOSITE_GEOM");
+ DLIList<CubitString*> string_list;
+ string_list.append( &name );
+ CubitSimpleAttrib geom_attrib( &string_list, 0, 0 );
+ curves_to_keep.get()->append_simple_attribute_virt( &geom_attrib );
+ curr_point->append_simple_attribute_virt( &geom_attrib );
+ loop = CUBIT_FALSE;
+ }
+ else if( curves_to_keep.size() == 0 )
+ {
+ DLIList<CubitSimpleAttrib*> attrib_list;
+ curr_point->get_simple_attribute( "COMPOSIT_GEOM", attrib_list );
+ if( !attrib_list.size() )
+ {
+ CubitString name("COMPOSITE_GEOM");
+ DLIList<CubitString*> string_list;
+ string_list.append( &name );
+ CubitSimpleAttrib geom_attrib( &string_list, 0, 0 );
+ curr_point->append_simple_attribute_virt( &geom_attrib );
+ loop = CUBIT_TRUE;
+ }
+ }
+ }
+ if( loop )
+ loop = CUBIT_FALSE;
+ else
+ loop = CUBIT_TRUE;
+ }
+ */
+ GeometryModifyEngine* gme = GeometryModifyTool::instance()->get_engine(old_body);
+
+ restore_vg_after_modify(new_bodysms, input_bodies, gme);
+
+
+ DLIList<RefVolume*> volume_list;
+
+ int i;
+ for(i=new_bodysms.size(); i--;)
+ {
+ BodySM *bsm = new_bodysms.get_and_step();
+ Body *body = dynamic_cast<Body*>(bsm->topology_entity());
+ if(body)
+ {
+ // Append to the total list of volumes.
+ body->ref_volumes(volume_list);
+ }
+ }
+ // get all child entities (only get entities below volumes)
+ DLIList<RefEntity*> child_list, ref_ent_list;
+ CAST_LIST_TO_PARENT(volume_list, ref_ent_list);
+ RefEntity::get_all_child_ref_entities( ref_ent_list, child_list );
+
+ // Only push the id attributes if we are doing persistent ids.
+ for(i=child_list.size(); i--;)
+ {
+ child_list.get_and_step()->auto_actuate_cubit_attrib(CUBIT_FALSE,CUBIT_TRUE);
+ }
+
+ remove_pushed_attributes(new_bodysms, input_bodies);
+
+ finish_sm_op( input_bodies, new_bodysms , result_bodies);
+
+ fixup_merged_entities( merged_surface_ids, merged_curve_ids);
+
+ //Look for RefEdges that are orphaned inside of virtual surfaces
+ CubitBoolean loop = CUBIT_TRUE;
+ DLIList<RefVertex*> vertex_list;
+ while(loop)
+ {
+ loop = CUBIT_FALSE;
+ vertex_list.clean_out();
+ for(i=0; i< volume_list.size(); i++)
+ {
+ RefVolume* curr_volume = volume_list.get_and_step();
+ curr_volume->ref_vertices( vertex_list );
+ }
+ for(i=0; i< vertex_list.size(); i++)
+ {
+ RefVertex* curr_vertex = vertex_list.get_and_step();
+ DLIList<RefEdge*> edges_on_vertex;
+ curr_vertex->ref_edges( edges_on_vertex );
+ edges_on_vertex.uniquify_unordered();
+ if( edges_on_vertex.size() == 1 )
+ {
+ RefEdge* edge_to_remove = edges_on_vertex.get();
+ CompositeTool::instance()->remove_edge(edge_to_remove);
+ loop = CUBIT_TRUE;
+ break;
+ }
+ }
+ }
+ ///*
+ //Force merge faces that were missed by finish_sm_op
+ //
+ //This fixes a problem caused by the lack of support
+ //for automatically remerging surfaces that contain any
+ //virtual geometry.
+ //This should be removed if this issue is ever fixed - AHH
+ for(i=0; i< merged_surface_ids.size(); i++)
+ {
+ int refface_id = merged_surface_ids.get_and_step();
+ DLIList<RefFace*> ref_faces_to_remerge;
+ if(merged_map.find( refface_id ) != merged_map.end())
+ {
+ DLIList<Surface*> merged_surfsms = merged_map[ refface_id ];
+ for(int k=0; k< merged_surfsms.size(); k++)
+ {
+ Surface* merging_surf = merged_surfsms.get_and_step();
+ RefFace* merging_refface = CAST_TO(merging_surf->topology_entity(),RefFace);
+ if(merging_refface)
+ ref_faces_to_remerge.append_unique(merging_refface);
+ }
+ }
+ if( ref_faces_to_remerge.size() == 2 )
+ {
+ RefFace* first_remerge_face = ref_faces_to_remerge.get_and_step();
+ RefFace* second_remerge_face = ref_faces_to_remerge.get_and_step();
+ int first_id = first_remerge_face->id();
+ int second_id = second_remerge_face->id();
+ MergeTool::instance()->force_merge( first_remerge_face , second_remerge_face );
+ PRINT_WARNING("Remerging Surfaces %i and %i\n",first_id,second_id);
+ }
+ }
+ //*/
+ //do_attribute_cleanup();
+
+ return CUBIT_SUCCESS;
+}
+
+#endif
GeometryModifyEngine*
GeometryModifyTool::make_RefEdge_common( RefVertex* start_vertex,
RefVertex* end_vertex,
@@ -1012,7 +1528,9 @@
ref_face_ptr->move_to_surface(vert_1);
ref_face_ptr->move_to_surface(vert_2);
- if (!ref_vertex_1->coordinates().within_tolerance(vert_1, GEOMETRY_RESABS))
+ GeometryQueryEngine *gqe = ref_face_ptr->get_geometry_query_engine();
+
+ if (!ref_vertex_1->coordinates().within_tolerance(vert_1, gqe->get_sme_resabs_tolerance()))
{
PRINT_ERROR("vertices must lie within tolerance to the given"
" surface.\n"
@@ -1023,7 +1541,7 @@
ref_face_ptr->id() );
return (RefEdge*)NULL;
}
- else if (!ref_vertex_2->coordinates().within_tolerance(vert_2, GEOMETRY_RESABS))
+ else if (!ref_vertex_2->coordinates().within_tolerance(vert_2, gqe->get_sme_resabs_tolerance() ))
{
PRINT_ERROR("vertices must lie within tolerance to the given"
" surface.\n"
@@ -1072,6 +1590,9 @@
// Make sure that we get back valid Points
assert ( point_ptr1 != NULL && point_ptr2 != NULL );
+
+
+
// Request the GME to create a Curve using the Points
Curve *curve_ptr;
curve_ptr = GMEPtr->make_Curve( point_ptr1,
@@ -1091,9 +1612,25 @@
return (RefEdge *)NULL ;
}
+ if( CubitUndo::get_undo_enabled() )
+ {
+ //if endpoints are free vertices, need to save them out
+ DLIList<RefVertex*> verts_to_save;
+ verts_to_save.append( ref_vertex_1 );
+ verts_to_save.append( ref_vertex_2 );
+ bool save_only_if_free = true;
+ CubitUndo::save_state_with_cubit_file( verts_to_save, save_only_if_free );
+ }
+
// Complete the task of linking this new Curve into the rest of the
// geometry datastructures and return the new RefEdge.
- return GeometryQueryTool::instance()->make_free_RefEdge(curve_ptr);
+ RefEdge *new_edge = GeometryQueryTool::instance()->make_free_RefEdge(curve_ptr);
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( new_edge )
+ CubitUndo::note_result_entity( new_edge );
+ }
+ return new_edge;
}
//-------------------------------------------------------------------------
@@ -1127,8 +1664,6 @@
Point* point_ptr2 = NULL;
Surface* surface_ptr = NULL;
-
-
// Look for a common GeometryModifyEngine
GMEPtr = make_RefEdge_common( ref_vertex_1, ref_vertex_2,
point_ptr1, point_ptr2,
@@ -1139,6 +1674,16 @@
// Make sure that we get back valid Points
assert ( point_ptr1 != NULL && point_ptr2 != NULL );
+ if( CubitUndo::get_undo_enabled() )
+ {
+ //if endpoints are free vertices, need to save them out
+ DLIList<RefVertex*> verts_to_save;
+ verts_to_save.append( ref_vertex_1 );
+ verts_to_save.append( ref_vertex_2 );
+ bool save_only_if_free = true;
+ CubitUndo::save_state_with_cubit_file( verts_to_save, save_only_if_free );
+ }
+
// Request the GME to create a Curve using the Points
Curve* curve_ptr = GMEPtr->make_Curve(ref_edge_type,
point_ptr1,
@@ -1160,7 +1705,13 @@
// Complete the task of linking this new Curve into the rest of the
// geometry datastructures and return the new RefEdge.
- return GeometryQueryTool::instance()->make_free_RefEdge(curve_ptr);
+ RefEdge *new_edge = GeometryQueryTool::instance()->make_free_RefEdge(curve_ptr);
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( new_edge )
+ CubitUndo::note_result_entity( new_edge );
+ }
+ return new_edge;
}
//-------------------------------------------------------------------------
@@ -1198,6 +1749,16 @@
// Make sure that we get back valid Points
assert ( point_ptr1 != NULL && point_ptr2 != NULL ) ;
+ if( CubitUndo::get_undo_enabled() )
+ {
+ //if endpoints are free vertices, need to save them out
+ DLIList<RefVertex*> verts_to_save;
+ verts_to_save.append( ref_vertex_1 );
+ verts_to_save.append( ref_vertex_2 );
+ bool save_only_if_free = true;
+ CubitUndo::save_state_with_cubit_file( verts_to_save, save_only_if_free );
+ }
+
// Request the GME to create a Curve using the Points
Curve* curve_ptr = GMEPtr->make_Curve(ref_edge_type,
point_ptr1,
@@ -1218,8 +1779,15 @@
// Complete the task of linking this new Curve into the rest of the
// geometry datastructures and return the new RefEdge.
- return GeometryQueryTool::instance()->make_free_RefEdge( curve_ptr );
+ RefEdge *new_edge = GeometryQueryTool::instance()->make_free_RefEdge( curve_ptr );
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( new_edge )
+ CubitUndo::note_result_entity( new_edge );
+ }
+ return new_edge;
}
+
//-------------------------------------------------------------------------
// Purpose : This function creates a RefFace from an existing RefFace.
// The new face is a sheet body, double sided face with no
@@ -1254,17 +1822,16 @@
return (RefFace*)NULL;
}
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state();
+
//this list will get all the TB's what we'll be copying
-#ifdef BOYD17
- DLIList<TopologyBridge*> original_bridges;
-#endif
TopologyBridge *top_bridge = old_surface_ptr;
if( !extended_from )
{
prepare_for_copy( from_ref_face, top_bridge );
}
-
Surface *tmp_surface = CAST_TO( top_bridge, Surface );
Surface* new_surface_ptr = engine->make_Surface( tmp_surface,
extended_from );
@@ -1274,6 +1841,10 @@
PRINT_ERROR("Surface copy failed.\n");
if( !extended_from )
clean_up_from_copy_failure( old_surface_ptr );
+
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
+
return 0;
}
@@ -1289,10 +1860,75 @@
new_Body->ref_faces(ref_faces);
assert(ref_faces.size() > 0);
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( new_Body )
+ CubitUndo::note_result_body( new_Body );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
return ref_faces.get();
}
//-------------------------------------------------------------------------
+// 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 : 02/28/08
+//-------------------------------------------------------------------------
+Body*
+GeometryModifyTool::make_extended_sheet( DLIList<RefFace*> &ref_face_list,
+ CubitBox *clip_box_ptr,
+ bool preview ) const
+{
+ if( !ref_face_list.size() )
+ return 0;
+
+ // Check for virtual geometry
+ DLIList<RefEntity*> ref_ent_list;
+ CAST_LIST_TO_PARENT(ref_face_list, ref_ent_list);
+ if ( GeometryQueryTool::instance()->contains_intermediate_geometry(ref_ent_list) )
+ {
+ PRINT_ERROR("EXTENDING surfaces containing virtual geometry is not\n"
+ " allowed. Delete virtual geometry on these surfaces\n"
+ " before operation.\n" );
+ return 0;
+ }
+
+ // Look for a common GeometryModifyEngine for all of the RefFaces
+ int count = ref_face_list.size();
+ DLIList<TopologyBridge*> bridge_list(count);
+ DLIList<TopologyEntity*> entity_list(count);
+ CAST_LIST_TO_PARENT( ref_face_list, entity_list );
+
+ GeometryModifyEngine* GME_ptr =
+ common_modify_engine( entity_list, bridge_list );
+ if(! GME_ptr )
+ {
+ PRINT_ERROR("Cannot construct an extended sheet using surfaces that\n"
+ " do not share a common geometry engine.\n");
+ return 0;
+ }
+
+ DLIList<Surface*> surface_list(count);
+ CAST_LIST( bridge_list, surface_list, Surface );
+
+ BodySM *bodySM_ptr = GME_ptr->make_extended_sheet( surface_list,
+ clip_box_ptr, preview );
+
+ if( bodySM_ptr )
+ return GeometryQueryTool::instance()->make_Body(bodySM_ptr);
+ else
+ return 0;
+}
+
+//-------------------------------------------------------------------------
// Purpose : This function takes a type information and a list of
// RefEdges to create a Body with just one RefFace. The
// underlying representation of the RefFace is determined
@@ -1311,6 +1947,7 @@
RefFace* GeometryModifyTool::make_RefFace(GeometryType ref_face_type,
DLIList<RefEdge*>& ref_edge_list,
+ bool is_free_face,
RefFace *ref_face_ptr,
bool check_edges ) const
{
@@ -1328,7 +1965,7 @@
if(! GME_ptr )
{
PRINT_ERROR("Cannot construct a Surface using entities that do "
- "not share a common GeometryModifyEngine.\n");
+ "not share a common geometry engine.\n");
return 0;
}
@@ -1336,6 +1973,44 @@
if (ref_face_ptr)
old_surface_ptr = dynamic_cast<Surface*>(bridge_list.pop());
+ //Collect all the names on vertices to propagate after you create
+ //the surface
+ DLIList<CubitVector> vertex_coordinates;
+ DLIList<CubitString*> vertex_names;
+ DLIList<RefEdge*> free_ref_edges;
+ int kk;
+ for( kk=ref_edge_list.size(); kk--; )
+ {
+ DLIList<CubitString*> tmp_names;
+ RefEdge *tmp_edge = ref_edge_list.get_and_step();
+
+ if( tmp_edge->num_parent_ref_entities() == 0 )
+ free_ref_edges.append( tmp_edge );
+
+ RefVertex *s_vertex = tmp_edge->start_vertex();
+ RefVertex *e_vertex = tmp_edge->end_vertex();
+ int jj;
+
+ s_vertex->entity_names( tmp_names );
+ for( jj=tmp_names.size(); jj--; )
+ {
+ CubitVector tmp_vec = tmp_edge->start_vertex()->coordinates();
+ CubitString *name = tmp_names.get_and_step();
+ vertex_coordinates.append( tmp_vec );
+ vertex_names.append( new CubitString(*name) );
+ }
+
+ tmp_names.clean_out();
+ e_vertex->entity_names( tmp_names );
+ for( jj=tmp_names.size(); jj--; )
+ {
+ CubitVector tmp_vec = tmp_edge->end_vertex()->coordinates();
+ CubitString *name = tmp_names.get_and_step();
+ vertex_coordinates.append( tmp_vec );
+ vertex_names.append( new CubitString(*name) );
+ }
+ }
+
DLIList<Curve*> curve_list(ref_edge_list.size());
CAST_LIST( bridge_list, curve_list, Curve );
@@ -1349,74 +2024,46 @@
}
GeometryQueryTool* const gqt = GeometryQueryTool::instance();
- RefFace* result_face = gqt->make_free_RefFace(surface_ptr);
+
+ RefFace* result_face = gqt->make_free_RefFace(surface_ptr, is_free_face);
gqt->cleanout_deactivated_geometry();
- return result_face;
-}
-//-------------------------------------------------------------------------
-// Purpose : This function takes a type information and a list of
-// RefFaces to create a RefVolume. The underlying
-// representation of the RefVolume is determined by the
-// GeometryModifyEngine of the RefFaces. All the
-// RefFaces in the list must be associated with the same
-// GeometryModifyEngine. The return value can be a
-// NULL pointer, if the RefVolume cannot be succesfully
-// made for some reason.
-//
-// Special Notes :
-//
-// Creator : Raikanta Sahu
-//
-// Creation Date : 03/29/97
-//-------------------------------------------------------------------------
-/*
-RefVolume*
-GeometryModifyTool::make_RefVolume( DLIList<RefFace*>& ref_face_list) const
-{
- GeometryModifyEngine* GME_ptr = 0;
-
- DLIList<TopologyEntity*> entity_list(ref_face_list.size());
- DLIList<TopologyBridge*> bridge_list(ref_face_list.size());
-
- //Look for a common GeometryModifyEngine
- CAST_LIST_TO_PARENT( ref_face_list, entity_list );
- GME_ptr = common_modify_engine( entity_list, bridge_list );
-
- if( !GME_ptr )
+ //send out events for free curves saying that their 'free' status has
+ //be changed
+
+ for( kk=0; kk<free_ref_edges.size(); kk++ )
{
- PRINT_ERROR("The surfaces are not owned by the same geometry "
- "engine. Cannot create a volume from them.\n");
- return 0;
+ RefEdge *free_edge = free_ref_edges.get_and_step();
+ CubitObserver::notify_static_observers( free_edge, TOP_LEVEL_ENTITY_DESTRUCTED );
+ CGMHistory::Event evt(CGMHistory::TOP_LEVEL_ENTITY_DELETED, free_edge );
+ GeometryQueryTool::instance()->history().add_event(evt);
}
- //Get the list of surfaces.
- DLIList<Surface*> surface_list(ref_face_list.size());
- CAST_LIST( bridge_list, surface_list, Surface );
- surface_list.remove_all_with_value(0);
- assert(surface_list.size() == ref_face_list.size());
- // Use the Surfaces to create a Lump
- Lump* lump_ptr = GME_ptr->make_Lump(surface_list) ;
+ //look for a vertex at the same location of the original
+ //vertex(s). Add the name to this new vertex.
+ DLIList<RefVertex*> tmp_verts;
+ result_face->ref_vertices( tmp_verts);
+ for( kk=vertex_coordinates.size(); kk--; )
+ {
+ CubitVector tmp_coord = vertex_coordinates.get_and_step();
+ CubitString *tmp_name = vertex_names.get_and_step();
- // If we get a NULL pointer, give a warning message and return
- // a NULL pointer.
- if (lump_ptr == NULL)
- {
- PRINT_WARNING("In GeometryModifyTool::make_RefVolume\n"
- " Got a NULL pointer to a Lump.\n"
- " Cannot make a RefVolume.\n") ;
- return (RefVolume *)NULL;
+ int jj;
+ for( jj=tmp_verts.size(); jj--; )
+ {
+ RefVertex *tmp_vert = tmp_verts.get_and_step();
+ if( tmp_coord.distance_between( tmp_vert->coordinates() ) < GEOMETRY_RESABS )
+ {
+ //add the name if it doesn't already exist
+ RefEntityName::instance()->add_refentity_name( tmp_vert, *tmp_name );
+ }
+ }
}
- // Use the Lump to make a RefVolume
- RefVolume* ref_volume_ptr =
- GeometryQueryTool::instance()->make_RefVolume(lump_ptr);
+ return result_face;
+}
- // Return the new RefVolume
- return ref_volume_ptr ;
-}
-*/
//-------------------------------------------------------------------------
// Purpose : This function takes a list of RefVolumes to create a
// Body. The underlying representation of the Body is
@@ -1482,9 +2129,11 @@
Body* GeometryModifyTool::make_Body(RefFace *from_ref_face,
CubitBoolean extended_from) const
{
+ bool is_free_face = false;
+
// Given the arguments, make a RefFace.
RefFace* new_ref_face = this->make_RefFace(from_ref_face,
- extended_from);
+ extended_from );
if (!new_ref_face)
{
return (Body *)NULL;
@@ -1525,10 +2174,16 @@
DLIList<RefEdge*>& ref_edge_list,
RefFace *ref_face_ptr) const
{
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state_with_cubit_file( ref_edge_list );
+
+ bool is_free_face = false;
+
// Given the arguments, make a RefFace.
RefFace* new_ref_face = this->make_RefFace(ref_face_type,
ref_edge_list,
- ref_face_ptr) ;
+ is_free_face,
+ ref_face_ptr);
if( new_ref_face == NULL )
return NULL;
@@ -1548,6 +2203,14 @@
bodies.append( body );
}
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( bodies.size() )
+ CubitUndo::note_result_entity( bodies.get() );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
// Return the body containing the new RefFace.
return bodies.get();
}
@@ -1627,29 +2290,48 @@
{
CubitStatus ret = CUBIT_SUCCESS;
- if(strcmp(op, "WEBCUT") &&
- strcmp(op, "CHOP") &&
- strcmp(op, "IMPRINT") &&
- strcmp(op, "SPLIT"))
+ Body *b = webcut_body_list.get();
+ if(b)
{
- if ( contains_intermediate_geom(webcut_body_list) )
+ GeometryModifyEngine *gme = get_engine(b);
+ if(gme)
{
- PRINT_ERROR("Performing %s on volumes containing geometry from\n"
- "different modeling engines is not allowed.\n"
- "Delete uncommon geometry on these volumes before operation.\n\n",
- op);
- ret = CUBIT_FAILURE;
+ if(!gme->supports_interoperability() &&
+ contains_intermediate_geom(webcut_body_list))
+ {
+ PRINT_ERROR("Intermixing real and virtual geometry operations using the current solid modeling kernel is not allowed.\n");
+ ret = CUBIT_FAILURE;
+ }
}
}
- else
+
+ if(ret == CUBIT_SUCCESS)
{
- if(contains_partitions(webcut_body_list))
+ // If the operation is not one of the ones below...
+ if(strcmp(op, "WEBCUT") &&
+ strcmp(op, "CHOP") &&
+ strcmp(op, "UNITE") &&
+ strcmp(op, "TWEAK") &&
+ strcmp(op, "IMPRINT") &&
+ strcmp(op, "REGULARIZE") &&
+ strcmp(op, "SPLIT_SURFACE") &&
+ strcmp(op, "REMOVE_TOPOLOGY") &&
+ strcmp(op, "SPLIT"))
{
- PRINT_ERROR("Performing %s on volumes containing virtual partitions.\n"
- "This is currently not supported.\n\n",
- op);
- ret = CUBIT_FAILURE;
+ if (contains_intermediate_geom(webcut_body_list))
+ {
+ PRINT_ERROR("Performing %s on volumes containing virtual geometry is not allowed.\n", op);
+ ret = CUBIT_FAILURE;
+ }
}
+ else
+ {
+ if(contains_partitions(webcut_body_list))
+ {
+ PRINT_ERROR("Performing %s on volumes containing virtual partitions is not allowed.\n", op);
+ ret = CUBIT_FAILURE;
+ }
+ }
}
return ret;
@@ -1670,6 +2352,8 @@
CubitBoolean merge,
CubitStatus status,
DLIList<Body*>& result_list,
+ DLIList<int> *merged_surface_ids,
+ DLIList<int> *merged_curve_ids,
CubitBoolean print_info) const
{
if (!finish_sm_op(webcut_body_list, result_body_sms, result_list,(bool)print_info))
@@ -1682,10 +2366,12 @@
result_list = temp_result_list;
}
+ if( merged_surface_ids && merged_curve_ids )
+ fixup_merged_entities( *merged_surface_ids, *merged_curve_ids );
+
if (merge && status)
{
DLIList<Body*> temp_results(result_list);
- temp_results += webcut_body_list;
status = MergeTool::instance()->merge_bodies( temp_results );
}
@@ -1713,6 +2399,13 @@
DLIList<int> updated_ids, created_ids, destroyed_ids;
DLIList<int> updated_vol_ids, created_vol_ids, destroyed_vol_ids;
+ // traverse the body object and remove any meshes from modified objects
+ int b;
+ for (b = 0; b < input_bodies.size(); b++) {
+ Body* body = input_bodies.get_and_step();
+ body_premodify(body);
+ }
+
// Remove dead bodies
input_bodies.reset();
for (i = input_bodies.size(); i--;)
@@ -1816,14 +2509,45 @@
const CubitVector &axis,
const CubitVector ¢er,
DLIList<Body*>& results_list,
- CubitBoolean imprint,
- CubitBoolean merge)
+ DLIList<Body*> &neighboring_bodies,
+ ImprintType imprint_type,
+ CubitBoolean merge,
+ CubitBoolean preview)
{
if (!okay_to_modify( webcut_body_list, "WEBCUT" ))
return CUBIT_FAILURE;
CubitStatus rval = CUBIT_SUCCESS;
+ if (preview)
+ {
+ // find the bounding box for the cylinder
+ CubitBox bounding_box;
+ Body* body_ptr = webcut_body_list.get_and_step();
+ bounding_box = body_ptr->bounding_box();
+
+ int i;
+ for( i=1; i<webcut_body_list.size(); i++ )
+ {
+ body_ptr = webcut_body_list.get_and_step();
+ bounding_box |= body_ptr->bounding_box();
+ }
+
+ int color = CUBIT_BLUE;
+ GfxPreview::clear();
+ GfxPreview::draw_cylinder(axis, center, bounding_box, (float) radius, color);
+ GfxPreview::flush();
+ return rval;
+ }
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<Body*> bodies_to_save;
+ bodies_to_save += webcut_body_list;
+ bodies_to_save += neighboring_bodies;
+ CubitUndo::save_state_with_cubit_file( bodies_to_save );
+ }
+
const int count = webcut_body_list.size();
DLIList<BodySM*> result_sm_list;
DLIList<Body*> body_list(webcut_body_list);
@@ -1831,20 +2555,61 @@
DLIList<Body*> engine_bodies(count);
GeometryModifyEngine* gme = 0;
- do_attribute_setup();
+ if(!preview)
+ do_attribute_setup();
while ( (gme = group_bodies_by_engine(body_list, engine_bodies, engine_body_sms)) )
{
- push_vg_attributes_before_modify(engine_body_sms);
+ //get all bodysms that we might modify in this operation
+ DLIList<BodySM*> neighbor_imprint_list;
+ DLIList<BodySM*> bodies_sm_to_modify;
+ DLIList<Body*> bodies_to_modify;
+ bodies_to_modify += engine_bodies;
+ int i;
+ for( i=neighboring_bodies.size(); i--; )
+ {
+ Body *tmp_body = neighboring_bodies.get_and_step();
+ BodySM *tmp_body_sm = tmp_body->get_body_sm_ptr();
+ if( gme == get_engine(tmp_body_sm ) )
+ {
+ neighbor_imprint_list.append( tmp_body_sm );
+ bodies_to_modify.append( tmp_body );
+ }
+ }
+ DLIList<int> merged_surface_ids;
+ DLIList<int> merged_curve_ids;
+
+ if(!preview)
+ {
+ bodies_sm_to_modify += neighbor_imprint_list;
+
+ push_vg_attributes_before_modify( bodies_sm_to_modify );
+ //get all the child entities that have been merged
+ get_merged_curve_and_surface_ids( bodies_to_modify, merged_surface_ids, merged_curve_ids );
+ }
+
+ // note that preview actually gets handled before this point
CubitStatus status = gme->webcut_with_cylinder(engine_body_sms, radius, axis,
- center, result_sm_list, imprint );
+ center, neighbor_imprint_list, result_sm_list, imprint_type, preview );
- restore_vg_after_modify(result_sm_list, engine_bodies);
-
if ( status != CUBIT_FAILURE )
- status = finish_webcut( engine_bodies, result_sm_list, merge, status, results_list );
+ {
+ if(!preview)
+ {
+ restore_vg_after_modify(result_sm_list, bodies_to_modify, gme);
+ remove_pushed_attributes(result_sm_list, bodies_to_modify);
+ }
+ status = finish_webcut( engine_bodies, result_sm_list, merge, status,
+ results_list, &merged_surface_ids, &merged_curve_ids );
+ }
+ else
+ {
+ if(!preview)
+ remove_pushed_attributes(result_sm_list, engine_bodies);
+ }
+
engine_bodies.clean_out();
engine_body_sms.clean_out();
result_sm_list.clean_out();
@@ -1856,8 +2621,17 @@
}
}
- do_attribute_cleanup();
+ if(!preview)
+ do_attribute_cleanup();
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( rval == CUBIT_SUCCESS )
+ CubitUndo::note_result_bodies( results_list );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
return rval;
}
@@ -1865,6 +2639,19 @@
{
//save attribute settings
CGMApp::instance()->save_current_attribute_states();
+
+ //Turn off all attributes
+ CubitAttribManager *attrib_manager = CGMApp::instance()->attrib_manager();
+ attrib_manager->set_all_auto_update_flags( CUBIT_FALSE );
+ attrib_manager->set_all_auto_actuate_flags( CUBIT_FALSE );
+ attrib_manager->set_all_auto_write_flags( CUBIT_FALSE );
+ attrib_manager->set_all_auto_read_flags( CUBIT_FALSE );
+
+ CGMApp::instance()->attrib_manager()->set_auto_update_flag(CA_ENTITY_NAME, CUBIT_TRUE);
+ CGMApp::instance()->attrib_manager()->set_auto_actuate_flag(CA_ENTITY_NAME, CUBIT_TRUE);
+ CGMApp::instance()->attrib_manager()->set_auto_write_flag(CA_ENTITY_NAME, CUBIT_TRUE);
+ CGMApp::instance()->attrib_manager()->set_auto_read_flag(CA_ENTITY_NAME, CUBIT_TRUE);
+
// enable update, actuate, write, read for composite attributes
CGMApp::instance()->attrib_manager()->set_auto_update_flag(CA_COMPOSITE_VG, CUBIT_TRUE);
CGMApp::instance()->attrib_manager()->set_auto_actuate_flag(CA_COMPOSITE_VG, CUBIT_TRUE);
@@ -1875,6 +2662,13 @@
CGMApp::instance()->attrib_manager()->set_auto_actuate_flag(CA_PARTITION_VG, CUBIT_TRUE);
CGMApp::instance()->attrib_manager()->set_auto_write_flag(CA_PARTITION_VG, CUBIT_TRUE);
CGMApp::instance()->attrib_manager()->set_auto_read_flag(CA_PARTITION_VG, CUBIT_TRUE);
+ // enable update, actuate, write, read for entity ids
+ // We will use these ID atts to make sure the ref entities associated with unmodified
+ // virtual bridges will maintain the same ids after real operations.
+ CGMApp::instance()->attrib_manager()->set_auto_update_flag(CA_ENTITY_ID, CUBIT_TRUE);
+ CGMApp::instance()->attrib_manager()->set_auto_actuate_flag(CA_ENTITY_ID, CUBIT_TRUE);
+ CGMApp::instance()->attrib_manager()->set_auto_write_flag(CA_ENTITY_ID, CUBIT_TRUE);
+ CGMApp::instance()->attrib_manager()->set_auto_read_flag(CA_ENTITY_ID, CUBIT_TRUE);
}
void GeometryModifyTool::do_attribute_cleanup(void)
@@ -1886,6 +2680,31 @@
// topology.
void GeometryModifyTool::push_vg_attributes_before_modify(DLIList<BodySM*> &old_sms)
{
+ // Get all of the ref entities involved and push CA_ENTITY_ID attributes
+ // on to them. This will help us maintain ids on virtual that doesn't
+ // get modified by the real operation.
+ int i;
+ DLIList<RefVolume*> volume_list;
+
+ for(i=old_sms.size(); i--;)
+ {
+ BodySM *bsm = old_sms.get_and_step();
+ Body *body = dynamic_cast<Body*>(bsm->topology_entity());
+ if(body)
+ {
+ // Append to the total list of volumes.
+ body->ref_volumes(volume_list);
+ }
+ }
+ // get all child entities (only get entities below volumes)
+ DLIList<RefEntity*> child_list, ref_ent_list;
+ CAST_LIST_TO_PARENT(volume_list, ref_ent_list);
+ RefEntity::get_all_child_ref_entities( ref_ent_list, child_list );
+
+ // Only push the id attributes if we are doing persistent ids.
+ if(!get_new_ids())
+ CubitAttribUser::auto_update_cubit_attrib(child_list);
+
DLIList<TopologyBridge*> top_bridges;
CAST_LIST_TO_PARENT(old_sms, top_bridges);
GeometryQueryTool::instance()->ige_export_geom(top_bridges);
@@ -1898,6 +2717,12 @@
GeometryQueryTool::instance()->ige_push_imprint_attributes_before_modify(body_sms);
}
+void GeometryModifyTool::push_named_attributes_to_curves_and_points(DLIList<TopologyBridge*> &tb_list,
+ const char *name_in)
+{
+ GeometryQueryTool::instance()->ige_push_named_attributes_to_curves_and_points(tb_list, name_in);
+}
+
// Cleanup imprint attributes that were pushed onto the underlying solid
// model topology.
void GeometryModifyTool::remove_imprint_attributes_after_modify(DLIList<BodySM*> &old_sms,
@@ -1912,8 +2737,9 @@
RefFace *ref_face_top,
RefFace *ref_face_bottom,
DLIList<Body*> &results_list,
- CubitBoolean imprint,
- CubitBoolean merge )
+ ImprintType imprint_type,
+ CubitBoolean merge,
+ CubitBoolean preview)
{
if (!okay_to_modify( webcut_body_list, "WEBCUT" ))
return CUBIT_FAILURE;
@@ -1940,18 +2766,26 @@
DLIList<BodySM*> result_sm_list, webcut_sm_list(bridge_list.size());
CAST_LIST(bridge_list, webcut_sm_list, BodySM);
- do_attribute_setup();
- push_vg_attributes_before_modify(webcut_sm_list);
+ if (!preview)
+ {
+ do_attribute_setup();
+ push_vg_attributes_before_modify(webcut_sm_list);
+ }
+ DLIList<BodySM*> neighbor_list;
CubitStatus result_val = gme->webcut_across_translate (
- webcut_sm_list, surface_top, surface_bottom, result_sm_list, imprint );
+ webcut_sm_list, surface_top, surface_bottom, result_sm_list, neighbor_list, imprint_type, preview );
- restore_vg_after_modify(result_sm_list, original_body_list);
+ // if we're doing the real thing (not preview) finish the process
+ if (!preview)
+ {
+ restore_vg_after_modify(result_sm_list, original_body_list, gme);
+ remove_pushed_attributes(result_sm_list, original_body_list);
+ result_val = finish_webcut( webcut_body_list, result_sm_list, merge,
+ result_val, results_list);
+ do_attribute_cleanup();
+ }
- result_val = finish_webcut( webcut_body_list, result_sm_list, merge,
- result_val, results_list);
- do_attribute_cleanup();
-
return result_val;
}
#endif
@@ -1970,14 +2804,16 @@
DLIList<Body*>& webcut_body_list,
DLIList<RefEdge*>& refedge_list,
DLIList<Body*>& results_list,
- CubitBoolean imprint)
+ DLIList<Body*> &neighboring_bodies,
+ ImprintType imprint_type,
+ CubitBoolean merge,
+ CubitBoolean preview)
{
if (!okay_to_modify( webcut_body_list, "WEBCUT" ))
return CUBIT_FAILURE;
int i;
- DLIList<Body*> original_body_list = webcut_body_list;
const int count = webcut_body_list.size() + refedge_list.size();
DLIList<TopologyEntity*> entity_list(count);
DLIList<TopologyBridge*> bridge_list(count);
@@ -1995,25 +2831,76 @@
return CUBIT_FAILURE;
}
- DLIList<BodySM*> webcut_sm_list(webcut_body_list.size()), result_sm_list;
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ DLIList<Body*> bodies_to_save;
+ bodies_to_save += webcut_body_list;
+ bodies_to_save += neighboring_bodies;
+ CubitUndo::save_state_with_cubit_file( bodies_to_save );
+ }
+
+ DLIList<BodySM*> body_sm_list(webcut_body_list.size()), result_sm_list;
DLIList<Curve*> curve_list(refedge_list.size());
- CAST_LIST(bridge_list, webcut_sm_list, BodySM);
+ CAST_LIST(bridge_list, body_sm_list, BodySM);
CAST_LIST(bridge_list, curve_list, Curve);
- assert(webcut_sm_list.size() == webcut_body_list.size());
+ assert(body_sm_list.size() == webcut_body_list.size());
assert(curve_list.size() == refedge_list.size());
- do_attribute_setup();
- push_vg_attributes_before_modify(webcut_sm_list);
+ DLIList<int> merged_surface_ids;
+ DLIList<int> merged_curve_ids;
+ DLIList<BodySM*> neighbor_imprint_list;
+ DLIList<Body*> bodies_to_modify;
+ if (!preview)
+ {
+ int i;
+ for( i=neighboring_bodies.size(); i--; )
+ {
+ Body *neighbor_body = neighboring_bodies.get_and_step();
+ BodySM *tmp_body = neighbor_body->get_body_sm_ptr();
+ GeometryModifyEngine *neighbor_gme = get_engine( tmp_body );
+
+ if( gme == neighbor_gme )
+ neighbor_imprint_list.append( tmp_body );
+ }
+
+ do_attribute_setup();
+ DLIList<BodySM*> bodies_sm_to_modify;
+ bodies_sm_to_modify += body_sm_list;
+ bodies_sm_to_modify += neighbor_imprint_list;
+ push_vg_attributes_before_modify( bodies_sm_to_modify );
+ bodies_to_modify += webcut_body_list;
+ bodies_to_modify += neighboring_bodies;
+ get_merged_curve_and_surface_ids( bodies_to_modify, merged_surface_ids, merged_curve_ids );
+ }
+
+
CubitStatus result_val = gme->webcut_with_curve_loop(
- webcut_sm_list, curve_list, result_sm_list, imprint) ;
+ body_sm_list, curve_list,
+ neighbor_imprint_list,
+ result_sm_list,
+ imprint_type, preview) ;
- restore_vg_after_modify(result_sm_list, original_body_list);
+ // finish up if we're doing the real thing
+ if (!preview)
+ {
+ restore_vg_after_modify(result_sm_list, bodies_to_modify, gme);
+ remove_pushed_attributes(result_sm_list, bodies_to_modify);
- result_val = finish_webcut( webcut_body_list, result_sm_list, CUBIT_FALSE,
- result_val, results_list );
- do_attribute_cleanup();
+ result_val = finish_webcut( webcut_body_list, result_sm_list, merge,
+ result_val, results_list,
+ &merged_surface_ids, &merged_curve_ids );
+ do_attribute_cleanup();
+ }
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ if( result_val == CUBIT_SUCCESS )
+ CubitUndo::note_result_bodies( results_list );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
return result_val;
}
@@ -2033,8 +2920,10 @@
DLIList<Body*>& webcut_body_list,
RefFace* refFace,
DLIList<Body*>& results_list,
- CubitBoolean imprint,
- CubitBoolean merge)
+ DLIList<Body*> &neighboring_bodies,
+ ImprintType imprint_type,
+ CubitBoolean merge,
+ CubitBoolean preview)
{
//make sure that this refface is planar, or you'll get unexpected results
if( refFace->geometry_type() != PLANE_SURFACE_TYPE )
@@ -2051,7 +2940,8 @@
CubitVector vector2 = refFace->position_from_u_v(0, 0) ;
CubitStatus result_val = this->webcut_with_plane(webcut_body_list, vector1,
- vector2, vector3, results_list, imprint, merge) ;
+ vector2, vector3, results_list, neighboring_bodies,
+ imprint_type, merge, preview) ;
return result_val;
}
@@ -2072,16 +2962,17 @@
DLIList<Body*>& webcut_body_list,
Body* tool_body,
DLIList<Body*>& results_list,
- CubitBoolean imprint,
- CubitBoolean merge)
+ DLIList<Body*> &neighboring_bodies,
+ ImprintType imprint_type,
+ CubitBoolean merge,
+ CubitBoolean preview)
{
+
+ CubitStatus ret;
+
if (!okay_to_modify( webcut_body_list, "WEBCUT" ))
return CUBIT_FAILURE;
- if( tool_body->is_sheet_body() )
- return webcut_with_sheet( webcut_body_list, tool_body, results_list, imprint );
-
- DLIList<Body*> original_body_list = webcut_body_list;
DLIList<BodySM*> body_sm_list(webcut_body_list.size()), result_sm_list;
BodySM* tool_sm = tool_body->get_body_sm_ptr();
GeometryModifyEngine* gme = 0;
@@ -2093,7 +2984,8 @@
}
webcut_body_list.reset();
- for (int i = webcut_body_list.size(); i--; )
+ int i;
+ for (i = webcut_body_list.size(); i--; )
{
Body* body_ptr = webcut_body_list.get_and_step();
BodySM* sm_ptr = body_ptr->get_body_sm_ptr();
@@ -2109,20 +3001,70 @@
body_sm_list.append(sm_ptr);
}
- do_attribute_setup();
+ DLIList<int> merged_surface_ids;
+ DLIList<int> merged_curve_ids;
+ DLIList<BodySM*> neighbor_imprint_list;
+ DLIList<Body*> bodies_to_modify;
- push_vg_attributes_before_modify(body_sm_list);
+ if (!preview)
+ {
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ DLIList<Body*> bodies_to_save;
+ bodies_to_save += webcut_body_list;
+ bodies_to_save += neighboring_bodies;
+ CubitUndo::save_state_with_cubit_file( bodies_to_save );
+ }
- int count = gme->webcut(body_sm_list, tool_sm, result_sm_list, imprint);
+ int i;
+ for( i=neighboring_bodies.size(); i--; )
+ {
+ Body *neighbor_body = neighboring_bodies.get_and_step();
+ BodySM *tmp_body = neighbor_body->get_body_sm_ptr();
+ GeometryModifyEngine *neighbor_gme = get_engine( tmp_body );
+
+ if( gme == neighbor_gme )
+ neighbor_imprint_list.append( tmp_body );
+ }
- restore_vg_after_modify(result_sm_list, original_body_list);
+ do_attribute_setup();
+ DLIList<BodySM*> bodies_sm_to_modify;
+ bodies_sm_to_modify += body_sm_list;
+ bodies_sm_to_modify += neighbor_imprint_list;
+ push_vg_attributes_before_modify( bodies_sm_to_modify );
+ bodies_to_modify += webcut_body_list;
+ bodies_to_modify += neighboring_bodies;
+ get_merged_curve_and_surface_ids( bodies_to_modify, merged_surface_ids, merged_curve_ids );
+ }
- CubitStatus ret = finish_webcut(webcut_body_list, result_sm_list, merge,
- count > 0 ? CUBIT_SUCCESS : CUBIT_FAILURE,
- results_list);
- do_attribute_cleanup();
+ int count = gme->webcut(body_sm_list, tool_sm,
+ neighbor_imprint_list,
+ result_sm_list, imprint_type, preview);
+ // finish up if we're doing the real thing
+ if (!preview)
+ {
+ restore_vg_after_modify(result_sm_list, bodies_to_modify, gme);
+ remove_pushed_attributes(result_sm_list, bodies_to_modify );
+
+ ret = finish_webcut(webcut_body_list, result_sm_list, merge,
+ count > 0 ? CUBIT_SUCCESS : CUBIT_FAILURE,
+ results_list, &merged_surface_ids, &merged_curve_ids );
+
+ do_attribute_cleanup();
+ }
+ else
+ ret = count > 0 ? CUBIT_SUCCESS : CUBIT_FAILURE;
+
+ if( preview == CUBIT_FALSE && CubitUndo::get_undo_enabled() )
+ {
+ if( ret == CUBIT_SUCCESS )
+ CubitUndo::note_result_bodies( results_list );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
return ret;
}
@@ -2145,22 +3087,48 @@
DLIList<BodySM*> engine_body_sms(count);
DLIList<Body*> engine_bodies(count);
GeometryModifyEngine* gme = 0;
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( keep_old )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( section_body_list );
+ }
+
while ( (gme = group_bodies_by_engine(body_list, engine_bodies, engine_body_sms)) )
{
+ //get all the child entities that have been merged
+ DLIList<int> merged_surface_ids;
+ DLIList<int> merged_curve_ids;
+ get_merged_curve_and_surface_ids( engine_bodies, merged_surface_ids, merged_curve_ids );
+
CubitStatus result = gme->section( engine_body_sms,
point_1, point_2, point_3,
result_sm_list,
keep_normal_side, keep_old );
+
if (!finish_sm_op( engine_bodies, result_sm_list, new_body_list ))
result = CUBIT_FAILURE;
if (!result)
rval = CUBIT_FAILURE;
+ if( merged_surface_ids.size() || merged_curve_ids.size() )
+ fixup_merged_entities( merged_surface_ids, merged_curve_ids);
+
engine_body_sms.clean_out();
engine_bodies.clean_out();
result_sm_list.clean_out();
}
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( new_body_list.size() ) //if there are new bodies...something succeeded
+ CubitUndo::note_result_bodies( new_body_list );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
return rval;
}
@@ -2182,6 +3150,9 @@
return CUBIT_FAILURE;
}
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state();
+
DLIList<Curve*> curve_list(bridge_list.size()), result_list;
CAST_LIST(bridge_list, curve_list, Curve);
assert(curve_list.size() == ref_edge_list.size());
@@ -2190,9 +3161,22 @@
offset_distance, offset_direction, gap_type );
assert( rval || !result_list.size() );
result_list.reset();
+
+ DLIList<RefEntity*> created_edges;
for (int i = result_list.size(); i--; )
- GeometryQueryTool::instance()->make_free_RefEdge(result_list.get_and_step());
+ {
+ RefEdge *new_edge = GeometryQueryTool::instance()->make_free_RefEdge(result_list.get_and_step());
+ created_edges.append( new_edge );
+ }
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( created_edges.size() )
+ CubitUndo::note_result_entities( created_edges );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
return rval;
}
@@ -2248,6 +3232,13 @@
CubitVector my_vector = my_face->normal_at( my_center, ref_vol );
CubitVector target_vector = target_face->normal_at( target_center );
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<Body*> align_list(1);
+ align_list.append( body_ptr );
+ CubitUndo::save_state_with_cubit_file( align_list );
+ }
+
axis = my_vector * target_vector;
//Move the body so that the center of my_face
//is at the origin.
@@ -2261,6 +3252,11 @@
//Now we have the angle and the axis to rotate about...
angle = 180.0*angle/CUBIT_PI;
+
+ //if the angle is greater 180, we want the normals pointing
+ //into one another, not in the same direction
+ if( angle > 90 )
+ angle = angle - 180;
//Now rotate the body about the axis.
GeometryQueryTool::instance()->rotate( body_ptr, axis, angle );
@@ -2331,6 +3327,13 @@
return CUBIT_FAILURE;
}
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<Body*> align_list(1);
+ align_list.append( body_ptr );
+ CubitUndo::save_state_with_cubit_file( align_list );
+ }
+
//translate body so surface's centroid is at 0,0,0
GeometryQueryTool::instance()->translate( body_ptr, -my_center_1 );
@@ -2355,6 +3358,13 @@
GeometryQueryTool::instance()->rotate( body_ptr, second_vector, angle );
}
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<Body*> align_list(1);
+ align_list.append( body_ptr );
+ CubitUndo::save_state_with_cubit_file( align_list );
+ }
+
//translate body back
GeometryQueryTool::instance()->translate( body_ptr, my_center_1 );
@@ -2409,6 +3419,13 @@
CubitVector target_vector = first_vector;
axis_of_rot = my_vector * target_vector;
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<Body*> align_list(1);
+ align_list.append( body_ptr );
+ CubitUndo::save_state_with_cubit_file( align_list );
+ }
+
//Move the body so that the center of the vertex
//is at the origin.
GeometryQueryTool::instance()->translate( body_ptr, -my_center_1 );
@@ -2465,7 +3482,10 @@
"to remain in the positive plane\n",body_ptr->id());
if ( flip_result == CUBIT_FAILURE )
{
- return CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
+
+ return CUBIT_FAILURE;
}
}
}
@@ -2605,6 +3625,7 @@
const char* const,
DLIList<Body*>& input_body_list,
DLIList<BodySM*>& new_body_list,
+ DLIList<Body*>& output_body_list,
CubitBoolean changed_new_ids )
{
int i;
@@ -2620,6 +3641,7 @@
{
regen_list.append_unique(bodysm);
remove_dead_entity_names(body);
+ output_body_list.append( body );
}
else
{
@@ -2633,6 +3655,7 @@
{
BodySM* bodysm = regen_list.get_and_step();
Body* body = gqt->make_Body(bodysm);
+ output_body_list.append( body );
PRINT_INFO("%s volume %d\n",
new_body_list.is_in_list(bodysm) ? "Created swept" : "Updated",
body->ref_volume()->id());
@@ -2668,22 +3691,46 @@
change_newids, geom_list))
return CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled())
+ {
+ DLIList<RefEdge*> edge_list;
+ DLIList<RefFace*> face_list;
+
+ CAST_LIST( ref_ent_list, edge_list, RefEdge );
+ CAST_LIST( ref_ent_list, face_list, RefFace );
+
+ //Edges aren't consumed, so there's nothing to save out
+ if( edge_list.size() )
+ CubitUndo::save_state();
+ else
+ //Faces will get consumed so you have to save out original entities
+ CubitUndo::save_state_with_cubit_file( face_list );
+ }
+
DLIList<BodySM*> result_list;
- CubitStatus status = gePtr1-> sweep_rotational( geom_list,
- result_list,
- point,
- sweep_axis,
- angle,
- steps,
- draft_angle,
- draft_type,
- switchside,
- make_solid,
- rigid);
-
- if (!sweep_finish("rotational", body_list, result_list, change_newids))
+ CubitStatus status = gePtr1->sweep_rotational( geom_list,
+ result_list,
+ point,
+ sweep_axis,
+ angle,
+ steps,
+ draft_angle,
+ draft_type,
+ switchside,
+ make_solid,
+ rigid);
+ DLIList<Body*> output_body_list;
+ if (!sweep_finish("rotational", body_list, result_list, output_body_list, change_newids))
status = CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled())
+ {
+ if( status == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+ else
+ CubitUndo::note_result_bodies( output_body_list );
+ }
+
return status;
}
@@ -2703,6 +3750,22 @@
change_newids, geom_list))
return CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled())
+ {
+ DLIList<RefEdge*> edge_list;
+ DLIList<RefFace*> face_list;
+
+ CAST_LIST( ref_ent_list, edge_list, RefEdge );
+ CAST_LIST( ref_ent_list, face_list, RefFace );
+
+ //Edges aren't consumed, so there's nothing to save out
+ if( edge_list.size() )
+ CubitUndo::save_state();
+ else
+ //Faces will get consumed so you have to save out original entities
+ CubitUndo::save_state_with_cubit_file( face_list );
+ }
+
DLIList<BodySM*> result_list;
CubitStatus status = gePtr1->
sweep_translational( geom_list,
@@ -2713,14 +3776,25 @@
switchside,
rigid);
- if (!sweep_finish("translational", body_list, result_list, change_newids))
+ DLIList<Body*> output_body_list;
+ if (!sweep_finish("translational", body_list, result_list, output_body_list, change_newids))
status = CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled())
+ {
+ if( status == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+ else
+ CubitUndo::note_result_bodies( output_body_list );
+ }
+
return status;
}
-CubitStatus GeometryModifyTool::sweep_target(CubitPlane ref_plane,
- DLIList<RefEntity*>& ref_ent_list)
+//Author:: Jonathan Bugman
+//Sept 10, 2006
+CubitStatus GeometryModifyTool::sweep_curve_target(CubitPlane ref_plane,
+ DLIList<RefEntity*>& ref_ent_list)
{
double distance1;
double distance2;
@@ -2733,7 +3807,7 @@
CubitVector end_point;
CubitVector target_end_point;
DLIList<RefEdge*> edge_list;
- CAST_LIST(ref_ent_list, edge_list, RefEdge);
+ CAST_LIST(ref_ent_list, edge_list, RefEdge);
CubitVector result;
double max_distance_for_edge=0;
CubitVector max_result;
@@ -2808,7 +3882,6 @@
{
Curve *facet_curve;
facet_curve=edge_list[ii]->get_curve_ptr();
- int num_points;
int color = 2;
CubitStatus response;
GMem g_mem;
@@ -2816,7 +3889,8 @@
//get number of points and their locations
//on the curve as defined by the drawing geometry algorithm
response = facet_curve->get_geometry_query_engine()->
- get_graphics( facet_curve, num_points, &g_mem );
+ get_graphics( facet_curve, &g_mem );
+ int num_points = g_mem.pointListCount;
if (response==CUBIT_FAILURE || num_points == 0)
{
@@ -2903,25 +3977,24 @@
vec2=vec2+target_mid_point;
vec3=vec3+target_mid_point;
+ DLIList<BodySM*> neighbor_imprint_list;
//do a webcut with a plane created from the three projected points above
CubitStatus status2 = gePtr1->webcut(sweep_result_list,target_mid_point,
- vec2,vec3,webcut_results_list);
+ vec2,vec3, neighbor_imprint_list, webcut_results_list);
if (status2 == 0)
{
PRINT_ERROR( "Sweep operation worked; however, webcut operation failed.\n" );
//delete memory since it failed
gePtr1->get_gqe()->delete_solid_model_entities(sweep_result_list);
- gePtr1->get_gqe()->delete_solid_model_entities(webcut_results_list);
return CUBIT_FAILURE;
}
- if (webcut_results_list.size()<=0)
+ if (webcut_results_list.size()==0)
{
PRINT_ERROR( "Number of bodies from webcut is zero, unable to perform rest of sweep operation\n" );
//delete memory since it failed
gePtr1->get_gqe()->delete_solid_model_entities(sweep_result_list);
- gePtr1->get_gqe()->delete_solid_model_entities(webcut_results_list);
return CUBIT_FAILURE;
}
@@ -2975,12 +4048,24 @@
//delete webcut_results_list memory
gePtr1->get_gqe()->delete_solid_model_entities(webcut_results_list);
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state();
+
//builds ref bodies
- if (!sweep_finish("translational", body_list, keep_bodies_list, change_newids))
+ DLIList<Body*> output_body_list;
+ if (!sweep_finish("translational", body_list, keep_bodies_list, output_body_list, change_newids))
{
gePtr1->get_gqe()->delete_solid_model_entities(keep_bodies_list);
status = CUBIT_FAILURE;
}
+
+ if( CubitUndo::get_undo_enabled())
+ {
+ if( status == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+ else
+ CubitUndo::note_result_bodies( output_body_list );
+ }
}
else
{
@@ -2988,11 +4073,225 @@
return CUBIT_FAILURE;
}
- return CUBIT_SUCCESS;
+ return CUBIT_SUCCESS;
}
+// Author: Derek Quam
+// Dec. 1, 2008
+CubitStatus GeometryModifyTool::sweep_surface_target(RefFace *face,
+ Body *target_body,
+ CubitVector distance,
+ CubitPlane stop_plane,
+ double magnitude)
+{
+ // Declare local variables
+ Surface *source_surf;
+ bool set_dist = true, set_plane = true, set_mag = true;
+ CubitVector direction;
+ CubitStatus status;
+ DLIList<Body*> body_list;
+ DLIList<GeometryEntity*> geom_list;
+ GeometryModifyEngine* gePtr1 = 0;
+ CubitBoolean change_newids;
+ DLIList<RefEntity*> ref_ent_list;
+ ref_ent_list.append(face);
+ // Check to make sure the target body is a solid
+ if (target_body->is_sheet_body())
+ {
+ PRINT_ERROR("Target body must be a solid body.\n");
+ return CUBIT_FAILURE;
+ }
+
+ // Set up the sweep
+ if (!sweep_setup("target", ref_ent_list, body_list, gePtr1, change_newids, geom_list))
+ return CUBIT_FAILURE;
+
+ // Get the Surface * from the RefFace *
+ source_surf = face->get_surface_ptr();
+
+ // Check if the direction vector and stop plane were specified
+ if (distance.length() < 0.0001)
+ set_dist = false;
+ if (stop_plane.normal().length() < 0.0001)
+ set_plane = false;
+ if (magnitude < 0.0001)
+ set_mag = false;
+
+ // Calculate the direction of the sweep
+ if (!set_dist)
+ direction = face->normal_at(face->center_point());
+ else
+ direction = distance;
+ direction.normalize();
+
+ double length = 0.0;
+ if (!set_mag && !set_plane)
+ {
+ CubitVector center_body = target_body->center_point();
+ CubitVector center_face = face->center_point();
+ length = center_face.distance_between(center_body);
+ }
+ else if (set_plane)
+ {
+ length = stop_plane.intersect(face->center_point(), direction).distance_between(face->center_point());
+ }
+ else
+ {
+ length = magnitude;
+ }
+ if (set_mag && length > magnitude)
+ length = magnitude;
+ direction *= length;
+
+ DLIList<BodySM*> new_bodies;
+ status = gePtr1->sweep_to_body(source_surf, target_body->get_body_sm_ptr(), direction, new_bodies);
+
+ if (status != CUBIT_SUCCESS)
+ return status;
+
+ // Make all the new bodies
+ DLIList<Body*> output_body_list;
+ if (!sweep_finish("target", body_list, new_bodies, output_body_list, change_newids))
+ status = CUBIT_FAILURE;
+
+
+ /*
+ for (int i = 0; i < new_bodies.size(); i++)
+ GeometryQueryTool::instance()->make_Body(new_bodies.get_and_step());
+ */
+
+
+ return CUBIT_SUCCESS;
+}
+
+// Author: Andrew Rout and Derek Quam
+// Nov. 14, 2008
+CubitStatus GeometryModifyTool::sweep_curve_target(DLIList<RefEdge*>& edge_list,
+ Body *target_body,
+ DLIList<Body*> &out_bodies,
+ CubitVector distance,
+ CubitPlane stop_plane,
+ bool unite)
+{
+ DLIList<BodySM*> new_bodies;
+ DLIList<Curve*> curve_list;
+ bool set_dist = true, set_plane = true;
+ double larDist = 1.0;
+ CubitVector dir = distance;
+ CubitStatus status;
+
+ // Check to make sure the target body is a sheetbody
+ if (!target_body->is_sheet_body())
+ {
+ PRINT_ERROR("Target body must be a sheet body.\n");
+ return CUBIT_FAILURE;
+ }
+
+ // Get the Curve *'s from the RefEdge *'s
+ for (int i = 0; i < edge_list.size(); i++)
+ {
+ edge_list[i]->get_curve_ptr()->set_saved_id(edge_list[i]->id());
+ curve_list.append(edge_list[i]->get_curve_ptr());
+ }
+ // Check if the direction vector and stop plane were specified
+ if (distance.length() < 0.0001)
+ set_dist = false;
+ if (stop_plane.normal().length() < 0.0001)
+ set_plane = false;
+
+ // Check inputs
+ if (!set_plane && !set_dist)
+ {
+ PRINT_ERROR("User must specify a stop plane, a direction, or both.\n");
+ return CUBIT_FAILURE;
+ }
+
+ // Calculate the direction vector
+ double begDist, midDist, endDist;
+ for (int i = 0; i < edge_list.size(); i++)
+ {
+ CubitVector beg, mid, end, begP, midP, endP;
+ RefEdge *temp = edge_list.get_and_step();
+
+ // Retrieve the beginning, middle, and end coordinates of the edge
+ beg = temp->start_coordinates();
+ temp->mid_point(mid);
+ end = temp->end_coordinates();
+
+ if (set_plane)
+ {
+ // Project the start, mid, and end point onto the stop plane
+ begP = stop_plane.project(beg);
+ midP = stop_plane.project(mid);
+ endP = stop_plane.project(end);
+
+ // Calculate the distance between the points
+ begDist = beg.distance_between(begP);
+ midDist = mid.distance_between(midP);
+ endDist = end.distance_between(endP);
+ }
+ else // No stop plane specified
+ {
+ begDist = beg.distance_between(target_body->center_point());
+ midDist = mid.distance_between(target_body->center_point());
+ endDist = end.distance_between(target_body->center_point());
+ }
+
+ // Find the largest distance
+ if (begDist > larDist)
+ larDist = begDist;
+ if (midDist > larDist)
+ larDist = midDist;
+ if (endDist > larDist)
+ larDist = endDist;
+
+ // Make sure the plane normal is pointing the right way
+ if (set_plane)
+ {
+ double planeNorm = stop_plane.normal().interior_angle(beg-begP);
+ if (planeNorm <= 90 || planeNorm >= 270)
+ stop_plane.reverse();
+ }
+
+ if (!set_dist)
+ dir += (midP-mid);
+
+ } // End for loop
+ if (!set_dist)
+ dir /= edge_list.size();
+
+ // Unitize the direction vector
+ dir /= dir.length();
+
+ // Add the magnitude to the direction vector and check for intersection with the stop plane
+ dir *= larDist;
+ if (set_plane)
+ {
+ double angle = dir.interior_angle(stop_plane.normal());
+ if (angle >= 90 && angle <= 270)
+ PRINT_WARNING("Direction vector does not intersect stop plane!\n");
+ }
+
+ // Call the geometry function
+ status = get_gme()->sweep_to_body(curve_list, target_body->get_body_sm_ptr(), dir, new_bodies, unite);
+
+ if (status != CUBIT_SUCCESS)
+ return CUBIT_FAILURE;
+
+ // Make all the new bodies
+ for (int i = 0; i < new_bodies.size(); i++)
+ {
+ out_bodies.append(GeometryQueryTool::instance()->make_Body(new_bodies.get_and_step()));
+ PRINT_INFO("Created volume in body %d\n", out_bodies[i]->id());
+ }
+
+ return CUBIT_SUCCESS;
+}
+
+//Author: Jonathan Bugman
+//Sept 10, 2006
CubitStatus GeometryModifyTool::sweep_surface_target(CubitPlane ref_plane,
- DLIList<RefEntity*>& ref_ent_list)
+ DLIList<RefEntity*>& ref_ent_list)
{
DLIList<RefFace*> surface_list;
CAST_LIST(ref_ent_list, surface_list, RefFace);
@@ -3014,7 +4313,7 @@
//make sure that only one surface has been selected
if(surface_list.size() == 0)
{
- PRINT_ERROR( "No edge(s) found - sweep surface to target failed.\n" );
+ PRINT_ERROR( "No surface found - sweep surface to target failed.\n" );
return CUBIT_FAILURE;
}
@@ -3037,7 +4336,7 @@
//get midpoint of edge on surface
surf_edge_list[j]->mid_point(get_mid_point);
//Project the midpoint of each surface edge onto the specified plane
- target_mid_point = ref_plane.project(get_mid_point);
+ target_mid_point = ref_plane.project(get_mid_point);
//Calculate the distance between the mid_point, and target_point
distance1 = target_mid_point.distance_between(get_mid_point);
@@ -3114,7 +4413,6 @@
{
Curve *facet_curve;
facet_curve=surf_edge_list[ii]->get_curve_ptr();
- int num_points;
int color = 2;
CubitStatus response;
GMem g_mem;
@@ -3122,8 +4420,10 @@
//get number of points and their locations
//on the curve as defined by the drawing geometry algorithm
response = facet_curve->get_geometry_query_engine()->
- get_graphics( facet_curve, num_points, &g_mem );
+ get_graphics( facet_curve, &g_mem );
+ int num_points = g_mem.pointListCount;
+
if (response==CUBIT_FAILURE || num_points == 0)
{
PRINT_WARNING("Unable to preview a curve\n" );
@@ -3182,6 +4482,10 @@
change_newids, geom_list))
return CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled())
+ //Faces will get consumed so you have to save out original entities
+ CubitUndo::save_state_with_cubit_file( surface_list );
+
DLIList<BodySM*> sweep_result_list;
//below block is default settings to be fed into sweep_translational
@@ -3214,12 +4518,16 @@
//print an error to the screen for the user
gePtr1->get_gqe()->delete_solid_model_entities(sweep_result_list);
PRINT_ERROR( "Error occured in the sweep operation.\n" );
+
+ if( CubitUndo::get_undo_enabled())
+ CubitUndo::remove_last_undo();
return CUBIT_FAILURE;
}
+ DLIList<BodySM*> neighbor_imprint_list;
//do a webcut with a plane created from the three projected points
CubitStatus status2 = gePtr1->webcut(sweep_result_list,target_mid_point,
- vec2,vec3,webcut_results_list);
+ vec2,vec3,neighbor_imprint_list, webcut_results_list);
if (status2 == 0)
{
@@ -3228,6 +4536,9 @@
gePtr1->get_gqe()->delete_solid_model_entities(sweep_result_list);
gePtr1->get_gqe()->delete_solid_model_entities(webcut_results_list);
PRINT_ERROR( "Error occured in the webcut operation.\n" );
+
+ if( CubitUndo::get_undo_enabled())
+ CubitUndo::remove_last_undo();
return CUBIT_FAILURE;
}
@@ -3244,7 +4555,7 @@
CubitVector vec_1 = mid_point_surface - target_mid_point_surface;
vec_1.normalize();
- //step through the
+ //step through the
for (int counter=0;counter<webcut_results_list.size();counter++)
{
//find the geometric midpoint of the body and project that point on the target plane
@@ -3272,6 +4583,9 @@
PRINT_ERROR( "All sweeped surfaces deleted - sweep_target failed.\n" );
PRINT_ERROR( "This may be due to granite engine limitations and/or\n" );
PRINT_ERROR( "angle between curve and target surface\n" );
+
+ if( CubitUndo::get_undo_enabled())
+ CubitUndo::remove_last_undo();
return CUBIT_FAILURE;
}
@@ -3280,9 +4594,18 @@
gePtr1->get_gqe()->delete_solid_model_entities(webcut_results_list);
//builds ref bodies
- if (!sweep_finish("translational", body_list, keep_bodies_list, change_newids))
+ DLIList<Body*> output_body_list;
+ if (!sweep_finish("translational", body_list, keep_bodies_list, output_body_list, change_newids))
status = CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled())
+ {
+ if( status == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+ else
+ CubitUndo::note_result_bodies( output_body_list );
+ }
+
}
return CUBIT_SUCCESS;
}
@@ -3303,6 +4626,22 @@
change_newids, geom_list))
return CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled())
+ {
+ DLIList<RefEdge*> edge_list;
+ DLIList<RefFace*> face_list;
+
+ CAST_LIST( ref_ent_list, edge_list, RefEdge );
+ CAST_LIST( ref_ent_list, face_list, RefFace );
+
+ //Edges aren't consumed, so there's nothing to save out
+ if( edge_list.size() )
+ CubitUndo::save_state();
+ else
+ //Faces will get consumed so you have to save out original entities
+ CubitUndo::save_state_with_cubit_file( face_list );
+ }
+
DLIList<BodySM*> result_list;
CubitStatus status = gePtr1->
sweep_perpendicular( geom_list,
@@ -3313,9 +4652,18 @@
switchside,
rigid);
- if (!sweep_finish("perpendicular", body_list, result_list, change_newids))
+ DLIList<Body*> output_body_list;
+ if (!sweep_finish("perpendicular", body_list, result_list, output_body_list, change_newids))
status = CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled())
+ {
+ if( status == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+ else
+ CubitUndo::note_result_bodies( output_body_list );
+ }
+
return status;
}
CubitStatus GeometryModifyTool::sweep_along_curve(DLIList<RefEntity*>& ref_ent_list,
@@ -3325,38 +4673,61 @@
CubitBoolean rigid)
{
- DLIList<GeometryEntity*> geom_list(ref_ent_list.size());
- DLIList<Curve*> curve_list(ref_edge_list.size());
- DLIList<Body*> body_list(ref_ent_list.size());
- GeometryModifyEngine* engine_ptr = 0;
- CubitBoolean changed_new_ids = CUBIT_FALSE;
- CubitStatus status = sweep_setup( "along_curve",
- ref_ent_list,
- body_list,
- engine_ptr,
- changed_new_ids,
- geom_list,
- &ref_edge_list,
- &curve_list );
- if (status != CUBIT_SUCCESS)
- return status;
+ DLIList<GeometryEntity*> geom_list(ref_ent_list.size());
+ DLIList<Curve*> curve_list(ref_edge_list.size());
+ DLIList<Body*> body_list(ref_ent_list.size());
+ GeometryModifyEngine* engine_ptr = 0;
+ CubitBoolean changed_new_ids = CUBIT_FALSE;
+ CubitStatus status = sweep_setup( "along_curve",
+ ref_ent_list,
+ body_list,
+ engine_ptr,
+ changed_new_ids,
+ geom_list,
+ &ref_edge_list,
+ &curve_list );
+ if (status != CUBIT_SUCCESS)
+ return status;
+ if( CubitUndo::get_undo_enabled())
+ {
+ DLIList<RefEdge*> edge_list;
+ DLIList<RefFace*> face_list;
+ CAST_LIST( ref_ent_list, edge_list, RefEdge );
+ CAST_LIST( ref_ent_list, face_list, RefFace );
- DLIList<BodySM*> result_list;
- status = engine_ptr->sweep_along_curve( geom_list,
- result_list,
- curve_list,
- draft_angle,
- draft_type,
- rigid);
+ //Edges aren't consumed, so there's nothing to save out
+ if( edge_list.size() )
+ CubitUndo::save_state();
+ else
+ //Faces will get consumed so you have to save out original entities
+ CubitUndo::save_state_with_cubit_file( face_list );
+ }
- if (!sweep_finish("along_curve", body_list, result_list, changed_new_ids))
- status = CUBIT_FAILURE;
+ DLIList<BodySM*> result_list;
+ status = engine_ptr->sweep_along_curve( geom_list,
+ result_list,
+ curve_list,
+ draft_angle,
+ draft_type,
+ rigid);
- return status;
+ DLIList<Body*> output_body_list;
+ if (!sweep_finish("along_curve", body_list, result_list, output_body_list, changed_new_ids))
+ status = CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled())
+ {
+ if( status == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+ else
+ CubitUndo::note_result_bodies( output_body_list );
+ }
+
+ return status;
}
+
void GeometryModifyTool::initialize_settings() {
@@ -3380,6 +4751,13 @@
GeometryModifyTool::set_old_names,
GeometryModifyTool::get_old_names);
+ SettingHandler::instance()->add_setting("Mesh Auto Delete",
+ GeometryModifyTool::set_mesh_autodelete,
+ GeometryModifyTool::get_mesh_autodelete);
+
+ SettingHandler::instance()->add_setting("Mesh Auto Delete Cache",
+ GeometryModifyTool::set_mesh_autodelete_remesh,
+ GeometryModifyTool::is_mesh_autodelete_remesh);
}
@@ -3420,8 +4798,10 @@
const CubitVector axes[3],
const CubitVector &extension,
DLIList<Body*> &results_list,
- CubitBoolean imprint,
- CubitBoolean merge )
+ DLIList<Body*> &neighboring_bodies,
+ ImprintType imprint_type,
+ CubitBoolean merge,
+ CubitBoolean preview)
{
// Make sure that entity creation is possible. Allow at most
// only one of the dimensions to be zero - in which case a planar
@@ -3472,12 +4852,21 @@
}
return webcut_with_planar_sheet (webcut_body_list, center, sheet_axes,
- width, height, results_list, imprint, merge);
+ width, height, results_list, neighboring_bodies,
+ imprint_type, merge, preview);
}
if (!okay_to_modify( webcut_body_list, "WEBCUT" ))
- return CUBIT_FAILURE;
+ return CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<Body*> bodies_to_save;
+ bodies_to_save += webcut_body_list;
+ bodies_to_save += neighboring_bodies;
+ CubitUndo::save_state_with_cubit_file( bodies_to_save );
+ }
+
CubitStatus rval = CUBIT_SUCCESS;
const int count = webcut_body_list.size();
@@ -3487,18 +4876,53 @@
DLIList<Body*> engine_bodies(count);
GeometryModifyEngine* gme = 0;
- do_attribute_setup();
-
while ( (gme = group_bodies_by_engine(body_list, engine_bodies, engine_body_sms)) )
{
- push_vg_attributes_before_modify(engine_body_sms);
+ DLIList<int> merged_surface_ids;
+ DLIList<int> merged_curve_ids;
+ DLIList<BodySM*> neighbor_imprint_list;
+ if (!preview)
+ {
+ int i;
+ for( i=neighboring_bodies.size(); i--; )
+ {
+ Body *neighbor_body = neighboring_bodies.get_and_step();
+ BodySM *tmp_body = neighbor_body->get_body_sm_ptr();
+ GeometryModifyEngine *neighbor_gme = get_engine( tmp_body );
+
+ if( gme == neighbor_gme )
+ {
+ neighbor_imprint_list.append( tmp_body );
+ engine_bodies.append( neighbor_body );
+ }
+ }
+ do_attribute_setup();
+ DLIList<BodySM*> bodies_to_modify;
+ bodies_to_modify += engine_body_sms;
+ bodies_to_modify += neighbor_imprint_list;
+ push_vg_attributes_before_modify( bodies_to_modify );
+ get_merged_curve_and_surface_ids( engine_bodies, merged_surface_ids, merged_curve_ids );
+ }
+
CubitStatus status = gme->webcut_with_brick (
- engine_body_sms, center, axes, extension, result_sm_list, imprint );
+ engine_body_sms, center, axes, extension,
+ neighbor_imprint_list,
+ result_sm_list, imprint_type, preview );
- restore_vg_after_modify(result_sm_list, engine_bodies);
+ // just continue the loop if previewing
+ if (preview)
+ {
+ rval = status;
+ continue;
+ }
- status = finish_webcut( engine_bodies, result_sm_list, merge, status, results_list );
+ restore_vg_after_modify(result_sm_list, engine_bodies, gme);
+ remove_pushed_attributes(result_sm_list, engine_bodies);
+
+ status = finish_webcut( engine_bodies, result_sm_list, merge, status, results_list,
+ &merged_surface_ids, &merged_curve_ids );
+
if (!status)
rval = CUBIT_FAILURE;
@@ -3507,8 +4931,17 @@
result_sm_list.clean_out();
}
- do_attribute_cleanup();
+ if (!preview)
+ do_attribute_cleanup();
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ if( results_list.size() ) //if there are new bodies...something succeeded
+ CubitUndo::note_result_bodies( results_list );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
return rval;
}
@@ -3518,8 +4951,10 @@
const CubitVector axes[2],
double width, double height,
DLIList<Body*> &results_list,
- CubitBoolean imprint,
- CubitBoolean merge )
+ DLIList<Body*> &neighboring_bodies,
+ ImprintType imprint_type,
+ CubitBoolean merge,
+ CubitBoolean preview)
{
if ( width <= GEOMETRY_RESABS || height <= GEOMETRY_RESABS )
{
@@ -3534,23 +4969,67 @@
CubitStatus rval = CUBIT_SUCCESS;
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<Body*> bodies_to_save;
+ bodies_to_save += webcut_body_list;
+ bodies_to_save += neighboring_bodies;
+ CubitUndo::save_state_with_cubit_file( bodies_to_save );
+ }
+
const int count = webcut_body_list.size();
DLIList<BodySM*> result_sm_list;
DLIList<Body*> body_list(webcut_body_list);
DLIList<BodySM*> engine_body_sms(count);
DLIList<Body*> engine_bodies(count);
GeometryModifyEngine* gme = 0;
- do_attribute_setup();
+
while ( (gme = group_bodies_by_engine(body_list, engine_bodies, engine_body_sms)) )
{
- push_vg_attributes_before_modify(engine_body_sms);
+ DLIList<int> merged_surface_ids;
+ DLIList<int> merged_curve_ids;
+ DLIList<BodySM*> neighbor_imprint_list;
+ if (!preview)
+ {
+ int i;
+ for( i=neighboring_bodies.size(); i--; )
+ {
+ Body *neighbor_body = neighboring_bodies.get_and_step();
+ BodySM *tmp_body = neighbor_body->get_body_sm_ptr();
+ GeometryModifyEngine *neighbor_gme = get_engine( tmp_body );
+
+ if( gme == neighbor_gme )
+ {
+ neighbor_imprint_list.append( tmp_body );
+ engine_bodies.append( neighbor_body );
+ }
+ }
+ do_attribute_setup();
+ DLIList<BodySM*> bodies_sms_to_modify;
+ bodies_sms_to_modify += engine_body_sms;
+ bodies_sms_to_modify += neighbor_imprint_list;
+ push_vg_attributes_before_modify( bodies_sms_to_modify );
+ get_merged_curve_and_surface_ids( engine_bodies, merged_surface_ids, merged_curve_ids );
+ }
+
CubitStatus status = gme->webcut_with_planar_sheet (
- engine_body_sms, center, axes, width, height, result_sm_list, imprint );
+ engine_body_sms, center, axes, width, height,
+ neighbor_imprint_list,
+ result_sm_list, imprint_type, preview );
- restore_vg_after_modify(result_sm_list, engine_bodies);
+ // just continue the loop if previewing
+ if (preview)
+ {
+ rval = status;
+ continue;
+ }
- status = finish_webcut( engine_bodies, result_sm_list, merge, status, results_list );
+ restore_vg_after_modify(result_sm_list, engine_bodies, gme);
+ remove_pushed_attributes(result_sm_list, engine_bodies);
+
+ status = finish_webcut( engine_bodies, result_sm_list, merge, status, results_list,
+ &merged_surface_ids, &merged_curve_ids );
if (!status)
rval = CUBIT_FAILURE;
@@ -3559,8 +5038,17 @@
result_sm_list.clean_out();
}
- do_attribute_cleanup();
+ if (!preview)
+ do_attribute_cleanup();
+ if( preview == CUBIT_FALSE && CubitUndo::get_undo_enabled() )
+ {
+ if( rval == CUBIT_SUCCESS )
+ CubitUndo::note_result_bodies( results_list );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
return rval;
}
@@ -3570,14 +5058,29 @@
const CubitVector &vector2,
const CubitVector &vector3,
DLIList<Body*>& results_list,
- CubitBoolean imprint,
- CubitBoolean merge)
+ DLIList<Body*> &neighboring_bodies,
+ ImprintType imprint_type,
+ CubitBoolean merge,
+ CubitBoolean preview)
{
if (!okay_to_modify( webcut_body_list, "WEBCUT" ))
return CUBIT_FAILURE;
CubitStatus rval = CUBIT_SUCCESS;
+ if (preview)
+ {
+ GeometryModifyTool::plane_preview(webcut_body_list, vector1, vector2, vector3);
+ return rval;
+ }
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ DLIList<Body*> bodies_to_save;
+ bodies_to_save += webcut_body_list;
+ bodies_to_save += neighboring_bodies;
+ CubitUndo::save_state_with_cubit_file( bodies_to_save );
+ }
+
const int count = webcut_body_list.size();
DLIList<BodySM*> temp_sm_list(webcut_body_list.size());
DLIList<BodySM*> result_sm_list;
@@ -3586,19 +5089,59 @@
DLIList<Body*> engine_bodies(count);
GeometryModifyEngine* gme = 0;
- do_attribute_setup();
+ // all preview stuff handled before this point
+ if(!preview)
+ do_attribute_setup();
while ( (gme = group_bodies_by_engine(body_list, engine_bodies, engine_body_sms)) )
{
- push_vg_attributes_before_modify(engine_body_sms);
+ //get all the child entities that have been merged
+ DLIList<int> merged_surface_ids;
+ DLIList<int> merged_curve_ids;
+ DLIList<BodySM*> neighbor_imprint_list;
+
+ if (!preview)
+ {
+ int i;
+ for( i=neighboring_bodies.size(); i--; )
+ {
+ Body *neighbor_body = neighboring_bodies.get_and_step();
+ BodySM *tmp_body = neighbor_body->get_body_sm_ptr();
+ GeometryModifyEngine *neighbor_gme = get_engine( tmp_body );
+
+ if( gme == neighbor_gme )
+ {
+ neighbor_imprint_list.append( tmp_body );
+ engine_bodies.append( neighbor_body );
+ }
+ }
+
+ DLIList<BodySM*> bodies_sms_to_modify;
+ bodies_sms_to_modify += engine_body_sms;
+ bodies_sms_to_modify += neighbor_imprint_list;
+ push_vg_attributes_before_modify( bodies_sms_to_modify );
+ get_merged_curve_and_surface_ids( engine_bodies, merged_surface_ids, merged_curve_ids );
+ }
+
CubitStatus status = gme->webcut(engine_body_sms, vector1, vector2,
- vector3, result_sm_list, imprint );
+ vector3, neighbor_imprint_list, result_sm_list, imprint_type, preview );
- restore_vg_after_modify(result_sm_list, engine_bodies);
-
if ( status != CUBIT_FAILURE )
- status = finish_webcut( engine_bodies, result_sm_list, merge, status, results_list );
+ {
+ if(!preview)
+ {
+ restore_vg_after_modify(result_sm_list, engine_bodies, gme);
+ remove_pushed_attributes(result_sm_list, engine_bodies);
+ }
+ status = finish_webcut( engine_bodies, result_sm_list, merge, status, results_list,
+ &merged_surface_ids, &merged_curve_ids );
+ }
+ else
+ {
+ if(!preview)
+ remove_pushed_attributes(result_sm_list, engine_bodies);
+ }
engine_bodies.clean_out();
engine_body_sms.clean_out();
@@ -3611,18 +5154,28 @@
}
}
- do_attribute_cleanup();
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ if( rval == CUBIT_SUCCESS )
+ CubitUndo::note_result_bodies( results_list );
+ else
+ CubitUndo::remove_last_undo();
+ }
+ if(!preview)
+ do_attribute_cleanup();
+
return rval;
}
-CubitStatus GeometryModifyTool::restore_vg_after_modify(DLIList<BodySM*> &new_sms,
+void GeometryModifyTool::remove_pushed_attributes(DLIList<BodySM*> &new_sms,
DLIList<Body*> &old_bodies)
{
DLIList<TopologyBridge*> old_bridges(old_bodies.size());
DLIList<TopologyBridge*> new_bridges(new_sms.size());
CAST_LIST(new_sms, new_bridges, TopologyBridge);
+ // Get bridges for all of the old Bodies.
int k;
for(k = old_bodies.size(); k>0; k--)
{
@@ -3631,37 +5184,106 @@
if(tb)
{
old_bridges.append(tb);
+ DLIList<TopologyBridge*> bridge_list;
+ bridge_list.append(tb);
+ // Add any bodies with composites to the new_sms list so that
+ // make_Body gets called on them. This will make sure that the
+ // virtual gets ref entities properly built.
+ if(this->contains_composites(bridge_list))
+ {
+ BodySM *bsm = dynamic_cast<BodySM*>(tb);
+ if(bsm)
+ new_sms.append_unique(bsm);
+ }
}
}
+ // Make a list including all of the bridges passed in.
DLIList<TopologyBridge*> all_bridges;
all_bridges = new_bridges;
for(k=old_bridges.size(); k--;)
all_bridges.append_unique(old_bridges.get_and_step());
- // After a real geometry operation some of the virtual topology bridges may
- // have been blown away and some of them may have just had underlying
- // topology modified. These calls will try to recognize virtual geometry
- // that has been modified so that it can be deactivated and rebuilt.
- // I am calling it on both of these lists because it is not always clear
- // which one will have the virtual we are interested in.
- GeometryQueryTool::instance()->ige_remove_modified(all_bridges);
+ // At this point we don't need any more attributes on the underlying
+ // entities so make sure they are cleaned up.
+ GeometryQueryTool::instance()->ige_remove_attributes( all_bridges );
+}
- // Now that we have removed any virtual that was affected by the operation we
- // can examine the remaining virtual and remove any COMPOSITE_GEOM attributes
- // that are unneeded since the virtual already exists and wasn't modified by
- // the operation. Another way of saying this is that we don't need to process the
- // COMPOSITE_GEOM attributes to rebuild the virtual layer if the virtual layer is
- // already there.
- GeometryQueryTool::instance()->ige_remove_attributes_from_unmodifed_virtual(all_bridges);
+CubitStatus GeometryModifyTool::restore_vg_after_modify(DLIList<BodySM*> &new_sms,
+ DLIList<Body*> &old_bodies,
+ GeometryModifyEngine *gme)
+{
+ DLIList<TopologyBridge*> old_bridges(old_bodies.size());
+ DLIList<TopologyBridge*> new_bridges(new_sms.size());
+ CAST_LIST(new_sms, new_bridges, TopologyBridge);
+ // Get bridges for all of the old Bodies.
+ int k;
+ for(k = old_bodies.size(); k>0; k--)
+ {
+ Body *body = old_bodies.get_and_step();
+ TopologyBridge *tb = body->bridge_manager()->topology_bridge();
+ if(tb)
+ {
+ old_bridges.append(tb);
+ DLIList<TopologyBridge*> bridge_list;
+ bridge_list.append(tb);
+ // Add any bodies with composites to the new_sms list so that
+ // make_Body gets called on them. This will make sure that the
+ // virtual gets ref entities properly built.
+ if(this->contains_composites(bridge_list))
+ {
+ BodySM *bsm = dynamic_cast<BodySM*>(tb);
+ if(bsm)
+ new_sms.append_unique(bsm);
+ }
+ }
+ }
+
+ // Make a list including all of the bridges passed in.
+ DLIList<TopologyBridge*> all_bridges;
+ all_bridges = new_bridges;
+ for(k=old_bridges.size(); k--;)
+ all_bridges.append_unique(old_bridges.get_and_step());
+
+ DLIList<TopologyBridge*> tbs_to_check;
+ if(gme)
+ gme->get_possible_invalid_tbs(all_bridges, tbs_to_check);
+
+ DLIList<Surface*> all_surfs;
+ DLIList<Curve*> all_curves;
+ DLIList<Point*> all_points;
+ if(tbs_to_check.size() > 0)
+ {
+ for(k=tbs_to_check.size(); k--;)
+ {
+ TopologyBridge *tb = tbs_to_check.get_and_step();
+ Surface *surf = dynamic_cast<Surface*>(tb);
+ if(surf)
+ all_surfs.append(surf);
+ else
+ {
+ Curve *cur = dynamic_cast<Curve*>(tb);
+ if(cur)
+ all_curves.append(cur);
+ else
+ {
+ Point *pt = dynamic_cast<Point*>(tb);
+ if(pt)
+ all_points.append(pt);
+ }
+ }
+ }
+ }
+
+ // This function has been changed to blown away any virtual (really only doing
+ // composites right now). The virtual will rebuilt from the attributes stored
+ // on the ACIS entities.
+ GeometryQueryTool::instance()->ige_remove_modified(all_surfs, all_curves, all_points);
+
//Restore virtual
GeometryQueryTool::instance()->ige_import_geom( all_bridges );
- // At this point we don't need any more attributes on the underlying
- // entities so make sure they are cleaned up.
- GeometryQueryTool::instance()->ige_remove_attributes( all_bridges );
-
return CUBIT_SUCCESS;
}
@@ -3736,7 +5358,7 @@
CubitStatus GeometryModifyTool::unite( DLIList<BodySM*> &body_sm_list,
DLIList<BodySM*> &new_body_sm_list,
- bool keep_old )
+ bool keep_old)
{
//this assumes that all bodies have the same modify engine
GeometryModifyEngine *gme = get_engine( body_sm_list.get() );
@@ -3744,18 +5366,18 @@
return result;
}
-
-CubitStatus GeometryModifyTool::unite( DLIList<Body*> &bodies,
- DLIList<Body*> &newBodies,
- bool keep_old )
+CubitStatus
+GeometryModifyTool::unite( DLIList<Body*> &bodies,
+ DLIList<Body*> &new_body_list,
+ bool keep_old )
{
- if (bodies.size() <= 1)
- {
- PRINT_WARNING("There is only one body in the list. Nothing modified\n");
- return CUBIT_FAILURE;
- }
- if (!okay_to_modify( bodies, "UNITE" ))
- return CUBIT_FAILURE;
+ if( bodies.size() <= 1 )
+ {
+ PRINT_WARNING("There is only one volume in the list. Nothing modified.\n");
+ return CUBIT_FAILURE;
+ }
+ if (!okay_to_modify( bodies, "UNITE" ))
+ return CUBIT_FAILURE;
int i;
const int count = bodies.size();
@@ -3766,72 +5388,223 @@
entity_list.append_unique(bodies.get_and_step());
GeometryModifyEngine* gme = common_modify_engine( entity_list, bridge_list );
- if ( !gme )
+ if( !gme )
{
- PRINT_ERROR("Performing UNITE with volumes containing geometry from\n"
- "different modeling engines is not allowed.\n"
- "Delete uncommon geometry on these volumes before operation.\n\n");
- return CUBIT_FAILURE;
+ PRINT_ERROR("Performing UNITE with volumes containing geometry from\n"
+ "different modeling engines is not allowed.\n"
+ "Delete uncommon geometry on these volumes before operation.\n\n");
+ return CUBIT_FAILURE;
}
- // give 1st body in "old_bodies" list all the
- // names of all bodies being united
+ // Cubit can't mesh mixed sheet/solid bodies that are united together. If
+ // required, separate the unite between these types.
+ CubitStatus result;
+ if( GeometryModifyTool::instance()->unite_mixed_models() )
+ result = unite_all( gme, bodies, new_body_list, keep_old );
+ else
+ result = unite_separately( gme, bodies, new_body_list, keep_old );
+ if( result == CUBIT_FAILURE )
+ PRINT_ERROR("UNITE failed\n");
+
+ return result;
+}
+
+CubitStatus
+GeometryModifyTool::unite_separately( GeometryModifyEngine *gme_ptr,
+ DLIList<Body*> &bodies,
+ DLIList<Body*> &new_body_list,
+ bool keep_old )
+{
+ // Cubit can't mesh mixed sheet/solid bodies that are united together. Sort
+ // based on these types.
+ int i;
+ Body *body_ptr;
+ DLIList<Body*> solid_body_list;
+ DLIList<Body*> sheet_body_list;
+ bodies.reset();
+ for( i=bodies.size(); i--; )
+ {
+ body_ptr = bodies.get_and_step();
+
+ if( body_ptr->is_sheet_body() )
+ sheet_body_list.append( body_ptr );
+ else
+ solid_body_list.append( body_ptr );
+ }
+
+ if( sheet_body_list.size() == 1 && solid_body_list.size() == 1 )
+ {
+ PRINT_ERROR( "Cannot unite solid and sheet bodies together\n" );
+ return CUBIT_FAILURE;
+ }
+
+ // Setup undo
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( keep_old )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( bodies );
+ }
+
+ // Unite solids with each other, and sheets with each other separately
+ CubitStatus result1 = CUBIT_SUCCESS;
+ CubitStatus result2 = CUBIT_SUCCESS;
+ if( solid_body_list.size() > 1 )
+ result1 = unite_private( gme_ptr, solid_body_list, new_body_list, keep_old );
+ if( sheet_body_list.size() > 1 )
+ result2 = unite_private( gme_ptr, sheet_body_list, new_body_list, keep_old );
+
+ // Finish undo
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( new_body_list.size() )
+ CubitUndo::note_result_bodies( new_body_list );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
+ // Return success if both unites successful
+ if( result1 == CUBIT_SUCCESS && result2 == CUBIT_SUCCESS )
+ return CUBIT_SUCCESS;
+
+ // Return success if either unite was successful
+ if( solid_body_list.size() > 1 && result1 == CUBIT_SUCCESS ||
+ sheet_body_list.size() > 1 && result2 == CUBIT_SUCCESS )
+ {
+ // Give warning if one or the other failed
+ if( result1 = CUBIT_FAILURE )
+ PRINT_WARNING( "Unite of solid volumes failed\n" );
+ if( result2 = CUBIT_FAILURE )
+ PRINT_WARNING( "Unite of sheet bodies failed\n" );
+
+ return CUBIT_SUCCESS;
+ }
+
+ return CUBIT_FAILURE;
+}
+
+CubitStatus
+GeometryModifyTool::unite_all( GeometryModifyEngine *gme_ptr,
+ DLIList<Body*> &bodies,
+ DLIList<Body*> &new_body_list,
+ bool keep_old )
+{
+ // Setup undo
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( keep_old )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( bodies );
+ }
+
+ // Unite solids with each other, and sheets with each other separately
+ CubitStatus result = unite_private( gme_ptr, bodies, new_body_list, keep_old );
+
+ // Finish undo
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( new_body_list.size() )
+ CubitUndo::note_result_bodies( new_body_list );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
+ return result;
+}
+
+// Private workhorse function for unite
+CubitStatus
+GeometryModifyTool::unite_private( GeometryModifyEngine *gme_ptr,
+ DLIList<Body*> &body_list,
+ DLIList<Body*> &new_body_list,
+ bool keep_old )
+{
+ if( !body_list.size() )
+ return CUBIT_SUCCESS;
+
+ int i, j;
+ Body *body_ptr;
+ CubitStatus result;
+
+ // Give 1st body all the names of all bodies being united
std::list<CubitString> names_list;
DLIList<CubitString*> entity_names;
- //Loop through second till end body
- for (i=0; i < bodies.size(); i++)
+ body_list.reset();
+ for( i=body_list.size(); i--; )
{
+ body_ptr = body_list.get_and_step();
- //See if body has names
- if(bodies.get()->num_names())
+ // See if body has names
+ if( body_ptr->num_names() )
{
- //Put the names in a list
- bodies.get()->entity_names( entity_names );
+ // Put the names in a list
+ body_ptr->entity_names( entity_names );
entity_names.reset();
- //Loop through names
- for (int ij = 0; ij < entity_names.size(); ij++)
+ // Loop through names
+ for( j=entity_names.size(); j--; )
names_list.push_back( *entity_names.get_and_step() );
entity_names.clean_out();
- bodies.get()->remove_entity_names();
+ body_ptr->remove_entity_names();
}
- bodies.step();
}
- DLIList<BodySM*> body_sm_list(bridge_list.size());
- DLIList<BodySM*> new_bodies;
+ do_attribute_setup();
+
+ DLIList<TopologyEntity*> entity_list(body_list.size());
+ DLIList<TopologyBridge*> bridge_list(body_list.size());
+ body_list.reset();
+ for( i=body_list.size(); i--; )
+ entity_list.append_unique(body_list.get_and_step());
+ common_modify_engine( entity_list, bridge_list );
+
+ DLIList<BodySM*> body_sm_list(body_list.size());
CAST_LIST(bridge_list, body_sm_list, BodySM);
- CubitStatus result = unite(body_sm_list, new_bodies, keep_old);
+ push_vg_attributes_before_modify(body_sm_list);
+
+ DLIList<int> merged_surface_ids;
+ DLIList<int> merged_curve_ids;
+
+ get_merged_curve_and_surface_ids( body_list, merged_surface_ids, merged_curve_ids );
+
+ DLIList<BodySM*> new_body_sm_list;
+ result = unite( body_sm_list, new_body_sm_list, keep_old );
+
+ restore_vg_after_modify( new_body_sm_list, body_list, gme_ptr );
+ remove_pushed_attributes( new_body_sm_list, body_list );
+
DLIList<Body*> result_list;
- if (!finish_sm_op(bodies, new_bodies, result_list))
+ if( !finish_sm_op(body_list, new_body_sm_list, result_list) )
result = CUBIT_FAILURE;
- if (result)
+ if( keep_old == CUBIT_FALSE )
+ fixup_merged_entities( merged_surface_ids, merged_curve_ids );
+
+ do_attribute_cleanup();
+
+ if( result )
{
- newBodies += result_list;
+ new_body_list += result_list;
- int i;
- for( i=result_list.size(); i--; )
- {
- //Add names to 1st body
- std::list<CubitString>::iterator iter, end = names_list.end();
- for (iter = names_list.begin(); iter != end; ++iter)
- result_list.get_and_step()->entity_name( *iter );
- }
+ for( j=result_list.size(); j--; )
+ {
+ //Add names to 1st body
+ std::list<CubitString>::iterator iter, end = names_list.end();
+ for (iter = names_list.begin(); iter != end; ++iter)
+ result_list.get_and_step()->entity_name( *iter );
+ }
}
- else
- {
- PRINT_ERROR("UNITE failed\n");
- }
return result;
}
-CubitStatus GeometryModifyTool::chop( DLIList<Body*>& bodies,
+CubitStatus GeometryModifyTool::chop( DLIList<Body*> &bodies,
DLIList<Body*> &intersectBodies,
DLIList<Body*> &outsideBodies,
Body*& leftoversBody,
@@ -3870,28 +5643,75 @@
DLIList<BodySM*> intersect_bodies, outside_bodies;
BodySM *leftovers_body = 0;
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( keep_old )
+ CubitUndo::save_state();
+ else
+ {
+ //Get all the bodies associated with the vertex
+ CubitUndo::save_state_with_cubit_file( bodies );
+ }
+ }
+
+ DLIList<int> merged_surface_ids;
+ DLIList<int> merged_curve_ids;
+ DLIList<Body*> tmp_bodies(1);
+ tmp_bodies.append( bodies.get() );
+ if( keep_old == CUBIT_FALSE )
+ get_merged_curve_and_surface_ids( tmp_bodies, merged_surface_ids, merged_curve_ids );
+
do_attribute_setup();
- push_vg_attributes_before_modify(body_sm_list);
+ // Push attributes down onto the blank body (first one in list).
+ DLIList<BodySM*> tmp_body_sm_list;
+ body_sm_list.reset();
+ tmp_body_sm_list.append(body_sm_list.get());
+ push_vg_attributes_before_modify(tmp_body_sm_list);
+
CubitStatus result = gme->chop( body_sm_list, intersect_bodies,
outside_bodies, leftovers_body, keep_old, nonreg );
if( result == CUBIT_FAILURE )
{
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
+
PRINT_ERROR("CHOP failed\n");
+ remove_pushed_attributes(tmp_body_sm_list, tmp_bodies);
do_attribute_cleanup();
return CUBIT_FAILURE;
}
- restore_vg_after_modify(intersect_bodies, original_body_list);
- restore_vg_after_modify(outside_bodies, original_body_list);
+ DLIList<BodySM*> all_sms = intersect_bodies;
+ all_sms += outside_bodies;
+ restore_vg_after_modify(all_sms, tmp_bodies, gme);
+ remove_pushed_attributes(all_sms, tmp_bodies);
+
DLIList<Body*> result_bodies;
+
body_sm_list.clean_out();
body_sm_list += intersect_bodies;
- if (!finish_sm_op(bodies, body_sm_list, result_bodies))
+ CubitStatus stat = finish_sm_op(bodies, body_sm_list, result_bodies);
+
+ if( keep_old == CUBIT_FALSE )
+ fixup_merged_entities( merged_surface_ids, merged_curve_ids);
+
+ if( CubitUndo::get_undo_enabled() )
{
+ if( stat == CUBIT_SUCCESS )
+ CubitUndo::note_result_bodies( result_bodies );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
+ if( stat == CUBIT_FAILURE )
+ {
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
+
PRINT_ERROR("CHOP failed\n");
do_attribute_cleanup();
return CUBIT_FAILURE;
@@ -3904,6 +5724,9 @@
result_bodies.clean_out();
if (!finish_sm_op(bodies, body_sm_list, result_bodies))
{
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
+
PRINT_ERROR("CHOP failed\n");
do_attribute_cleanup();
return CUBIT_FAILURE;
@@ -3917,13 +5740,29 @@
result_bodies.clean_out();
if (!finish_sm_op(bodies, body_sm_list, result_bodies))
{
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
+
PRINT_ERROR("CHOP failed\n");
do_attribute_cleanup();
return CUBIT_FAILURE;
}
leftoversBody = result_bodies.get();
+
}
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( leftoversBody )
+ {
+ DLIList<Body*> tmp_list(1);
+ tmp_list.append( leftoversBody );
+ CubitUndo::note_result_bodies( tmp_list );
+ }
+ CubitUndo::note_result_bodies( intersectBodies );
+ CubitUndo::note_result_bodies( outsideBodies );
+ }
+
do_attribute_cleanup();
return CUBIT_SUCCESS;
}
@@ -3959,6 +5798,9 @@
return CUBIT_FAILURE;
}
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state_with_cubit_file( bodies );
+
DLIList<BodySM*> new_sms(count);
DLIList<BodySM*> body_sms(count);
CAST_LIST(bridge_list, body_sms, BodySM);
@@ -3998,6 +5840,14 @@
if (!finish_sm_op(bodies, new_sms, new_bodies))
result = CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( new_bodies.size() )
+ CubitUndo::note_result_bodies( new_bodies );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
// Update graphics
while (entities_to_update.size())
entities_to_update.pop()->notify_all_observers( GEOMETRY_MODIFIED );
@@ -4052,18 +5902,18 @@
}
- DLIList<RefFace*> face_list;
DLIList<RefFace*> ref_face_list;
DLIList<RefFace*> free_face_list;
DLIList<RefFace*> bad_face_list;
+ //gather all the faces from all the bodies
bodies.reset();
+ for( int i=bodies.size(); i--; )
+ {
+ Body* BodyPtr = bodies.get_and_step();
+ BodyPtr->ref_faces(free_face_list);
+ }
- Body* BodyPtr = bodies.get_and_step();
- BodyPtr->ref_faces(face_list);
- BodyPtr->ref_faces(free_face_list);
-
-
RefFace *ref_face_ptr;
RefFace *inter_face_ptr;
@@ -4073,7 +5923,7 @@
}
else
{
- ref_face_ptr = face_list.get_and_step();
+ ref_face_ptr = free_face_list.get_and_step();
}
ref_face_list.append(ref_face_ptr);
@@ -4142,11 +5992,12 @@
if (reverse && bad_face_list.size())
{
-// CubitStatus result = gePtr1->flip_normals(bad_face_list);
-// if ( result == CUBIT_FAILURE )
-// {
- return CUBIT_FAILURE;
-// }
+ //CubitStatus result = gePtr1->flip_normals(bad_face_list);
+ CubitStatus result = GeometryModifyTool::instance()->reverse(bad_face_list);
+ if ( result == CUBIT_FAILURE )
+ {
+ return CUBIT_FAILURE;
+ }
}
else if(!bad_face_list.size())
{
@@ -4157,10 +6008,10 @@
-CubitStatus GeometryModifyTool::subtract ( Body* tool_body, DLIList<Body*> &from_bodies,
- DLIList<Body*> &new_bodies,
- bool imprint,
- bool keep_old )
+CubitStatus GeometryModifyTool::subtract( Body* tool_body, DLIList<Body*> &from_bodies,
+ DLIList<Body*> &new_bodies,
+ bool imprint,
+ bool keep_old )
{
DLIList<Body*> temp_body_list;
temp_body_list.append(tool_body);
@@ -4206,83 +6057,255 @@
return CUBIT_FAILURE;
}
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( keep_old )
+ CubitUndo::save_state();
+ else
+ {
+ //Get all the bodies associated with the vertex
+ DLIList<Body*> bodies;
+ bodies += tool_body_list;
+ bodies += from_bodies;
+ CubitUndo::save_state_with_cubit_file( bodies );
+ }
+ }
+
+ DLIList<int> merged_surface_ids;
+ DLIList<int> merged_curve_ids;
+ if( keep_old == CUBIT_FALSE )
+ get_merged_curve_and_surface_ids( from_bodies, merged_surface_ids, merged_curve_ids );
+
// Do the subtract operation
DLIList<BodySM*> new_sms;
CubitStatus result = gme->subtract(tool_sms, from_sms, new_sms, imprint, keep_old );
- if (!finish_sm_op(tem_bodies, new_sms, new_bodies))
- result = CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled() && result == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+ result = finish_sm_op(tem_bodies, new_sms, new_bodies);
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( result == CUBIT_SUCCESS )
+ CubitUndo::note_result_bodies( new_bodies );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
if ( result == CUBIT_FAILURE )
{
PRINT_ERROR("Subtract FAILED\n" );
return CUBIT_FAILURE;
}
+ if( keep_old == CUBIT_FALSE )
+ fixup_merged_entities( merged_surface_ids, merged_curve_ids);
+
return CUBIT_SUCCESS;
}
+CubitStatus GeometryModifyTool::intersect( DLIList<Body*> &from_bodies,
+ DLIList<Body*> &new_bodies,
+ bool keep_old )
+{
+ DLIList<Body*> tem_bodies = from_bodies;
+ if (!okay_to_modify( tem_bodies, "INTERSECT" ))
+ return CUBIT_FAILURE;
-CubitStatus GeometryModifyTool::intersect ( Body *tool_body_ptr,
- DLIList<Body*> &from_bodies,
- DLIList<Body*> &new_bodies,
- bool keep_old )
+ DLIList<BodySM*> from_sm_list(tem_bodies.size());
+ GeometryModifyEngine* engine = common_modify_engine(tem_bodies, from_sm_list);
+ if ( NULL == engine )
+ {
+ PRINT_ERROR("Performing INTERSECTION with volumes containing geometry\n"
+ "from different modeling engines is not allowed.\n"
+ "Delete uncommon geometry on these volumes before operation.\n\n");
+ return CUBIT_FAILURE;
+ }
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( keep_old )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( from_bodies );
+ }
+
+ DLIList<int> merged_surface_ids;
+ DLIList<int> merged_curve_ids;
+ if( keep_old == CUBIT_FALSE )
+ get_merged_curve_and_surface_ids( from_bodies, merged_surface_ids, merged_curve_ids );
+
+ GeometryModifyEngine* gme_ptr = get_engine(from_sm_list.get());
+ GeometryQueryEngine* gqe_ptr = gme_ptr->get_gqe();
+
+ DLIList<BodySM*> all_new_bodysms;
+ int i,j;
+ for( i=0; i<from_sm_list.size(); i++ )
+ {
+ from_sm_list.reset();
+ from_sm_list.step(i);
+ BodySM *body1 = from_sm_list.get_and_step();
+
+ for(j=i+1; j<from_sm_list.size(); j++ )
+ {
+ BodySM *body2 = from_sm_list.get_and_step();
+
+ if( body1 == body2 )
+ continue;
+
+ //copy the bodies
+ BodySM *body1_copy = gme_ptr->copy_body( body1 );
+ BodySM *body2_copy = gme_ptr->copy_body( body2 );
+
+ DLIList<BodySM*> tmp_sm_list(1);
+ tmp_sm_list.append( body2_copy );
+ DLIList<BodySM*> new_sms;
+
+ CubitStatus result =
+ engine->intersect(body1_copy, tmp_sm_list, new_sms, true );
+
+ //delete the copies
+ gqe_ptr->delete_solid_model_entities( body1_copy );
+ gqe_ptr->delete_solid_model_entities( body2_copy );
+
+ if ( result == CUBIT_FAILURE || new_sms.size() == 0 )
+ {
+ RefEntity* ref_ent1 = dynamic_cast<RefEntity*>(body1->topology_entity());
+ RefEntity* ref_ent2 = dynamic_cast<RefEntity*>(body2->topology_entity());
+
+ PRINT_WARNING("INTERSECTION of %s with %s failed\n",
+ ref_ent1->entity_name().c_str(),
+ ref_ent2->entity_name().c_str() );
+ continue;
+
+ }
+
+ all_new_bodysms += new_sms;
+ }
+ }
+
+ //now make all the RefEntities
+ all_new_bodysms.reset();
+ for( i=all_new_bodysms.size(); i--; )
+ {
+ Body *new_body = GeometryQueryTool::instance()->make_Body(all_new_bodysms.get_and_step());
+ if( new_body )
+ new_bodies.append( new_body );
+ }
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( all_new_bodysms.size() )
+ CubitUndo::note_result_bodies( new_bodies );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
+ if( keep_old == CUBIT_FALSE )
+ fixup_merged_entities( merged_surface_ids, merged_curve_ids);
+
+ return CUBIT_SUCCESS;
+}
+
+
+
+CubitStatus GeometryModifyTool::intersect( Body *tool_body_ptr,
+ DLIList<Body*> &from_bodies,
+ DLIList<Body*> &new_bodies,
+ bool keep_old )
{
- if(tool_body_ptr == NULL )
- return CUBIT_FAILURE;
- if(from_bodies.size() == 0 || from_bodies.get() == NULL )
- return CUBIT_FAILURE;
+ if(tool_body_ptr == NULL )
+ return CUBIT_FAILURE;
+ if(from_bodies.size() == 0 || from_bodies.get() == NULL )
+ return CUBIT_FAILURE;
- DLIList<Body*> tem_bodies = from_bodies;
- tem_bodies.append( tool_body_ptr );
- if (!okay_to_modify( tem_bodies, "INTERSECT" ))
- return CUBIT_FAILURE;
+ DLIList<Body*> tem_bodies = from_bodies;
+ tem_bodies.append( tool_body_ptr );
+ if (!okay_to_modify( tem_bodies, "INTERSECT" ))
+ return CUBIT_FAILURE;
- DLIList<BodySM*> from_sm_list(tem_bodies.size());
- GeometryModifyEngine* engine = common_modify_engine(tem_bodies, from_sm_list);
- if ( NULL == engine )
- {
- PRINT_ERROR("Performing INTERSECTION with volumes containing geometry\n"
- "from different modeling engines is not allowed.\n"
- "Delete uncommon geometry on these volumes before operation.\n\n");
- return CUBIT_FAILURE;
- }
+ DLIList<BodySM*> from_sm_list(tem_bodies.size());
+ GeometryModifyEngine* engine = common_modify_engine(tem_bodies, from_sm_list);
+ if ( NULL == engine )
+ {
+ PRINT_ERROR("Performing INTERSECTION with volumes containing geometry\n"
+ "from different modeling engines is not allowed.\n"
+ "Delete uncommon geometry on these volumes before operation.\n\n");
+ return CUBIT_FAILURE;
+ }
- BodySM* tool_sm = from_sm_list.pop();
+ BodySM* tool_sm = from_sm_list.pop();
- //cannot intersect tool with itself
- from_sm_list.remove_all_with_value( tool_sm );
- if( from_sm_list.size() == 0 )
- {
- PRINT_ERROR("Cannot intersect volume %d from itself\n",
- tool_body_ptr->ref_volume()->id() );
- return CUBIT_FAILURE;
- }
+ //cannot intersect tool with itself
+ from_sm_list.remove_all_with_value( tool_sm );
+ if( from_sm_list.size() == 0 )
+ {
+ PRINT_ERROR("Cannot intersect volume %d from itself\n",
+ tool_body_ptr->ref_volume()->id() );
+ return CUBIT_FAILURE;
+ }
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( keep_old )
+ CubitUndo::save_state();
+ else
+ {
+ DLIList<Body*> bodies;
+ bodies.append( tool_body_ptr );
+ bodies += from_bodies;
+ CubitUndo::save_state_with_cubit_file( bodies );
+ }
+ }
+
+ DLIList<int> merged_surface_ids;
+ DLIList<int> merged_curve_ids;
+ if( keep_old == CUBIT_FALSE )
+ get_merged_curve_and_surface_ids( from_bodies, merged_surface_ids, merged_curve_ids );
+
// Do the intersect operation
- DLIList<BodySM*> new_sms;
- CubitStatus result =
- engine->intersect(tool_sm, from_sm_list, new_sms, keep_old );
- if(!finish_sm_op(tem_bodies, new_sms, new_bodies))
- result = CUBIT_FAILURE;
+ DLIList<BodySM*> new_sms;
+ CubitStatus result =
+ engine->intersect(tool_sm, from_sm_list, new_sms, keep_old );
+ result = finish_sm_op(tem_bodies, new_sms, new_bodies);
- if ( result == CUBIT_FAILURE )
- {
- PRINT_ERROR("Intersect FAILED\n" );
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( result == CUBIT_SUCCESS )
+ CubitUndo::note_result_bodies( new_bodies );
+ else
+ CubitUndo::remove_last_undo();
+ }
- return CUBIT_FAILURE;
- }
+ if ( result == CUBIT_FAILURE )
+ {
+ PRINT_ERROR("Intersect FAILED\n" );
+ return CUBIT_FAILURE;
+ }
- return CUBIT_SUCCESS;
+ if( keep_old == CUBIT_FALSE )
+ fixup_merged_entities( merged_surface_ids, merged_curve_ids);
+
+ return CUBIT_SUCCESS;
}
CubitStatus GeometryModifyTool::imprint( DLIList<Body*> &from_body_list,
DLIList<Body*> &new_body_list,
CubitBoolean keep_old )
{
+ if( from_body_list.size() == 1 )
+ {
+ PRINT_WARNING("Need more than 1 body or volume to imprint.\n");
+ return CUBIT_FAILURE;
+ }
+
if (get_group_imprint() == CUBIT_FALSE)
- return imprint_singly( from_body_list, new_body_list, keep_old );
+ {
+ CubitStatus result = imprint_singly( from_body_list, new_body_list, keep_old );
+ return result;
+ }
// Check the GeometryEngine for each of the Body's; check to
// make sure they're all the same
@@ -4304,9 +6327,13 @@
return CUBIT_FAILURE;
}
-#ifdef BOYD17
- DLIList<Body*> dummy_body_list;
-#endif
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( keep_old )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( from_body_list );
+ }
int process_composites = 0;
if(contains_composites(from_body_list))
@@ -4319,7 +6346,10 @@
do_attribute_setup();
push_vg_attributes_before_modify(from_sms);
// This must be done after pushing the vg atts because it uses them.
- push_imprint_attributes_before_modify(from_sms);
+ DLIList<TopologyBridge*> tb_list;
+ CAST_LIST(from_sms, tb_list, TopologyBridge);
+ push_named_attributes_to_curves_and_points(tb_list, "IMPRINTER");
+ push_named_attributes_to_curves_and_points(tb_list, "ORIGINAL");
}
DLIList<TopologyBridge*> new_tbs, att_tbs;
@@ -4329,15 +6359,21 @@
int i, j;
if(process_composites)
{
- // Analyze the results and adjust virtual attributes as necessary.
- GeometryQueryTool::instance()->ige_attribute_after_imprinting(new_tbs, att_tbs,
- new_sms, from_body_list);
+ if(result == CUBIT_SUCCESS)
+ {
+ // Analyze the results and adjust virtual attributes as necessary.
+ DLIList<TopologyBridge*> tb_list;
+ CAST_LIST(new_sms, tb_list, TopologyBridge);
+ GeometryQueryTool::instance()->ige_attribute_after_imprinting(new_tbs, att_tbs,
+ tb_list, from_body_list);
- // Clean up attributes.
- remove_imprint_attributes_after_modify(from_sms, new_sms);
+ // Clean up attributes.
+ remove_imprint_attributes_after_modify(from_sms, new_sms);
- // Restore the virtual geometry.
- restore_vg_after_modify(new_sms, from_body_list);
+ // Restore the virtual geometry.
+ restore_vg_after_modify(new_sms, from_body_list, gePtr1);
+ }
+ remove_pushed_attributes(new_sms, from_body_list);
}
if (get_old_names() == CUBIT_FALSE)
@@ -4345,6 +6381,14 @@
if (!finish_sm_op(from_body_list, new_sms, new_body_list))
result = CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( result == CUBIT_SUCCESS )
+ CubitUndo::note_result_bodies( new_body_list );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
if(process_composites)
do_attribute_cleanup();
@@ -4387,16 +6431,55 @@
}
GeometryQueryTool::instance()->cleanout_deactivated_geometry();
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( result == CUBIT_SUCCESS )
+ CubitUndo::note_result_bodies( new_body_list );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
return result;
}
CubitStatus GeometryModifyTool::scale( Body *&body,
- const CubitVector& factors, bool check_to_transform )
+ const CubitVector& factors,
+ bool check_to_transform,
+ bool preview /*=false*/)
{
if( check_to_transform )
if (!GeometryQueryTool::instance()->okay_to_transform( body ))
return CUBIT_FAILURE;
+ if (preview)
+ {
+ GfxPreview::clear();
+ DLIList<RefEdge*> edges;
+ body->ref_edges(edges);
+ for (int i = 0; i < edges.size(); i++)
+ {
+ GMem poly, prev;
+ edges[i]->get_graphics(poly);
+ GPoint *prev_points = NULL;
+ prev_points = new GPoint[poly.point_list_size()];
+ for (int j = 0; j < poly.point_list_size(); j++)
+ {
+ CubitVector tempV(poly.point_list()[j].x, poly.point_list()[j].y, poly.point_list()[j].z);
+ tempV.x(tempV.x()*factors.x());
+ tempV.y(tempV.y()*factors.y());
+ tempV.z(tempV.z()*factors.z());
+ prev_points[j].x = tempV.x();
+ prev_points[j].y = tempV.y();
+ prev_points[j].z = tempV.z();
+ }
+ GfxPreview::draw_polyline(prev_points, poly.point_list_size(), CUBIT_BLUE);
+ delete [] prev_points;
+ prev_points = NULL;
+ }
+ GfxPreview::flush();
+ return CUBIT_SUCCESS;
+ }
+
BodySM* bodysm = body->get_body_sm_ptr();
GeometryModifyEngine* engine = get_engine( bodysm );
CubitStatus result;
@@ -4445,9 +6528,6 @@
//between the two lists.
from_body_list.uniquify_ordered();
-#ifdef BOYD17
- DLIList<BodySM*> from_sms(from_body_list.size()), new_sms;
-#endif
DLIList<BodySM*> from_sms(from_body_list.size());
GeometryModifyEngine* gePtr1 = common_modify_engine(from_body_list, from_sms);
if ( !gePtr1 )
@@ -4471,6 +6551,14 @@
new_body_list = from_body_list;
GeometryQueryTool* gqt = GeometryQueryTool::instance();
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( keep_old )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( from_body_list );
+ }
+
int i;
for (i = 0; i < new_body_list.size(); i++) {
for (int j = 1; j < new_body_list.size()-i; j++) {
@@ -4539,6 +6627,15 @@
temp_body = from_body_list.get_and_step();
while (new_body_list.move_to(temp_body)) new_body_list.remove();
}
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( new_body_list.size() )
+ CubitUndo::note_result_bodies( new_body_list );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
PRINT_INFO("\n");
if( DEBUG_FLAG( 153 ) )
{
@@ -4594,7 +6691,6 @@
}
PRINT_INFO("\n");
-
if (reset_new_ids) set_new_ids(CUBIT_FALSE);
return CUBIT_SUCCESS;
@@ -4607,44 +6703,133 @@
CubitBoolean keep_old_body,
CubitBoolean show_messages)
{
- // Check the GeometryEngine for each of the bodies; check to
- // make sure they're all the same
- body_list.reset();
- int i;
+ // Check the GeometryEngine for each of the bodies; check to
+ // make sure they're all the same
+ body_list.reset();
+ int i;
- if (!okay_to_modify( body_list, "IMPRINT" ))
- return CUBIT_FAILURE;
+ if (!okay_to_modify( body_list, "IMPRINT" ))
+ return CUBIT_FAILURE;
- const int count = body_list.size() + ref_edge_list.size();
- DLIList<TopologyEntity*> entity_list(count);
- DLIList<TopologyBridge*> bridge_list(count);
- CAST_LIST_TO_PARENT(body_list, entity_list);
- ref_edge_list.reset();
- for (i = ref_edge_list.size(); i--;)
- entity_list.append(ref_edge_list.get_and_step());
+ const int count = body_list.size() + ref_edge_list.size();
+ DLIList<TopologyEntity*> entity_list(count);
+ DLIList<TopologyBridge*> bridge_list(count);
+ CAST_LIST_TO_PARENT(body_list, entity_list);
+ ref_edge_list.reset();
+ for (i = ref_edge_list.size(); i--;)
+ entity_list.append(ref_edge_list.get_and_step());
- GeometryModifyEngine* gePtr1 = common_modify_engine(entity_list, bridge_list);
- DLIList<BodySM*> body_sm_list(body_list.size());
- DLIList<Curve*> curve_list(ref_edge_list.size());
- CAST_LIST(bridge_list, body_sm_list, BodySM);
- CAST_LIST(bridge_list, curve_list, Curve);
+ GeometryModifyEngine* gePtr1 = common_modify_engine(entity_list, bridge_list);
- if ( !gePtr1 ||
- body_sm_list.size() != body_list.size() ||
- curve_list.size() != ref_edge_list.size() )
+ DLIList<BodySM*> body_sm_list(body_list.size());
+ DLIList<Curve*> curve_list(ref_edge_list.size());
+ CAST_LIST(bridge_list, body_sm_list, BodySM);
+ CAST_LIST(bridge_list, curve_list, Curve);
+
+ if ( !gePtr1 ||
+ body_sm_list.size() != body_list.size() ||
+ curve_list.size() != ref_edge_list.size() )
+ {
+ PRINT_ERROR("Performing IMPRINT with volumes containing geometry from\n"
+ "different modeling engines is not allowed.\n"
+ "Delete uncommon geometry on these volumes before operation.\n\n");
+ return CUBIT_FAILURE;
+ }
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( keep_old_body )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( body_list );
+ }
+
+ int process_composites = 0;
+ if(contains_composites(body_list))
+ process_composites = 1;
+
+ if(process_composites)
+ {
+ // Turn certain attributes on.
+ do_attribute_setup();
+ // Push virtual attributes down to solid model topology before
+ // doing the imprint.
+ push_vg_attributes_before_modify(body_sm_list);
+ // Put "ORIGINAL" attributes on the bodies being imprinted and
+ // the curves as these originally existed.
+ DLIList<TopologyBridge*> tb_list;
+ CAST_LIST(body_sm_list, tb_list, TopologyBridge);
+ push_named_attributes_to_curves_and_points(tb_list, "ORIGINAL");
+ tb_list.clean_out();
+ CAST_LIST(curve_list, tb_list, TopologyBridge);
+ push_named_attributes_to_curves_and_points(tb_list, "ORIGINAL");
+ }
+
+ DLIList<BodySM*> new_sm_list;
+ // The bridges doing the imprinting often get split during the process but
+ // because of the way we are making copies, the IMPRINTER attribute doesn't
+ // get propagated to them. temporary_bridges will be filled in with any
+ // additional IMPRINTER bridges we need to consider below when deciding whether to
+ // keep composite attributes.
+ DLIList<TopologyBridge*> temporary_bridges;
+ CubitStatus status = gePtr1->imprint( body_sm_list, curve_list,
+ new_sm_list, temporary_bridges, keep_old_body, show_messages);
+
+ temporary_bridges.uniquify_ordered();
+
+ if(status == CUBIT_FAILURE)
+ {
+ if(process_composites)
+ {
+ remove_pushed_attributes(new_sm_list, body_list);
+ do_attribute_cleanup();
+ }
+
+ while(temporary_bridges.size())
+ delete temporary_bridges.pop();
+
+ return status;
+ }
+ else
+ {
+ if(process_composites)
+ {
+ DLIList<TopologyBridge*> tb_list, new_tbs, att_tbs;
+ // Analyze the results and adjust virtual attributes as necessary.
+ CAST_LIST(new_sm_list, tb_list, TopologyBridge);
+ // The bridges coming back in temporary_bridges may not have IMPRINTER
+ // attributes on them becuase of the way they were generated below. Make
+ // sure they get IMPRINTER attributes.
+ push_named_attributes_to_curves_and_points(temporary_bridges, "IMPRINTER");
+ tb_list += temporary_bridges;
+ GeometryQueryTool::instance()->ige_attribute_after_imprinting(new_tbs, att_tbs,
+ tb_list, body_list);
+
+ // Clean up attributes.
+ remove_imprint_attributes_after_modify(body_sm_list, new_sm_list);
+
+ // Restore the virtual geometry.
+ restore_vg_after_modify(new_sm_list, body_list, gePtr1);
+ remove_pushed_attributes(new_sm_list, body_list);
+ }
+ }
+
+ while(temporary_bridges.size())
+ delete temporary_bridges.pop();
+
+ status = finish_sm_op(body_list, new_sm_list, new_body_list);
+
+ if(process_composites)
+ do_attribute_cleanup();
+
+ if( CubitUndo::get_undo_enabled() )
{
- PRINT_ERROR("Performing IMPRINT with volumes containing geometry from\n"
- "different modeling engines is not allowed.\n"
- "Delete uncommon geometry on these volumes before operation.\n\n");
- return CUBIT_FAILURE;
+ if( status == CUBIT_SUCCESS )
+ CubitUndo::note_result_bodies( new_body_list );
+ else
+ CubitUndo::remove_last_undo();
}
- DLIList<BodySM*> new_sm_list;
- CubitStatus status = gePtr1->imprint( body_sm_list, curve_list,
- new_sm_list, keep_old_body, show_messages );
- if (!finish_sm_op(body_list, new_sm_list, new_body_list))
- status = CUBIT_FAILURE;
-
return status;
}
@@ -4654,68 +6839,139 @@
CubitBoolean keep_old_body )
{
//get the owning bodies of the faces and edges
- DLIList<Body*> body_list;
- int j;
- for(j=ref_face_list.size(); j--;)
- ref_face_list.get_and_step()->bodies( body_list );
- for(j=ref_edge_list.size(); j--;)
- ref_edge_list.get_and_step()->bodies( body_list );
- body_list.uniquify_unordered();
- if (!okay_to_modify( body_list, "IMPRINT" ))
- return CUBIT_FAILURE;
+ DLIList<Body*> body_list;
+ int j;
+ for(j=ref_face_list.size(); j--;)
+ ref_face_list.get_and_step()->bodies( body_list );
+ for(j=ref_edge_list.size(); j--;)
+ ref_edge_list.get_and_step()->bodies( body_list );
+ body_list.uniquify_unordered();
+ if (!okay_to_modify( body_list, "IMPRINT" ))
+ return CUBIT_FAILURE;
- DLIList<ModelEntity*> temp_list, temp_list_2, body_me_list;
- CAST_LIST_TO_PARENT(ref_face_list, temp_list);
- CAST_LIST_TO_PARENT(ref_edge_list, temp_list_2);
- temp_list += temp_list_2;
- ModelQueryEngine::instance()->query_model(
- temp_list, DagType::body_type(), body_me_list );
+ DLIList<ModelEntity*> temp_list, temp_list_2, body_me_list;
+ CAST_LIST_TO_PARENT(ref_face_list, temp_list);
+ CAST_LIST_TO_PARENT(ref_edge_list, temp_list_2);
+ temp_list += temp_list_2;
+ ModelQueryEngine::instance()->query_model(temp_list, DagType::body_type(), body_me_list );
- DLIList<Surface*> surf_list(ref_face_list.size());
- DLIList<Curve*> curve_list(ref_edge_list.size());
- GeometryModifyEngine* gePtr1 = common_modify_engine( ref_face_list,
- ref_edge_list,
- surf_list,
- curve_list );
+ DLIList<Surface*> surf_list(ref_face_list.size());
+ DLIList<Curve*> curve_list(ref_edge_list.size());
+ GeometryModifyEngine* gePtr1 = common_modify_engine( ref_face_list,ref_edge_list,surf_list,
+ curve_list,true);
+ if ( !gePtr1 )
+ {
+ PRINT_ERROR("Performing IMPRINT with volumes containing geometry from\n"
+ "different modeling engines is not allowed.\n"
+ "Delete uncommon geometry on these volumes before operation.\n\n");
+ return CUBIT_FAILURE;
+ }
- if ( !gePtr1 )
- {
- PRINT_ERROR("Performing IMPRINT with volumes containing geometry from\n"
- "different modeling engines is not allowed.\n"
- "Delete uncommon geometry on these volumes before operation.\n\n");
- return CUBIT_FAILURE;
- }
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( keep_old_body )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( ref_face_list );
+ }
- body_list.clean_out();
- CAST_LIST(body_me_list, body_list, Body);
- DLIList<BodySM*> new_sm_list;
+ int process_composites = 0;
+ if(contains_composites(body_list))
+ process_composites = 1;
- CubitStatus status = gePtr1->imprint( surf_list, curve_list,
+ int i;
+ DLIList<BodySM*> body_sm_list;
+ if(process_composites)
+ {
+ // Turn certain attributes on.
+ do_attribute_setup();
+ for(i=body_list.size(); i--;)
+ body_sm_list.append_unique(body_list.get_and_step()->get_body_sm_ptr());
+ // Push virtual attributes down to solid model topology before
+ // doing the imprint.
+ push_vg_attributes_before_modify(body_sm_list);
+ // Put "ORIGINAL" attributes on the bodies being imprinted and
+ // the curves as these originally existed.
+ DLIList<TopologyBridge*> tmp_tb_list;
+ CAST_LIST(surf_list, tmp_tb_list, TopologyBridge);
+ push_named_attributes_to_curves_and_points(tmp_tb_list, "ORIGINAL");
+ }
+
+ DLIList<BodySM*> new_sm_list;
+ // The bridges doing the imprinting often get split during the process but
+ // because of the way we are making copies, the IMPRINTER attribute doesn't
+ // get propagated to them. temporary_bridges will be filled in with any
+ // additional IMPRINTER bridges we need to consider below when deciding whether to
+ // keep composite attributes.
+ DLIList<TopologyBridge*> temporary_bridges;
+ CubitStatus status = gePtr1->imprint( surf_list, curve_list, temporary_bridges,
new_sm_list, keep_old_body );
- if (!finish_sm_op(body_list, new_sm_list, new_body_list))
- status = CUBIT_FAILURE;
+ temporary_bridges.uniquify_ordered();
- body_list.reset();
- for (int i = body_list.size(); i--; )
+ if(process_composites)
+ {
+ // Analyze the results and adjust virtual attributes as necessary.
+ DLIList<TopologyBridge*> tb_list;
+ CAST_LIST(new_sm_list, tb_list, TopologyBridge);
+ // The bridges coming back in temporary_bridges may not have IMPRINTER
+ // attributes on them becuase of the way they were generated below. Make
+ // sure they get IMPRINTER attributes.
+ push_named_attributes_to_curves_and_points(temporary_bridges, "IMPRINTER");
+ tb_list += temporary_bridges;
+ DLIList<TopologyBridge*> new_tbs, att_tbs;
+ GeometryQueryTool::instance()->ige_attribute_after_imprinting(new_tbs, att_tbs,
+ tb_list, body_list);
+
+ // Clean up attributes.
+ remove_imprint_attributes_after_modify(body_sm_list, new_sm_list);
+
+ restore_vg_after_modify(body_sm_list, body_list, gePtr1);
+ remove_pushed_attributes(body_sm_list, body_list);
+ }
+
+ while(temporary_bridges.size())
+ delete temporary_bridges.pop();
+
+ status = finish_sm_op(body_list, new_sm_list, new_body_list);
+
+ if(process_composites)
+ do_attribute_cleanup();
+
+ if( CubitUndo::get_undo_enabled() )
{
- Body* body = body_list.get_and_step();
- BodySM* bodysm = body->get_body_sm_ptr();
- assert(!!bodysm);
- GeometryQueryTool::instance()->make_Body(bodysm);
+ if( status == CUBIT_SUCCESS )
+ CubitUndo::note_result_bodies( new_body_list );
+ else
+ CubitUndo::remove_last_undo();
}
- GeometryQueryTool::instance()->cleanout_deactivated_geometry();
return status;
-
}
CubitStatus GeometryModifyTool::imprint( DLIList<Surface*> &surface_list,
DLIList<DLIList<Curve*>*> &curve_lists_list,
Body*& /*new_body*/,
- CubitBoolean keep_old_body )
+ CubitBoolean keep_old_body,
+ CubitBoolean expand)
{
+ int i;
+ DLIList<Curve*> *curve_list_ptr;
+
+ // Check to see if any curves exist - if none, just exit
+ int have_curves = 0;
+ for( i=curve_lists_list.size(); i--; )
+ {
+ curve_list_ptr = curve_lists_list.get_and_step();
+ if( curve_list_ptr->size() )
+ {
+ have_curves++;
+ break;
+ }
+ }
+ if( !have_curves )
+ return CUBIT_SUCCESS;
+
// Get parent bodies
- int i;
DLIList<Body*> old_body_list;
surface_list.reset();
for( i=surface_list.size(); i--; )
@@ -4741,13 +6997,35 @@
return CUBIT_FAILURE;
}
+
+ // In order to support imprinting on composite surfaces we will
+ // get any surfaces underlying the surfaces passed in. For now
+ // we will only do this if a single surface is coming in but
+ // it could be extended for multiple surfaces as well.
+ DLIList<Surface*> new_surface_list;
+ if(surface_list.size() == 1)
+ {
+ GeometryQueryEngine *gqe = surface_list.get()->get_geometry_query_engine();
+ DLIList<TopologyBridge*> tbs;
+ gqe->get_underlying_surfaces(surface_list.get(), tbs);
+ if(tbs.size() > 0)
+ {
+ for(int k=tbs.size(); k--;)
+ new_surface_list.append(dynamic_cast<Surface*>(tbs.get_and_step()));
+ }
+ else
+ new_surface_list.append(surface_list.get());
+ }
+ else
+ new_surface_list = surface_list;
+
// Check engines - must all be the same
GeometryModifyEngine* gme;
- surface_list.reset();
- gme = get_engine( surface_list.get() );
- for( i=surface_list.size(); i--; )
+ new_surface_list.reset();
+ gme = get_engine( new_surface_list.get() );
+ for( i=new_surface_list.size(); i--; )
{
- Surface *surf_ptr = surface_list.get_and_step();
+ Surface *surf_ptr = new_surface_list.get_and_step();
GeometryModifyEngine* gme2 = get_engine( surf_ptr );
if( gme != gme2 )
{
@@ -4759,7 +7037,7 @@
int j;
for( i=curve_lists_list.size(); i--; )
{
- DLIList<Curve*> *curve_list_ptr = curve_lists_list.get_and_step();
+ curve_list_ptr = curve_lists_list.get_and_step();
for( j=curve_list_ptr->size(); j--; )
{
Curve *curve_ptr = curve_list_ptr->get_and_step();
@@ -4772,90 +7050,216 @@
}
}
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( keep_old_body )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( old_body_list );
+ }
+
+ int process_composites = 0;
+ if(contains_composites(old_body_list))
+ process_composites = 1;
+
BodySM* new_body_sm = 0;
+ DLIList<BodySM*> body_sm_list;
- CubitStatus status = gme->imprint( surface_list, curve_lists_list,
- new_body_sm, keep_old_body );
+ DLIList<TopologyBridge*> tb_list;
+ if(process_composites)
+ {
+ do_attribute_setup();
+ for(i=old_body_list.size(); i--;)
+ body_sm_list.append_unique(old_body_list.get_and_step()->get_body_sm_ptr());
+ push_vg_attributes_before_modify(body_sm_list);
+ // push_imprint_attributes_before_modify(body_sm_list);
+ DLIList<TopologyBridge*> tmp_tb_list;
+ CAST_LIST(new_surface_list, tmp_tb_list, TopologyBridge);
+ push_named_attributes_to_curves_and_points(tmp_tb_list, "ORIGINAL");
+ for(i=curve_lists_list.size(); i>0; i--)
+ {
+ DLIList<Curve*> *cur_list = curve_lists_list.get_and_step();
+ for(j=cur_list->size(); j>0; j--)
+ {
+ Curve *cur_curve = cur_list->get_and_step();
+ tb_list.append(cur_curve);
+ }
+ }
+ push_named_attributes_to_curves_and_points(tb_list, "IMPRINTER");
+ }
+ DLIList<TopologyBridge*> new_tbs, att_tbs;
+ CubitStatus status = gme->imprint( new_surface_list, curve_lists_list,
+ new_body_sm, keep_old_body, expand, &new_tbs, &att_tbs );
+
DLIList<Body*> new_body_list;
DLIList<BodySM*> new_sm_list;
new_sm_list.append( new_body_sm );
- if (!finish_sm_op(old_body_list, new_sm_list, new_body_list))
- status = CUBIT_FAILURE;
+ if(process_composites)
+ {
+ // Analyze the results and adjust virtual attributes as necessary.
+ DLIList<TopologyBridge*> tmp_tb_list;
+ CAST_LIST(new_sm_list, tmp_tb_list, TopologyBridge);
+ tb_list += tmp_tb_list;
+ GeometryQueryTool::instance()->ige_attribute_after_imprinting(new_tbs, att_tbs,
+ tb_list, old_body_list);
+ // Clean up attributes.
+ remove_imprint_attributes_after_modify(body_sm_list, new_sm_list);
+
+ restore_vg_after_modify(body_sm_list, old_body_list, gme);
+ remove_pushed_attributes(body_sm_list, old_body_list);
+ }
+
+ status = finish_sm_op(old_body_list, new_sm_list, new_body_list);
+
+ if(process_composites)
+ do_attribute_cleanup();
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( status == CUBIT_SUCCESS )
+ CubitUndo::note_result_bodies( new_body_list );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
return status;
}
CubitStatus GeometryModifyTool::imprint( DLIList<Body*> &body_list,
DLIList<CubitVector*> &vector_list,
DLIList<Body*>& new_body_list,
- CubitBoolean keep_old_body )
+ CubitBoolean keep_old_body,
+ CubitBoolean merge )
{
- // Check the GeometryEngine for each of the RefEdges; check to
- // make sure they're all the same
- body_list.reset();
+ // Check the GeometryEngine for each of the RefEdges; check to
+ // make sure they're all the same
+ body_list.reset();
- if (!okay_to_modify( body_list, "IMPRINT" ))
- return CUBIT_FAILURE;
+ if (!okay_to_modify( body_list, "IMPRINT" ))
+ return CUBIT_FAILURE;
- DLIList<BodySM*> body_sm_list(body_list.size()), new_sm_list;
- GeometryModifyEngine* gePtr1 = common_modify_engine(body_list, body_sm_list);
- if ( !gePtr1 )
- {
- PRINT_ERROR("Performing IMPRINT with volumes containing geometry from\n"
- "different modeling engines is not allowed.\n"
- "Delete uncommon geometry on these volumes before operation.\n\n");
- return CUBIT_FAILURE;
- }
+ DLIList<BodySM*> body_sm_list(body_list.size()), new_sm_list;
+ GeometryModifyEngine* gePtr1 = common_modify_engine(body_list, body_sm_list);
+ if ( !gePtr1 )
+ {
+ PRINT_ERROR("Performing IMPRINT with volumes containing geometry from\n"
+ "different modeling engines is not allowed.\n"
+ "Delete uncommon geometry on these volumes before operation.\n\n");
+ return CUBIT_FAILURE;
+ }
- int process_composites = 0;
- if(contains_composites(body_list))
- process_composites = 1;
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( keep_old_body )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( body_list );
+ }
- if(process_composites)
- {
- // Push virtual attributes down to solid model topology before
- // doing the imprint.
- do_attribute_setup();
- push_vg_attributes_before_modify(body_sm_list);
- // This must be done after pushing the vg atts because it uses them.
- push_imprint_attributes_before_modify(body_sm_list);
- }
- DLIList<TopologyBridge*> new_tbs, att_tbs;
+ int process_composites = 0;
+ if(contains_composites(body_list))
+ process_composites = 1;
- CubitStatus status = gePtr1->imprint( body_sm_list, vector_list,
- new_sm_list, keep_old_body, &new_tbs,
- &att_tbs );
+ int i;
+ DLIList<TopologyBridge*> temporary_bridges;
+ if(process_composites)
+ {
+ // Turn certain attributes on.
+ do_attribute_setup();
+ // Push virtual attributes down to solid model topology before
+ // doing the imprint.
+ push_vg_attributes_before_modify(body_sm_list);
+ // Create temporary bridges for the vector positions. We do
+ // this so that we can put an IMPRINTER attribute on them
+ // and use them later for deciding whether to keep composite
+ // attributes or not.
+ for(i=vector_list.size(); i>0; i--)
+ {
+ CubitVector *vec = vector_list.get_and_step();
+ Point *pt = gePtr1->make_Point(*vec);
+ temporary_bridges.append(pt);
+ }
+ push_named_attributes_to_curves_and_points(temporary_bridges, "IMPRINTER");
+ DLIList<TopologyBridge*> tmp_tb_list;
+ CAST_LIST(body_sm_list, tmp_tb_list, TopologyBridge);
+ // Put "ORIGINAL" attributes on the bridges that originally existed.
+ push_named_attributes_to_curves_and_points(tmp_tb_list, "ORIGINAL");
+ }
- int i, j;
+ DLIList<TopologyBridge*> new_tbs, att_tbs;
+ CubitStatus status = gePtr1->imprint( body_sm_list, vector_list,new_sm_list,
+ keep_old_body, &new_tbs,&att_tbs );
- if(process_composites)
+ temporary_bridges.uniquify_ordered();
+
+ if(process_composites)
+ {
+ // Analyze the results and adjust virtual attributes as necessary.
+ DLIList<TopologyBridge*> tb_list;
+ CAST_LIST(new_sm_list, tb_list, TopologyBridge);
+ tb_list += temporary_bridges;
+ GeometryQueryTool::instance()->ige_attribute_after_imprinting(new_tbs, att_tbs,
+ tb_list, body_list);
+
+ while(temporary_bridges.size())
+ delete temporary_bridges.pop();
+
+ // Clean up attributes.
+ remove_imprint_attributes_after_modify(body_sm_list, new_sm_list);
+
+ // Restore the virtual geometry.
+ restore_vg_after_modify(new_sm_list, body_list, gePtr1);
+ remove_pushed_attributes(new_sm_list, body_list);
+ }
+
+ status = finish_sm_op(body_list, new_sm_list, new_body_list);
+
+ if(process_composites)
+ do_attribute_cleanup();
+
+ if( merge )
{
- // Analyze the results and adjust virtual attributes as necessary.
- GeometryQueryTool::instance()->ige_attribute_after_imprinting(new_tbs, att_tbs,
- new_sm_list, body_list);
+ DLIList<Body*> bodies_to_merge;
+ int i;
+ for( i=new_body_list.size(); i--; )
+ {
+ Body *tmp_body = new_body_list.get_and_step();
+ DLIList<RefEdge*> ref_edge_list;
+ tmp_body->ref_edges( ref_edge_list );
- // Clean up attributes.
- remove_imprint_attributes_after_modify(body_sm_list, new_sm_list);
+ int j;
+ for( j=ref_edge_list.size(); j--; )
+ {
+ RefEdge *tmp_edge = ref_edge_list.get_and_step();
+ DLIList<Body*> body_list;
+ tmp_edge->bodies( body_list );
+ bodies_to_merge.merge_unique( body_list );
+ }
+ }
+ MergeTool::instance()->merge_bodies( bodies_to_merge );
+ }
- // Restore the virtual geometry.
- restore_vg_after_modify(new_sm_list, body_list);
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( status == CUBIT_SUCCESS )
+ CubitUndo::note_result_bodies( new_body_list );
+ else
+ CubitUndo::remove_last_undo();
}
- if (!finish_sm_op(body_list, new_sm_list, new_body_list))
- status = CUBIT_FAILURE;
-
- if(process_composites)
- do_attribute_cleanup();
-
return status;
}
CubitStatus GeometryModifyTool::project_edges( DLIList<RefFace*> &ref_face_list,
DLIList<RefEdge*> &ref_edge_list_in,
- DLIList<RefEdge*> &ref_edge_list_new)
+ DLIList<RefEdge*> &ref_edge_list_new,
+ CubitBoolean trim_projected)
{
+ int i, j;
+
// Check the GeometryEngine for each of the RefEdges; check to
// make sure they're all the same
DLIList<Surface*> surface_list(ref_face_list.size());
@@ -4874,17 +7278,73 @@
CubitStatus status = gme->
project_edges( surface_list, curve_list_in, curve_list_new);
+ if( CubitUndo::get_undo_enabled() && status == CUBIT_SUCCESS )
+ CubitUndo::save_state();
+
+
curve_list_new.reset();
- for (int i = curve_list_new.size(); i--; )
+
+ if(trim_projected){
+ DLIList<Curve*> tmp_curves, all_new_curves;
+ Curve* tmp_curve;
+ Surface* tmp_surface;
+
+ for(i = 0; i< surface_list.size(); i++){
+ tmp_curves.clean_out();
+ tmp_surface = surface_list.get_and_step();
+ for(j=0; j<curve_list_new.size(); j++){
+ tmp_curve = curve_list_new.get_and_step();
+ status = gme->curve_surface_intersection( tmp_surface, tmp_curve, tmp_curves);
+ }
+ all_new_curves += tmp_curves;
+
+ }
+
+ if(!all_new_curves.size()){
+ if(!curve_list_new.size()){
+ PRINT_ERROR("Projection resulted in no curves.\n");
+ return CUBIT_FAILURE;
+ }
+ else{
+ PRINT_WARNING("No curve remained after trimming operation. \n \tCurve projection may lie completely outside of trimmed surface.\n");
+ }
+ }
+
+ //fix this...
+ //can we just cleanout this list or do we need to delete the entities in it.
+ for( i = 0; i< curve_list_new.size(); i++ )
+ {
+ Curve *tmp_curve = curve_list_new.get_and_step();
+ gme->get_gqe()->delete_solid_model_entities( tmp_curve );
+ }
+
+ curve_list_new.clean_out();
+ curve_list_new = all_new_curves;
+
+ if( CubitUndo::get_undo_enabled() && status == CUBIT_SUCCESS )
+ CubitUndo::save_state();
+ }
+
+
+
+ curve_list_new.reset();
+ for (i = curve_list_new.size(); i--; )
{
Curve* curve = curve_list_new.get_and_step();
RefEdge* new_edge = GeometryQueryTool::instance()->make_free_RefEdge(curve);
PRINT_INFO("Created Curve %d\n", new_edge->id());
ref_edge_list_new.append(new_edge);
+ if( CubitUndo::get_undo_enabled() && new_edge )
+ CubitUndo::note_result_entity( new_edge );
}
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( ref_edge_list_new.size() == 0 )
+ CubitUndo::remove_last_undo();
+ }
+
return status;
-
}
CubitStatus
@@ -4916,12 +7376,28 @@
CAST_LIST(query_output, body_list, Body);
DLIList<BodySM*> new_sm_list;
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( keep_old_body )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( ref_face_list );
+ }
+
CubitStatus status = gme->imprint_projected_edges( surface_list, curve_list,
new_sm_list, keep_old_body,keep_free_edges);
if (!finish_sm_op(body_list, new_sm_list, new_body_list))
status = CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( status == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+ else
+ CubitUndo::note_result_bodies( new_body_list );
+ }
+
return status;
}
@@ -5010,7 +7486,10 @@
CubitStatus GeometryModifyTool::webcut_with_sheet( DLIList<Body*> &webcut_body_list,
Body *sheet_body,
DLIList<Body*> &new_bodies,
- CubitBoolean imprint )
+ DLIList<Body*> &neighboring_bodies,
+ ImprintType imprint_type,
+ CubitBoolean merge,
+ CubitBoolean preview)
{
if (!okay_to_modify( webcut_body_list, "WEBCUT" ))
return CUBIT_FAILURE;
@@ -5027,66 +7506,206 @@
return CUBIT_FAILURE;
}
BodySM* tool_sm = body_sm_list.pop();
+
+ DLIList<int> merged_surface_ids;
+ DLIList<int> merged_curve_ids;
+ DLIList<BodySM*> neighbor_imprint_list;
+ DLIList<Body*> bodies_to_modify;
- do_attribute_setup();
+ if (!preview)
+ {
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<Body*> bodies_to_save;
+ bodies_to_save += webcut_body_list;
+ bodies_to_save += neighboring_bodies;
+ CubitUndo::save_state_with_cubit_file( bodies_to_save );
+ }
- push_vg_attributes_before_modify(body_sm_list);
+ int i;
+ for( i=neighboring_bodies.size(); i--; )
+ {
+ Body *neighbor_body = neighboring_bodies.get_and_step();
+ BodySM *tmp_body = neighbor_body->get_body_sm_ptr();
+ GeometryModifyEngine *neighbor_gme = get_engine( tmp_body );
+
+ if( gme == neighbor_gme )
+ neighbor_imprint_list.append( tmp_body );
+ }
+ do_attribute_setup();
+ DLIList<BodySM*> bodies_sm_to_modify;
+ bodies_sm_to_modify += body_sm_list;
+ bodies_sm_to_modify += neighbor_imprint_list;
+ push_vg_attributes_before_modify( bodies_sm_to_modify );
+ bodies_to_modify += webcut_body_list;
+ bodies_to_modify += neighboring_bodies;
+ get_merged_curve_and_surface_ids( bodies_to_modify, merged_surface_ids, merged_curve_ids );
+ }
+
CubitStatus stat = gme->webcut_with_sheet (
- body_sm_list, tool_sm, new_sms, imprint );
+ body_sm_list, tool_sm, neighbor_imprint_list,
+ new_sms, imprint_type, preview );
- restore_vg_after_modify(new_sms, original_body_list);
+ if (!preview)
+ {
+ restore_vg_after_modify(new_sms, bodies_to_modify, gme);
+ remove_pushed_attributes(new_sms, bodies_to_modify );
+ }
- stat = finish_webcut( webcut_body_list, new_sms, false, stat, new_bodies );
- // leave webcut_body_list as we found it -- remove appended tool body
- webcut_body_list.pop();
+ if( stat == CUBIT_FAILURE )
+ {
+ do_attribute_cleanup();
- do_attribute_cleanup();
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ if( stat == CUBIT_SUCCESS )
+ CubitUndo::note_result_bodies( new_bodies );
+ else
+ CubitUndo::remove_last_undo();
+ }
+ return CUBIT_FAILURE;
+ }
+ // finish up if not a preview
+ if (!preview)
+ {
+ stat = finish_webcut( webcut_body_list, new_sms, merge, stat, new_bodies,
+ &merged_surface_ids, &merged_curve_ids );
+ // leave webcut_body_list as we found it -- remove appended tool body
+ webcut_body_list.pop();
+
+ do_attribute_cleanup();
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( stat == CUBIT_SUCCESS )
+ CubitUndo::note_result_bodies( new_bodies );
+ else
+ CubitUndo::remove_last_undo();
+ }
+ }
+
+
return stat;
}
// Calls solid modeling engine to webcut with a sheet body.
-CubitStatus GeometryModifyTool::webcut_with_extended_surf( DLIList<Body*> &webcut_body_list,
- RefFace *extend_from,
+CubitStatus GeometryModifyTool::webcut_with_extended_sheet( DLIList<Body*> &webcut_body_list,
+ DLIList<RefFace*> &ref_face_list,
DLIList<Body*> &new_bodies,
+ DLIList<Body*> &neighboring_bodies,
int &num_cut,
- CubitBoolean imprint )
+ ImprintType imprint_type,
+ CubitBoolean merge,
+ CubitBoolean preview)
{
if (!okay_to_modify( webcut_body_list, "WEBCUT" ))
return CUBIT_FAILURE;
- DLIList<Body*> original_body_list = webcut_body_list;
+ DLIList<RefEntity*> ref_entity_list;
+ CAST_LIST( ref_face_list, ref_entity_list, RefEntity );
+ if( !same_modify_engine( ref_entity_list ) )
+ {
+ PRINT_ERROR( "Extending surfaces from different geometry engines is\n"
+ " not allowed.\n\n" );
+ return CUBIT_FAILURE;
+ }
+
DLIList<BodySM*> body_sm_list(webcut_body_list.size()), new_sms;
GeometryModifyEngine* gme = common_modify_engine(webcut_body_list, body_sm_list);
- Surface* surf_ptr = 0;
- if (gme) {
- TopologyBridge* bridge = extend_from->bridge_manager()->topology_bridge(gme->get_gqe());
- surf_ptr = dynamic_cast<Surface*>(bridge);
+
+ if( !gme )
+ {
+ PRINT_ERROR("Performing WEBCUTS on volumes containing geometry from\n"
+ "different modeling engines is not allowed.\n"
+ "Delete uncommon geometry on these volumes before operation.\n\n");
+ return CUBIT_FAILURE;
}
+ Surface* surf_ptr = 0;
+ TopologyBridge* bridge = ref_face_list.get()->bridge_manager()->topology_bridge(gme->get_gqe());
+ surf_ptr = dynamic_cast<Surface*>(bridge);
+
if ( !surf_ptr )
{
- PRINT_ERROR("Performing WEBCUTS on volumes containing geometry from\n"
- "different modeling engines is not allowed.\n"
+ PRINT_ERROR("Performing WEBCUTS on volumes containing geometry from a\n"
+ "different modeling engine than the extended surfaces is\n"
+ "not allowed.\n"
"Delete uncommon geometry on these volumes before operation.\n\n");
return CUBIT_FAILURE;
}
- do_attribute_setup();
+ GeometryQueryEngine *gqe = gme->get_gqe();
- push_vg_attributes_before_modify(body_sm_list);
+ int i;
+ RefFace *ref_face_ptr;
+ DLIList<Surface*> surf_list;
+ for( i=ref_face_list.size(); i--; )
+ {
+ ref_face_ptr = ref_face_list.get_and_step();
+ bridge = ref_face_ptr->bridge_manager()->topology_bridge(gqe);
+ surf_ptr = dynamic_cast<Surface*>(bridge);
+ surf_list.append( surf_ptr );
+ }
- //change sjs at cat 1/27/04
- CubitStatus stat = gme->webcut_with_extended_surf ( //gmeList.get()->webcut_with_extended_surf (
- body_sm_list, surf_ptr, new_sms, num_cut, imprint );
+ DLIList<int> merged_surface_ids;
+ DLIList<int> merged_curve_ids;
+ DLIList<BodySM*> neighbor_imprint_list;
+ DLIList<Body*> bodies_to_modify;
- restore_vg_after_modify(new_sms, original_body_list);
+ if (!preview)
+ {
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<Body*> bodies_to_save;
+ bodies_to_save += webcut_body_list;
+ bodies_to_save += neighboring_bodies;
+ CubitUndo::save_state_with_cubit_file( bodies_to_save );
+ }
- CubitStatus ret = finish_webcut(webcut_body_list, new_sms, false, stat, new_bodies );
+ int i;
+ for( i=neighboring_bodies.size(); i--; )
+ {
+ Body *neighbor_body = neighboring_bodies.get_and_step();
+ BodySM *tmp_body = neighbor_body->get_body_sm_ptr();
+ GeometryModifyEngine *neighbor_gme = get_engine( tmp_body );
+
+ if( gme == neighbor_gme )
+ neighbor_imprint_list.append( tmp_body );
+ }
- do_attribute_cleanup();
+ do_attribute_setup();
+ DLIList<BodySM*> bodies_sm_to_modify;
+ bodies_sm_to_modify += body_sm_list;
+ bodies_sm_to_modify += neighbor_imprint_list;
+ push_vg_attributes_before_modify( bodies_sm_to_modify );
+ bodies_to_modify += webcut_body_list;
+ bodies_to_modify += neighboring_bodies;
+ get_merged_curve_and_surface_ids( bodies_to_modify, merged_surface_ids, merged_curve_ids );
+ }
- return ret;
+ CubitStatus stat = gme->webcut_with_extended_sheet( body_sm_list,
+ surf_list, neighbor_imprint_list, new_sms, num_cut, imprint_type,
+ preview );
+
+ if (!preview)
+ {
+ restore_vg_after_modify(new_sms, bodies_to_modify, gme);
+ remove_pushed_attributes(new_sms, bodies_to_modify);
+ stat = finish_webcut(webcut_body_list, new_sms, merge, stat, new_bodies,
+ &merged_surface_ids, &merged_curve_ids );
+ do_attribute_cleanup();
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( stat == CUBIT_SUCCESS )
+ CubitUndo::note_result_bodies( new_bodies );
+ else
+ CubitUndo::remove_last_undo();
+ }
+ }
+
+ return stat;
}
@@ -5099,14 +7718,15 @@
RefFace* stop_surf,
bool up_to_next,
DLIList<Body*> &new_bodies,
- CubitBoolean imprint,
- CubitBoolean merge )
+ DLIList<Body*> &neighboring_bodies,
+ ImprintType imprint_type,
+ CubitBoolean merge,
+ CubitBoolean preview)
{
if (!okay_to_modify( webcut_body_list, "WEBCUT" ))
return CUBIT_FAILURE;
- DLIList<Body*> original_body_list = webcut_body_list;
DLIList<BodySM*> body_sm_list(webcut_body_list.size()), new_sms;
GeometryModifyEngine* gme = common_modify_engine(webcut_body_list, body_sm_list);
DLIList<Surface*> surfaces_to_sweep;
@@ -5130,22 +7750,67 @@
}
stop_surface = stop_surf->get_surface_ptr();
- }
+ }
- do_attribute_setup();
+ DLIList<int> merged_surface_ids;
+ DLIList<int> merged_curve_ids;
+ DLIList<BodySM*> neighbor_imprint_list;
+ DLIList<Body*> bodies_to_modify;
- push_vg_attributes_before_modify(body_sm_list);
+ if (!preview)
+ {
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<Body*> bodies_to_save;
+ bodies_to_save += webcut_body_list;
+ bodies_to_save += neighboring_bodies;
+ CubitUndo::save_state_with_cubit_file( bodies_to_save );
+ }
+ int i;
+ for( i=neighboring_bodies.size(); i--; )
+ {
+ Body *neighbor_body = neighboring_bodies.get_and_step();
+ BodySM *tmp_body = neighbor_body->get_body_sm_ptr();
+ GeometryModifyEngine *neighbor_gme = get_engine( tmp_body );
+
+ if( gme == neighbor_gme )
+ neighbor_imprint_list.append( tmp_body );
+ }
+
+ do_attribute_setup();
+ DLIList<BodySM*> bodies_sm_to_modify;
+ bodies_sm_to_modify += body_sm_list;
+ bodies_sm_to_modify += neighbor_imprint_list;
+ push_vg_attributes_before_modify( bodies_sm_to_modify );
+ bodies_to_modify += webcut_body_list;
+ bodies_to_modify += neighboring_bodies;
+ get_merged_curve_and_surface_ids( bodies_to_modify, merged_surface_ids, merged_curve_ids );
+ }
+
CubitStatus stat = gme->webcut_with_sweep_surfaces_rotated(
body_sm_list, surfaces_to_sweep, point, sweep_axis, angle,
- stop_surface, up_to_next, new_sms, imprint );
+ stop_surface, up_to_next, neighbor_imprint_list,
+ new_sms, imprint_type, preview );
- restore_vg_after_modify(new_sms, original_body_list);
+ // if not previewing do the rest of the creation
+ if (!preview)
+ {
+ restore_vg_after_modify(new_sms, bodies_to_modify, gme);
+ remove_pushed_attributes(new_sms, bodies_to_modify);
+ stat = finish_webcut(webcut_body_list, new_sms, merge, stat, new_bodies,
+ &merged_surface_ids, &merged_curve_ids );
+ do_attribute_cleanup();
- stat = finish_webcut(webcut_body_list, new_sms, merge, stat, new_bodies );
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( stat == CUBIT_SUCCESS )
+ CubitUndo::note_result_bodies( new_bodies );
+ else
+ CubitUndo::remove_last_undo();
+ }
+ }
- do_attribute_cleanup();
-
return stat;
}
@@ -5157,14 +7822,15 @@
double angle,
RefFace* stop_surf,
DLIList<Body*> &new_bodies,
- CubitBoolean imprint,
- CubitBoolean merge )
+ DLIList<Body*> &neighboring_bodies,
+ ImprintType imprint_type,
+ CubitBoolean merge,
+ CubitBoolean preview)
{
if (!okay_to_modify( webcut_body_list, "WEBCUT" ))
return CUBIT_FAILURE;
- DLIList<Body*> original_body_list = webcut_body_list;
DLIList<BodySM*> body_sm_list(webcut_body_list.size()), new_sms;
GeometryModifyEngine* gme = common_modify_engine(webcut_body_list, body_sm_list);
DLIList<Curve*> curves_to_sweep;
@@ -5193,19 +7859,65 @@
stop_surface = stop_surf->get_surface_ptr();
}
- do_attribute_setup();
- push_vg_attributes_before_modify(body_sm_list);
+ DLIList<int> merged_surface_ids;
+ DLIList<int> merged_curve_ids;
+ DLIList<BodySM*> neighbor_imprint_list;
+ DLIList<Body*> bodies_to_modify;
+ if (!preview)
+ {
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<Body*> bodies_to_save;
+ bodies_to_save += webcut_body_list;
+ bodies_to_save += neighboring_bodies;
+ CubitUndo::save_state_with_cubit_file( bodies_to_save );
+ }
+
+ int i;
+ for( i=neighboring_bodies.size(); i--; )
+ {
+ Body *neighbor_body = neighboring_bodies.get_and_step();
+ BodySM *tmp_body = neighbor_body->get_body_sm_ptr();
+ GeometryModifyEngine *neighbor_gme = get_engine( tmp_body );
+
+ if( gme == neighbor_gme )
+ neighbor_imprint_list.append( tmp_body );
+ }
+
+ do_attribute_setup();
+ DLIList<BodySM*> bodies_sm_to_modify;
+ bodies_sm_to_modify += body_sm_list;
+ bodies_sm_to_modify += neighbor_imprint_list;
+ push_vg_attributes_before_modify( bodies_sm_to_modify );
+ bodies_to_modify += webcut_body_list;
+ bodies_to_modify += neighboring_bodies;
+ get_merged_curve_and_surface_ids( bodies_to_modify, merged_surface_ids, merged_curve_ids );
+ }
+
+
CubitStatus stat = gme->webcut_with_sweep_curves_rotated(
body_sm_list, curves_to_sweep, point, sweep_axis, angle,
- stop_surface, new_sms, imprint);
+ stop_surface, neighbor_imprint_list,
+ new_sms, imprint_type, preview);
- restore_vg_after_modify(new_sms, original_body_list);
+ if (!preview)
+ {
+ restore_vg_after_modify(new_sms, bodies_to_modify, gme);
+ remove_pushed_attributes(new_sms, bodies_to_modify);
+ stat = finish_webcut(webcut_body_list, new_sms, merge, stat, new_bodies,
+ &merged_surface_ids, &merged_curve_ids );
+ do_attribute_cleanup();
- stat = finish_webcut(webcut_body_list, new_sms, merge, stat, new_bodies );
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( stat == CUBIT_SUCCESS )
+ CubitUndo::note_result_bodies( new_bodies );
+ else
+ CubitUndo::remove_last_undo();
+ }
+ }
- do_attribute_cleanup();
-
return stat;
}
@@ -5217,13 +7929,14 @@
RefFace *stop_surf,
RefEdge* edge_to_sweep_along,
DLIList<Body*> &new_bodies,
- CubitBoolean imprint,
- CubitBoolean merge )
+ DLIList<Body*> &neighboring_bodies,
+ ImprintType imprint_type,
+ CubitBoolean merge,
+ CubitBoolean preview)
{
if (!okay_to_modify( webcut_body_list, "WEBCUT" ))
return CUBIT_FAILURE;
- DLIList<Body*> original_body_list = webcut_body_list;
DLIList<BodySM*> body_sm_list(webcut_body_list.size()), new_sms;
GeometryModifyEngine* gme = common_modify_engine(webcut_body_list, body_sm_list);
DLIList<Curve*> curves_to_sweep;
@@ -5273,19 +7986,64 @@
curve_to_sweep_along = edge_to_sweep_along->get_curve_ptr();
}
- do_attribute_setup();
- push_vg_attributes_before_modify(body_sm_list);
+ DLIList<int> merged_surface_ids;
+ DLIList<int> merged_curve_ids;
+ DLIList<BodySM*> neighbor_imprint_list;
+ DLIList<Body*> bodies_to_modify;
+ if (!preview)
+ {
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<Body*> bodies_to_save;
+ bodies_to_save += webcut_body_list;
+ bodies_to_save += neighboring_bodies;
+ CubitUndo::save_state_with_cubit_file( bodies_to_save );
+ }
+
+ int i;
+ for( i=neighboring_bodies.size(); i--; )
+ {
+ Body *neighbor_body = neighboring_bodies.get_and_step();
+ BodySM *tmp_body = neighbor_body->get_body_sm_ptr();
+ GeometryModifyEngine *neighbor_gme = get_engine( tmp_body );
+
+ if( gme == neighbor_gme )
+ neighbor_imprint_list.append( tmp_body );
+ }
+
+ do_attribute_setup();
+ DLIList<BodySM*> bodies_sm_to_modify;
+ bodies_sm_to_modify += body_sm_list;
+ bodies_sm_to_modify += neighbor_imprint_list;
+ push_vg_attributes_before_modify( bodies_sm_to_modify );
+ bodies_to_modify += webcut_body_list;
+ bodies_to_modify += neighboring_bodies;
+ get_merged_curve_and_surface_ids( bodies_to_modify, merged_surface_ids, merged_curve_ids );
+ }
+
CubitStatus stat = gme->webcut_with_sweep_curves(
body_sm_list, curves_to_sweep, sweep_vector, through_all,
- stop_surface, curve_to_sweep_along, new_sms, imprint );
+ stop_surface, curve_to_sweep_along, neighbor_imprint_list,
+ new_sms, imprint_type, preview );
- restore_vg_after_modify(new_sms, original_body_list);
+ if (!preview)
+ {
+ restore_vg_after_modify(new_sms, bodies_to_modify, gme);
+ remove_pushed_attributes(new_sms, bodies_to_modify);
+ stat = finish_webcut(webcut_body_list, new_sms, merge, stat, new_bodies,
+ &merged_surface_ids, &merged_curve_ids );
+ do_attribute_cleanup();
- stat = finish_webcut(webcut_body_list, new_sms, merge, stat, new_bodies );
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( stat == CUBIT_SUCCESS )
+ CubitUndo::note_result_bodies( new_bodies );
+ else
+ CubitUndo::remove_last_undo();
+ }
+ }
- do_attribute_cleanup();
-
return stat;
}
@@ -5300,13 +8058,14 @@
RefFace* stop_surf,
RefEdge* edge_to_sweep_along,
DLIList<Body*> &new_bodies,
- CubitBoolean imprint,
- CubitBoolean merge )
+ DLIList<Body*> &neighboring_bodies,
+ ImprintType imprint_type,
+ CubitBoolean merge,
+ CubitBoolean preview)
{
if (!okay_to_modify( webcut_body_list, "WEBCUT" ))
return CUBIT_FAILURE;
- DLIList<Body*> original_body_list = webcut_body_list;
DLIList<BodySM*> body_sm_list(webcut_body_list.size()), new_sms;
GeometryModifyEngine* gme = common_modify_engine(webcut_body_list, body_sm_list);
DLIList<Surface*> surfaces_to_sweep;
@@ -5350,25 +8109,125 @@
return CUBIT_FAILURE;
}
+ //make sure that the curve is not part of the surface(s) being swept
+ DLIList<RefFace*> faces_of_edge;
+ edge_to_sweep_along->ref_faces( faces_of_edge );
+
+ int kk;
+ for( kk=faces_of_edge.size(); kk--; )
+ {
+ if( tool_faces.is_in_list( faces_of_edge.get_and_step() ) )
+ {
+ faces_of_edge.back();
+ PRINT_ERROR("Cannot perform sweep. Curve %d is in Surface %d\n",
+ edge_to_sweep_along->id(), faces_of_edge.get()->id() );
+ return CUBIT_FAILURE;
+ }
+ }
+
curve_to_sweep_along = edge_to_sweep_along->get_curve_ptr();
}
- do_attribute_setup();
- push_vg_attributes_before_modify(body_sm_list);
+ DLIList<BodySM*> neighbor_imprint_list;
+ DLIList<int> merged_surface_ids;
+ DLIList<int> merged_curve_ids;
+ DLIList<Body*> bodies_to_modify;
+ if (!preview)
+ {
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<Body*> bodies_to_save;
+ bodies_to_save += webcut_body_list;
+ bodies_to_save += neighboring_bodies;
+ CubitUndo::save_state_with_cubit_file( bodies_to_save );
+ }
+
+ int i;
+ for( i=neighboring_bodies.size(); i--; )
+ {
+ Body *neighbor_body = neighboring_bodies.get_and_step();
+ BodySM *tmp_body = neighbor_body->get_body_sm_ptr();
+ GeometryModifyEngine *neighbor_gme = get_engine( tmp_body );
+
+ if( gme == neighbor_gme )
+ neighbor_imprint_list.append( tmp_body );
+ }
+
+ do_attribute_setup();
+ DLIList<BodySM*> bodies_sm_to_modify;
+ bodies_sm_to_modify += body_sm_list;
+ bodies_sm_to_modify += neighbor_imprint_list;
+ push_vg_attributes_before_modify( bodies_sm_to_modify );
+ bodies_to_modify += webcut_body_list;
+ bodies_to_modify += neighboring_bodies;
+ get_merged_curve_and_surface_ids( bodies_to_modify, merged_surface_ids, merged_curve_ids );
+ }
+
CubitStatus stat = gme->webcut_with_sweep_surfaces(
body_sm_list, surfaces_to_sweep, sweep_vector, sweep_perp, through_all, outward,
- up_to_next, stop_surface, curve_to_sweep_along, new_sms, imprint );
+ up_to_next, stop_surface, curve_to_sweep_along, neighbor_imprint_list,
+ new_sms, imprint_type, preview );
- restore_vg_after_modify(new_sms, original_body_list);
+ if (!preview)
+ {
+ restore_vg_after_modify(new_sms, bodies_to_modify, gme);
+ remove_pushed_attributes(new_sms, bodies_to_modify);
+ stat = finish_webcut(webcut_body_list, new_sms, merge, stat, new_bodies,
+ &merged_surface_ids, &merged_curve_ids );
+ do_attribute_cleanup();
- stat = finish_webcut(webcut_body_list, new_sms, merge, stat, new_bodies );
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( stat == CUBIT_SUCCESS )
+ CubitUndo::note_result_bodies( new_bodies );
+ else
+ CubitUndo::remove_last_undo();
+ }
+ }
- do_attribute_cleanup();
-
return stat;
}
+CubitStatus GeometryModifyTool::split_free_curve( RefEdge *ref_edge,
+ CubitVector &split_location )
+{
+ TopologyBridge* bridge = 0;
+ GeometryModifyEngine* gme_ptr = get_engine(ref_edge, &bridge);
+ Curve *new_curve = 0, *curve = dynamic_cast<Curve*>(bridge);
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<RefEdge*> tmp_ents(1);
+ tmp_ents.append( ref_edge );
+ CubitUndo::save_state_with_cubit_file( tmp_ents );
+ }
+
+ DLIList<Curve*> new_curves;
+ gme_ptr->split_free_curve( curve, split_location, new_curves );
+
+ if (!new_curves.size())
+ {
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
+ return CUBIT_FAILURE;
+ }
+
+ GeometryQueryTool::instance()->delete_RefEdge( ref_edge );
+
+ int i;
+ for( i=0; i<new_curves.size(); i++ )
+ {
+ Curve *new_curve = new_curves.get_and_step();
+ RefEdge* new_edge = GeometryQueryTool::instance()->make_free_RefEdge(new_curve);
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::note_result_entity( new_edge );
+ }
+
+ return CUBIT_SUCCESS;
+}
+
+
//-------------------------------------------------------------------------
// Purpose : split a multiple volume body into several bodies
// each containing a single volume.
@@ -5382,88 +8241,224 @@
CubitStatus GeometryModifyTool::split_body( Body *body_ptr,
DLIList<Body*> &new_bodies ) const
{
- int i;
- DLIList<RefVolume*> ref_vols;
- body_ptr->ref_volumes(ref_vols);
- if ( ref_vols.size() < 2 )
- {
- //no need to split...
- new_bodies.append(body_ptr);
- return CUBIT_SUCCESS;
- }
+ int i;
+ DLIList<RefVolume*> ref_vols;
+ body_ptr->ref_volumes(ref_vols);
+ if ( ref_vols.size() < 2 )
+ {
+ //no need to split...
+ new_bodies.append(body_ptr);
+ return CUBIT_SUCCESS;
+ }
- DLIList<Body*> b_list;
- b_list.append(body_ptr);
- if (!okay_to_modify( b_list, "SPLIT" ))
- return CUBIT_FAILURE;
+ DLIList<Body*> b_list;
+ b_list.append(body_ptr);
+ if (!okay_to_modify( b_list, "SPLIT" ))
+ return CUBIT_FAILURE;
- // Call the owning GeometryModifyEngine to split the body
- // so that there is one volume per body.
- BodySM* bodysm_ptr = body_ptr->get_body_sm_ptr();
- GeometryModifyEngine* engine_ptr = get_engine(bodysm_ptr);
- if (!engine_ptr) {
- PRINT_ERROR("There is no modify engine available for this volume."
- " Volume cannot be split.\n");
- return CUBIT_FAILURE;
- }
+ // Call the owning GeometryModifyEngine to split the body
+ // so that there is one volume per body.
+ BodySM* bodysm_ptr = body_ptr->get_body_sm_ptr();
+ GeometryModifyEngine* engine_ptr = get_engine(bodysm_ptr);
+ if (!engine_ptr) {
+ PRINT_ERROR("There is no modify engine available for this volume."
+ " Volume cannot be split.\n");
+ return CUBIT_FAILURE;
+ }
- DLIList<BodySM*> new_sm_list;
- CubitStatus stat = engine_ptr->split_body( bodysm_ptr, new_sm_list );
- if ( new_sm_list.size() == 0 )
- {
- PRINT_ERROR("failed in splitting volumes, orginal was lost.\n");
- GeometryQueryTool::instance()->destroy_dead_entity(body_ptr);
- return CUBIT_FAILURE;
- }
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<Body*> bodies(1);
+ bodies.append( body_ptr );
+ CubitUndo::save_state_with_cubit_file( bodies );
+ }
- bodysm_ptr = body_ptr->get_body_sm_ptr();
- if (bodysm_ptr)
- {
- remove_dead_entity_names(body_ptr);
- body_ptr = GeometryQueryTool::instance()->make_Body(bodysm_ptr);
- }
- else
- {
- GeometryQueryTool::instance()->destroy_dead_entity(body_ptr);
- }
+ DLIList<BodySM*> new_sm_list;
+ CubitStatus stat = engine_ptr->split_body( bodysm_ptr, new_sm_list );
+ if ( new_sm_list.size() == 0 )
+ {
+ PRINT_ERROR("failed in splitting volumes, orginal was lost.\n");
+ GeometryQueryTool::instance()->destroy_dead_entity(body_ptr);
+ return CUBIT_FAILURE;
+ }
- new_sm_list.reset();
- for (i = new_sm_list.size(); i--; )
- {
- bodysm_ptr = new_sm_list.get_and_step();
- Body* body = GeometryQueryTool::instance()->make_Body(bodysm_ptr);
- new_bodies.append(body);
- }
+ bodysm_ptr = body_ptr->get_body_sm_ptr();
+ if (bodysm_ptr)
+ {
+ remove_dead_entity_names(body_ptr);
+ body_ptr = GeometryQueryTool::instance()->make_Body(bodysm_ptr);
+ }
+ else
+ {
+ GeometryQueryTool::instance()->destroy_dead_entity(body_ptr);
+ }
- if ( !GeometryModifyTool::instance()->get_new_ids())
- {
- //Now reuse the body ids.
- DLIList<RefVolume*> new_ref_vols;
- for ( int ii = new_bodies.size(); ii > 0; ii-- )
- {
- Body *temp_body = new_bodies.get_and_step();
- new_ref_vols.clean_out();
- temp_body->ref_volumes(new_ref_vols);
- int vol_id = new_ref_vols.get()->id();
- if ( temp_body->id() != vol_id )
- {
- //Check to see if this id is being used by
- //some other body.
- if ( RefEntityFactory::instance()->get_body(vol_id) == NULL )
- {
- temp_body->set_id(vol_id);
- }
- //if it is in use, then we shouldn't mess around with it...
- }
+ new_sm_list.reset();
+ for (i = new_sm_list.size(); i--; )
+ {
+ bodysm_ptr = new_sm_list.get_and_step();
+ Body* body = GeometryQueryTool::instance()->make_Body(bodysm_ptr);
+ new_bodies.append(body);
+ }
- }
- }
+ if ( !GeometryModifyTool::instance()->get_new_ids())
+ {
+ //Now reuse the body ids.
+ DLIList<RefVolume*> new_ref_vols;
+ for ( int ii = new_bodies.size(); ii > 0; ii-- )
+ {
+ Body *temp_body = new_bodies.get_and_step();
+ new_ref_vols.clean_out();
+ temp_body->ref_volumes(new_ref_vols);
+ int vol_id = new_ref_vols.get()->id();
+ if ( temp_body->id() != vol_id )
+ {
+ //Check to see if this id is being used by
+ //some other body.
+ if ( RefEntityFactory::instance()->get_body(vol_id) == NULL )
+ {
+ temp_body->set_id(vol_id);
+ }
+ //if it is in use, then we shouldn't mess around with it...
+ }
+ }
+ }
- GeometryQueryTool::instance()->cleanout_deactivated_geometry();
- return stat;
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::note_result_bodies( new_bodies );
+
+ GeometryQueryTool::instance()->cleanout_deactivated_geometry();
+ return stat;
}
//-------------------------------------------------------------------------
+// Purpose : Separate surfaces from a sheet body into separate bodies.
+// Connected surfaces will remain united but be placed in
+// a new body.
+//
+// Special Notes :
+//
+// Creator : Steve Storm
+//
+// Creation Date : 02/23/2008
+//-------------------------------------------------------------------------
+CubitStatus
+GeometryModifyTool::separate_surfaces( DLIList<RefFace*> &ref_face_list,
+ DLIList<Body*> &new_bodies )
+{
+ int i;
+ RefFace *ref_face_ptr;
+
+ for( i=ref_face_list.size(); i--; )
+ {
+ ref_face_ptr = ref_face_list.get();
+
+ // Check for no body
+ DLIList<Body*> body_list;
+ ref_face_ptr->bodies( body_list );
+ if( body_list.size()==0 )
+ {
+ PRINT_ERROR( "Surface %d is not contained within a parent body.\n"
+ " It cannot be separated.\n", ref_face_ptr->id() );
+ return CUBIT_FAILURE;
+ }
+ }
+
+ // Check for virtual geometry
+ DLIList<RefEntity*> ref_ent_list;
+ CAST_LIST_TO_PARENT(ref_face_list, ref_ent_list);
+ if ( GeometryQueryTool::instance()->contains_intermediate_geometry(ref_ent_list) )
+ {
+ PRINT_ERROR("SEPARATING surfaces containing virtual geometry is not\n"
+ " allowed. Delete virtual geometry on these surfaces\n"
+ " before operation.\n" );
+ return CUBIT_FAILURE;
+ }
+
+ // Prep for undo
+ DLIList<Body*> body_list;
+ for( i=ref_face_list.size(); i--; )
+ ref_face_list.get_and_step()->bodies( body_list );
+ body_list.uniquify_unordered();
+
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state_with_cubit_file( body_list );
+
+ // Handle surfaces from different modify engines. Copy the input list since
+ // we will be pulling RefFaces out of it.
+ DLIList<RefFace*> copied_ref_face_list = ref_face_list;
+
+ // Keep track of errors and success
+ int error_occurred = 0;
+ int successful_case = 0;
+
+ GeometryModifyEngine *gme_ptr;
+ while( copied_ref_face_list.size() )
+ {
+ // Need to send in Surfaces
+ DLIList<Surface*> surface_list;
+ DLIList<RefFace*> gme_face_list;
+
+ gme_ptr = pull_common_surfs( copied_ref_face_list, gme_face_list,
+ surface_list );
+ if( !gme_ptr )
+ return CUBIT_FAILURE;
+
+ // Get the owning bodies of the faces...needed for finish_sm_op
+ DLIList<Body*> gme_body_list;
+ for( i=gme_face_list.size(); i--; )
+ gme_face_list.get_and_step()->bodies( gme_body_list );
+ gme_body_list.uniquify_unordered();
+
+ DLIList<BodySM*> new_sm_list;
+ DLIList<Body*> new_body_list;
+ if( gme_ptr->separate_surfaces( surface_list, new_sm_list ) == CUBIT_FAILURE ||
+ finish_sm_op(gme_body_list, new_sm_list, new_body_list ) == CUBIT_FAILURE )
+ {
+ error_occurred++;
+ continue;
+ }
+
+ new_bodies += new_body_list;
+ successful_case++;
+ }
+
+ if( error_occurred && !successful_case )
+ return CUBIT_FAILURE;
+
+ // Following is copied from split_body - to keep same behavior. When all
+ // surfaces are separated from a given body, separate_surfaces just separates
+ // the body. Without the code below we get new body ids.
+ if ( !GeometryModifyTool::instance()->get_new_ids())
+ {
+ //Now reuse the body ids.
+ DLIList<RefVolume*> new_ref_vols;
+ for ( int ii = new_bodies.size(); ii > 0; ii-- )
+ {
+ Body *temp_body = new_bodies.get_and_step();
+ new_ref_vols.clean_out();
+ temp_body->ref_volumes(new_ref_vols);
+ int vol_id = new_ref_vols.get()->id();
+ if ( temp_body->id() != vol_id )
+ {
+ //Check to see if this id is being used by
+ //some other body.
+ if ( RefEntityFactory::instance()->get_body(vol_id) == NULL )
+ {
+ temp_body->set_id(vol_id);
+ }
+ //if it is in use, then we shouldn't mess around with it...
+ }
+ }
+ }
+
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::note_result_bodies( new_bodies );
+
+ return CUBIT_SUCCESS;
+}
+
+//-------------------------------------------------------------------------
// Purpose : Reverse a body
//
// Special Notes : Moved from Body
@@ -5472,30 +8467,123 @@
//
// Creation Date :
//-------------------------------------------------------------------------
-CubitStatus GeometryModifyTool::reverse( Body* body )
+CubitStatus GeometryModifyTool::reverse( DLIList<Body*> &body_list )
{
- BodySM* body_sm = body->get_body_sm_ptr();
- GeometryModifyEngine* gme = get_engine( body_sm );
- if (!gme) {
- PRINT_ERROR("Body %d does not have a modify engine.\n", body->id());
- return CUBIT_FAILURE;
+ DLIList<Body*> reversed_bodies;
+ int i;
+ for( i=body_list.size(); i--; )
+ {
+ Body *body = body_list.get_and_step();
+ BodySM* body_sm = body->get_body_sm_ptr();
+ GeometryModifyEngine* gme = get_engine( body_sm );
+ if (!gme) {
+ PRINT_ERROR("Body %d does not have a modify engine.\n", body->id());
+ continue;
+ }
+
+ CubitStatus stat = gme->reverse_body( body_sm );
+
+ if ( CUBIT_SUCCESS != stat )
+ {
+ PRINT_ERROR("Reverse failed.\n");
+ continue;
+ }
+ else
+ {
+ reversed_bodies.append( body );
+ GeometryQueryTool::instance()->make_Body( body_sm );
+ body->notify_all_observers( GEOMETRY_MODIFIED );
+ PRINT_INFO("Reversed body %d.\n", body->id());
+ continue;
+ }
}
- CubitStatus stat = gme->reverse_body( body_sm );
- if ( CUBIT_SUCCESS != stat )
+ if( CubitUndo::get_undo_enabled() )
{
- PRINT_ERROR("Reverse failed.\n");
- return CUBIT_FAILURE;
+ CubitString undo_command("reverse body ");
+ for( i=reversed_bodies.size(); i--; )
+ {
+ undo_command += reversed_bodies.get_and_step()->id();
+ undo_command += " ";
+ }
+ CubitUndo::set_undo_by_command( undo_command );
}
- else
- {
- GeometryQueryTool::instance()->make_Body( body_sm );
- body->notify_all_observers( GEOMETRY_MODIFIED );
- PRINT_INFO("Reversed body %d.\n", body->id());
- return CUBIT_SUCCESS;
- }
+
+ return CUBIT_SUCCESS;
}
+//===============================================================================
+// Function : reverse
+// Member Type: PUBLIC
+// Description: Reverse given surfaces (flip normals)
+// Author : Steve Storm (CAT)
+// Date : 4/3/2007
+//===============================================================================
+CubitStatus GeometryModifyTool::reverse( DLIList<RefFace*> &ref_face_list )
+{
+ // Check for virtual geometry
+ DLIList<RefEntity*> ref_ent_list;
+ CAST_LIST_TO_PARENT(ref_face_list, ref_ent_list);
+ if( GeometryQueryTool::instance()->contains_intermediate_geometry(ref_ent_list) )
+ {
+ PRINT_ERROR("REVERSING surfaces containing virtual geometry is not\n"
+ " allowed. Delete virtual geometry on surfaces before\n"
+ " operation.\n" );
+ return CUBIT_FAILURE;
+ }
+
+ // Get the owning bodies of the faces
+ int i;
+ DLIList<Body*> body_list;
+ for( i=ref_face_list.size(); i--; )
+ ref_face_list.get_and_step()->bodies( body_list );
+ body_list.uniquify_unordered();
+
+ // Handle surfaces from different modify engines. Copy the input list since
+ // we will be pulling RefFaces out of it.
+ DLIList<RefFace*> copied_ref_face_list = ref_face_list;
+
+ // Keep track of overall errors and successes
+ int error_occurred = 0;
+ int successful_case = 0;
+ GeometryModifyEngine *gme_ptr;
+
+ while( copied_ref_face_list.size() )
+ {
+ // Need to send in Surfaces
+ DLIList<Surface*> surface_list;
+ DLIList<RefFace*> common_face_list;
+
+ gme_ptr = pull_common_surfs( copied_ref_face_list, common_face_list,
+ surface_list );
+ if( !gme_ptr )
+ return CUBIT_FAILURE;
+
+ if( gme_ptr->flip_normals( surface_list ) == CUBIT_FAILURE )
+ error_occurred = 1;
+ else
+ successful_case = 1;
+ }
+
+ if( error_occurred && !successful_case )
+ return CUBIT_FAILURE;
+
+ // Update the impacted bodies
+ Body *body_ptr;
+ BodySM* body_sm_ptr;
+ DLIList<BodySM*> new_sm_list;
+ for( i=body_list.size(); i--; )
+ {
+ body_ptr = body_list.get_and_step();
+ body_ptr->notify_all_observers( GEOMETRY_MODIFIED );
+ body_sm_ptr = body_ptr->get_body_sm_ptr();
+ new_sm_list.append( body_sm_ptr );
+ }
+
+ DLIList<Body*> new_body_list;
+ return finish_sm_op(body_list, new_sm_list, new_body_list );
+}
+
//-------------------------------------------------------------------------
// Purpose : split a periodic surface.
//
@@ -5523,15 +8611,44 @@
BodySM* new_sm = 0;
- // Call the default GeometryModifyEngine to create a new Point
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::save_state_with_cubit_file(b_list);
+
+ DLIList<BodySM*> body_sms;
+ body_sms.append(body_sm);
+
+ do_attribute_setup();
+ push_vg_attributes_before_modify(body_sms);
+
+ // Call the default GeometryModifyEngine to create a new Point
CubitStatus stat = gme->split_periodic( body_sm, new_sm );
+ DLIList<BodySM*> new_bodysm_list;
+ if(new_sm)
+ new_bodysm_list.append(new_sm);
+ DLIList<Body*> old_body_list;
+ old_body_list.append(body_ptr);
+ restore_vg_after_modify(new_bodysm_list, old_body_list, gme);
+ remove_pushed_attributes(new_bodysm_list, old_body_list);
+ do_attribute_cleanup();
+
update_body(body_ptr);
new_body_ptr = 0;
if (new_sm)
new_body_ptr = GeometryQueryTool::instance()->make_Body(new_sm);
+ if (new_body_ptr)
+ {
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::note_result_body(new_body_ptr);
+ }
+ else
+ {
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::remove_last_undo();
+ }
+
GeometryQueryTool::instance()->cleanout_deactivated_geometry();
return stat;
@@ -5549,22 +8666,27 @@
DLIList<CubitVector*> &locations,
DLIList<DLIList<CubitVector*>*> &vec_lists,
CubitBoolean preview_flg,
- CubitBoolean create_ref_edges_flg )
+ CubitBoolean create_ref_edges_flg,
+ CubitBoolean clear_previous_previews )
{
// Check for virtual geometry
DLIList<RefFace*> ref_face_list;
ref_face_list.append( ref_face_ptr );
- DLIList<RefEntity*> ref_ent_list;
- CAST_LIST_TO_PARENT(ref_face_list, ref_ent_list);
- if( GeometryQueryTool::instance()->contains_intermediate_geometry(ref_ent_list) )
+ DLIList<Body*> b_list;
+ Body* body = ref_face_ptr->body();
+ if (body)
+ b_list.append(body);
+ else
{
- PRINT_ERROR("SPLITTING surfaces containing virtual geometry is not\n"
- " allowed. Delete virtual geometry on surface %d before\n"
- " operation.\n", ref_face_ptr->id() );
- return CUBIT_FAILURE;
+ PRINT_ERROR( "Surface %d is not contained within a parent body.\n"
+ " It cannot be split.\n", ref_face_ptr->id() );
+ return CUBIT_FAILURE;
}
+ if (!okay_to_modify( b_list, "SPLIT_SURFACE" ))
+ return CUBIT_FAILURE;
+
int i;
DLIList<Body*> old_body_list;
for( i=ref_face_list.size(); i--; )
@@ -5587,12 +8709,131 @@
SplitSurfaceTool sst;
if( preview_flg == CUBIT_TRUE )
- return sst.preview( ref_face_ptr, locations, vec_lists, create_ref_edges_flg );
+ return sst.preview( ref_face_ptr, locations, vec_lists, create_ref_edges_flg,
+ clear_previous_previews );
else
- return sst.split_surface( ref_face_ptr, locations, vec_lists );
+ return sst.split_surface( ref_face_ptr, vec_lists );
}
//===============================================================================
+// Function : split_surface
+// Member Type: PUBLIC
+// Description: Split multiple surfaces
+// Author : Greg Schebler (CAT)
+// Date : 06/08
+//===============================================================================
+
+CubitStatus
+GeometryModifyTool::split_surface( DLIList<RefFace*> &ref_face_list,
+ DLIList<CubitVector*> &locations,
+ DLIList<DLIList<DLIList<CubitVector*>*>*> &list_of_vec_lists,
+ CubitBoolean preview_flg,
+ CubitBoolean create_ref_edges_flg,
+ CubitBoolean clear_previous_previews )
+{
+ // Check for virtual geometry
+ DLIList<Body*> b_list;
+ int gg;
+ for( gg = ref_face_list.size() ; gg > 0 ; gg--)
+ {
+ RefFace* ref_face_ptr = ref_face_list.get_and_step();
+ Body* body = ref_face_ptr->body();
+ if (body)
+ b_list.append(body);
+ else
+ {
+ PRINT_ERROR( "Surface %d is not contained within a parent body.\n"
+ " It cannot be split.\n", ref_face_ptr->id() );
+ return CUBIT_FAILURE;
+ }
+ }
+ if (!okay_to_modify( b_list, "SPLIT_SURFACE" ))
+ return CUBIT_FAILURE;
+
+ int ii;
+
+ for( ii = ref_face_list.size(); ii > 0 ; ii--)
+ {
+ DLIList<Body*> old_body_list;
+ RefFace* ref_face_ptr = ref_face_list.get_and_step();
+
+ DLIList<Body*> body_list;
+ ref_face_ptr->bodies( body_list );
+ old_body_list.merge_unique( body_list );
+
+ if( old_body_list.size() < 1 )
+ {
+ PRINT_ERROR( "Surface %d is not contained within a parent body\n."
+ " It cannot be split.\n", ref_face_ptr->id() );
+ return CUBIT_FAILURE;
+ }
+ }
+
+ SplitSurfaceTool sst;
+ if( preview_flg == CUBIT_TRUE )
+ return sst.preview( ref_face_list, locations, list_of_vec_lists, create_ref_edges_flg,
+ clear_previous_previews );
+ else
+ return sst.split_surface( ref_face_list, list_of_vec_lists );
+}
+
+//===============================================================================
+// Function : split_surfaces_extend
+// Member Type: PUBLIC
+// Description: Split surfaces by extending hardline curves on the surface
+// Author : Steve Storm (CAT)
+// Date : 10/07
+//===============================================================================
+CubitStatus
+GeometryModifyTool::split_surfaces_extend( DLIList<RefFace*> &ref_face_list,
+ DLIList<RefVertex*> &ref_vertex_list,
+ CubitBoolean preview_flg,
+ CubitBoolean create_ref_edges_flg )
+{
+ int i;
+ RefFace *ref_face_ptr;
+
+ for( i=ref_face_list.size(); i--; )
+ {
+ ref_face_ptr = ref_face_list.get();
+
+ // Check for no body
+ DLIList<Body*> body_list;
+ ref_face_ptr->bodies( body_list );
+ if( body_list.size()==0 )
+ {
+ PRINT_ERROR( "Surface %d is not contained within a parent body.\n"
+ " It cannot be split.\n", ref_face_ptr->id() );
+ return CUBIT_FAILURE;
+ }
+ }
+
+ // Check for virtual geometry
+ DLIList<RefEntity*> ref_ent_list;
+ CAST_LIST_TO_PARENT(ref_face_list, ref_ent_list);
+ if ( GeometryQueryTool::instance()->contains_intermediate_geometry(ref_ent_list) )
+ {
+ PRINT_ERROR("SPLITTING surfaces containing virtual geometry is not\n"
+ " allowed. Delete virtual geometry on these surfaces\n"
+ " before operation.\n" );
+ return CUBIT_FAILURE;
+ }
+
+ // Make sure all surfaces are from same geometry engine
+ if ( !same_modify_engine(ref_ent_list, CUBIT_TRUE) )
+ {
+ PRINT_ERROR("Performing SPLIT with surfaces containing geometry from\n"
+ "different modeling engines is not allowed.\n"
+ "Delete uncommon geometry on these surfaces before operation.\n\n");
+ return CUBIT_FAILURE;
+ }
+
+ SplitSurfaceTool sst;
+ return sst.split_surfaces_extend( ref_face_list, ref_vertex_list,
+ preview_flg, create_ref_edges_flg );
+}
+
+//===============================================================================
// Function : split_surfaces
// Member Type: PUBLIC
// Description: Split a chain of surfaces into one or more pieces
@@ -5740,6 +8981,84 @@
create_ref_edges_flg);
}
+//===============================================================================
+// Function : auto_mid_surface
+// Member Type: PUBLIC
+// Description: Automatically midsurface a volume
+// Author : Sam Showman (CAT)
+// Date : 12/07
+//===============================================================================
+CubitStatus
+GeometryModifyTool::auto_mid_surface(DLIList<Body*> &body_list_in,
+ DLIList<Body*> &body_list_out,
+ DLIList<Body*> &old_bodies_midsurfaced,
+ DLIList<double> &thickness_list,
+ double lower_tol,
+ double upper_tol,
+ CubitBoolean delete_midsurfaced,
+
+ CubitBoolean preview)
+{
+ // Check for virtual geometry
+ DLIList<RefEntity*> ref_ent_list;
+ CAST_LIST_TO_PARENT(body_list_in, ref_ent_list);
+ if ( GeometryQueryTool::instance()->contains_intermediate_geometry(ref_ent_list) )
+ {
+ PRINT_ERROR("Midsurfacing volumes containing virtual geometry is not\n"
+ " allowed. Delete virtual geometry on these surfaces\n"
+ " before operation.\n" );
+ return CUBIT_FAILURE;
+ }
+
+ // Make sure all surfaces are from same geometry engine
+ if ( !same_modify_engine(ref_ent_list, CUBIT_TRUE) )
+ {
+ PRINT_ERROR("Performing Midsurface with geometry from\n"
+ "different modeling engines is not allowed.\n");
+ return CUBIT_FAILURE;
+ }
+
+ AutoMidsurfaceTool mid_tool;
+ DLIList<BodySM*> bodysm_list_out;
+
+ if (CubitUndo::get_undo_enabled() && delete_midsurfaced && !preview)
+ CubitUndo::save_state_with_cubit_file(body_list_in);
+
+ CubitStatus result = mid_tool.midsurface(
+ body_list_in,
+ bodysm_list_out,
+ old_bodies_midsurfaced,
+ thickness_list,
+ lower_tol,
+ upper_tol,
+ delete_midsurfaced,
+ preview);
+
+
+ if (result == CUBIT_SUCCESS &&
+ bodysm_list_out.size() > 0 &&
+ !preview)
+ {
+ if(CubitUndo::get_undo_enabled())
+ CubitUndo::save_state();
+
+ for( int i=0; i<bodysm_list_out.size(); i++ )
+ {
+ body_list_out.append(GeometryQueryTool::instance()->make_Body(bodysm_list_out[i]));
+ }
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( body_list_out.size() )
+ CubitUndo::note_result_bodies( body_list_out );
+ else
+ CubitUndo::remove_last_undo();
+ }
+ }
+
+ return result;
+}
+
//-------------------------------------------------------------------------
// Purpose : clean RefEntity
//
@@ -5751,35 +9070,99 @@
//-------------------------------------------------------------------------
CubitStatus
-GeometryModifyTool::regularize_refentity(RefEntity *old_entity_ptr,
- Body *&new_body_ptr)
+GeometryModifyTool::regularize_refentity(RefEntity *old_entity_ptr, Body *&new_body_ptr)
{
+ BasicTopologyEntity* bte_ptr = dynamic_cast<BasicTopologyEntity*>(old_entity_ptr);
+ if (!bte_ptr)
+ {
+ PRINT_ERROR("Invalid entity passed to regularize_refentity(..)\n");
+ return CUBIT_FAILURE;
+ }
+
+ DLIList<Body*> body_list;
+ bte_ptr->bodies(body_list);
+
+ //ignore free entities
+ if( body_list.size() == 0 )
+ {
+ PRINT_ERROR("%s %d is a free entity. Cannot regularize it.\n", old_entity_ptr->class_name(),
+ old_entity_ptr->id() );
+ new_body_ptr = NULL;
+ return CUBIT_FAILURE;
+ }
+
+ if (!okay_to_modify( body_list, "REGULARIZE" ))
+ return CUBIT_FAILURE;
+
+ DLIList<TopologyBridge*> bridge_list;
+ bte_ptr->bridge_manager()->get_bridge_list(bridge_list);
+ bridge_list.reset();
+
+ DLIList<BodySM*> new_sm_list;
+ DLIList<Body*> new_body_list;
+ CubitStatus stat = CUBIT_SUCCESS;
+
+ do_attribute_setup();
+
+ GeometryModifyEngine *save_gme = NULL;
+ for (int i = bridge_list.size(); i--; )
+ {
+ TopologyBridge* bridge = bridge_list.get_and_step();
+ GeometryEntity* geom_ptr = dynamic_cast<GeometryEntity*>(bridge);
+ GeometryModifyEngine* gme = get_engine(geom_ptr);
+ if(!save_gme)
+ save_gme = gme;
+ if (!gme) continue;
+
+ DLIList<BodySM*> body_sm_list;
+ geom_ptr->bodysms(body_sm_list);
+ push_vg_attributes_before_modify(body_sm_list);
+
+ BodySM *new_body_sm = NULL;
+ if (!gme->regularize_entity( geom_ptr, new_body_sm ))
+ stat = CUBIT_FAILURE;
+
+ if (new_body_sm)
+ new_sm_list.append(new_body_sm);
+ }
+
+ // This is bad in that it assumes all of the gmes will be the
+ // same but I don't know that we truly support the other case
+ // anyway.
+ if(new_sm_list.size())
+ {
+ restore_vg_after_modify(new_sm_list, body_list, save_gme);
+ remove_pushed_attributes(new_sm_list, body_list);
+ }
+
+ if (!finish_sm_op(body_list, new_sm_list, new_body_list))
+ stat = CUBIT_FAILURE;
+
+ do_attribute_cleanup();
+
+ new_body_ptr = new_body_list.size() ? new_body_list.get() : 0;
+ return stat;
+}
+
+CubitStatus GeometryModifyTool::test_regularize_refentity(RefEntity *old_entity_ptr)
+{
DLIList<RefEntity*> tmp_ref_ent_list(1);
tmp_ref_ent_list.append( old_entity_ptr );
if( GeometryQueryTool::instance()->contains_intermediate_geometry(tmp_ref_ent_list) )
{
- PRINT_ERROR("%s %d or owning parent(s) is virtual. Regularizing virtual\n"
- " geometry is not allowed. Delete virtual geometry first.\n",
- old_entity_ptr->class_name(), old_entity_ptr->id() );
return CUBIT_FAILURE;
}
BasicTopologyEntity* bte_ptr = dynamic_cast<BasicTopologyEntity*>(old_entity_ptr);
if (!bte_ptr)
{
- PRINT_ERROR("Invalid entity passed to regularize_refentity(..)\n");
return CUBIT_FAILURE;
}
- DLIList<Body*> body_list;
- bte_ptr->bodies(body_list);
-
DLIList<TopologyBridge*> bridge_list;
bte_ptr->bridge_manager()->get_bridge_list(bridge_list);
bridge_list.reset();
- DLIList<BodySM*> new_sm_list;
- DLIList<Body*> new_body_list;
CubitStatus stat = CUBIT_SUCCESS;
for (int i = bridge_list.size(); i--; )
@@ -5789,18 +9172,10 @@
GeometryModifyEngine* gme = get_engine(geom_ptr);
if (!gme) continue;
- BodySM* new_body_sm = 0;
- if (!gme->regularize_entity( geom_ptr, new_body_sm ))
+ if (!gme->test_regularize_entity( geom_ptr ))
stat = CUBIT_FAILURE;
-
- if (new_body_sm)
- new_sm_list.append(new_body_sm);
}
- if (!finish_sm_op(body_list, new_sm_list, new_body_list))
- stat = CUBIT_FAILURE;
-
- new_body_ptr = new_body_list.size() ? new_body_list.get() : 0;
return stat;
}
@@ -5830,6 +9205,11 @@
return CUBIT_FAILURE;
}
+ do_attribute_setup();
+ DLIList<BodySM*> body_sm_list, new_bodysm_list;
+ body_sm_list.append(body_sm);
+ push_vg_attributes_before_modify(body_sm_list);
+
CubitStatus stat = gme->regularize_body( body_sm, new_sm );
if ( new_sm == NULL )
{
@@ -5837,20 +9217,30 @@
return CUBIT_FAILURE;
}
+ // remove mesh from modified body
+ body_premodify(body_ptr);
+
+ new_bodysm_list.append(new_sm);
+ restore_vg_after_modify(new_bodysm_list, b_list, gme);
+ remove_pushed_attributes(new_bodysm_list, b_list);
+
body_sm = body_ptr->get_body_sm_ptr();
update_body(body_ptr);
new_body = GeometryQueryTool::instance()->make_Body(new_sm);
GeometryQueryTool::instance()->cleanout_deactivated_geometry();
+ do_attribute_cleanup();
+
return stat;
}
CubitStatus
-GeometryModifyTool::create_body_from_surfs( DLIList<RefFace*> &ref_face_list,
- Body *&new_body,
+GeometryModifyTool::create_solid_bodies_from_surfs( DLIList<RefFace*> &ref_face_list,
+ DLIList<Body*> &new_bodies,
CubitBoolean keep_old,
- CubitBoolean heal ) const
+ CubitBoolean heal,
+ CubitBoolean sheet ) const
{
//First check to make sure the data is all here.
for ( int ii = ref_face_list.size(); ii > 0; ii-- )
@@ -5894,16 +9284,16 @@
}
DLIList<ModelEntity*> query_output, query_input(ref_face_list.size());
- DLIList<Body*> body_list, new_body_list(1);
- DLIList<BodySM*> body_sm_list(1);
+ DLIList<Body*> body_list;
CAST_LIST_TO_PARENT(ref_face_list, query_input);
ModelQueryEngine::instance()->
query_model( query_input, DagType::body_type(), query_output );
CAST_LIST( query_output, body_list, Body );
-
+
+ int i;
DLIList<RefFace*> free_face_list;
- for (int i = ref_face_list.size(); i--; )
+ for ( i=ref_face_list.size(); i--; )
{
RefFace* ref_face = ref_face_list.get_and_step();
query_output.clean_out();
@@ -5913,14 +9303,47 @@
free_face_list.append(ref_face);
}
- BodySM* new_sm = 0;
- CubitStatus stat = gme->create_body_from_surfs( surface_list, new_sm, keep_old, heal );
- if (new_sm)
- body_sm_list.append(new_sm);
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::save_state_with_cubit_file(ref_face_list);
+
+ //get all the bodysm's
+ DLIList<BodySM*> old_body_sm_list;
+ for( i=body_list.size(); i--; )
+ {
+ Body *tmp_body = body_list.get_and_step();
+ TopologyBridge *tb = tmp_body->bridge_manager()->topology_bridge();
+ BodySM *tmp_body_sm = CAST_TO(tb, BodySM);
+ if( tmp_body_sm )
+ old_body_sm_list.append( tmp_body_sm );
+ }
- if (!finish_sm_op( body_list, body_sm_list, new_body_list))
+ // TODO: do I need a clear and a flush here? --KGM
+ GeometryModifyTool::instance()->do_attribute_setup();
+ GeometryModifyTool::instance()->push_vg_attributes_before_modify(old_body_sm_list);
+
+ DLIList<BodySM*> new_bodies_sm;
+ CubitStatus stat = gme->create_solid_bodies_from_surfs( surface_list, new_bodies_sm, keep_old, heal, sheet );
+ DLIList<BodySM*> body_sm_list;
+ for ( i=new_bodies_sm.size(); i--; )
+ body_sm_list.append( new_bodies_sm.get_and_step() );
+
+ GeometryModifyTool::instance()->restore_vg_after_modify(new_bodies_sm, body_list, gme);
+ GeometryModifyTool::instance()->remove_pushed_attributes(new_bodies_sm, body_list);
+
+ if (!finish_sm_op( body_list, body_sm_list, new_bodies))
+ {
stat = CUBIT_FAILURE;
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::remove_last_undo();
+ }
+ else
+ {
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::note_result_bodies(new_bodies);
+ }
+ GeometryModifyTool::instance()->do_attribute_cleanup();
+
DLIList<int> id_list (free_face_list.size());
while (free_face_list.size())
{
@@ -5932,11 +9355,12 @@
destroy_dead_entity( ref_face );
}
}
+
GeometryQueryTool::instance()->cleanout_deactivated_geometry();
if (id_list.size())
CubitUtil::list_entity_ids( "Destroyed surface(s) ", id_list );
- new_body = new_body_list.size() ? new_body_list.get() : 0;
+ //new_body = new_body_list.size() ? new_body_list.get() : 0;
return stat;
}
@@ -6080,6 +9504,8 @@
complete_entity_list.clean_out();
complete_entity_list.merge_unique(temp);
}
+ else
+ complete_entity_list = ref_entity_list;
//Now make sure all the RefEntitys are from the same geometry engine
DLIList<TopologyEntity*> te_list;
@@ -6101,13 +9527,28 @@
if (!gme_ptr || !curve)
return CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<RefEdge*> tmp_ents(1);
+ tmp_ents.append( trim_curve );
+ CubitUndo::save_state_with_cubit_file( tmp_ents );
+ }
+
new_curve = gme_ptr->trim_curve( curve, trim_vector, keep_vector );
if (!new_curve)
+ {
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
return CUBIT_FAILURE;
+ }
GeometryQueryTool::instance()->destroy_dead_entity( trim_curve );
RefEdge* new_edge = GeometryQueryTool::instance()->make_free_RefEdge(new_curve);
+
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::note_result_entity( new_edge );
+
PRINT_INFO("Created curve %d\n", new_edge->id());
return CUBIT_SUCCESS;
@@ -6140,10 +9581,14 @@
double resabs = gqe->get_sme_resabs_tolerance();
DLIList<Curve*> curve_list;
- if( gme->surface_intersection( surf0, surf1, curve_list, resabs ) ==
- CUBIT_FAILURE )
+ CubitStatus status = gme->surface_intersection( surf0, surf1, curve_list, resabs );
+
+ if( status == CUBIT_FAILURE )
return CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled() && curve_list.size() )
+ CubitUndo::save_state();
+
int i;
Curve *curve_ptr;
RefEdge *ref_edge_ptr;
@@ -6154,13 +9599,19 @@
ref_edge_ptr = GeometryQueryTool::instance()->
make_free_RefEdge( curve_ptr );
if( ref_edge_ptr )
- {
ref_edge_list.append( ref_edge_ptr );
- }
else
delete curve_ptr;
}
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<RefEntity*> tmp_list;
+ for( i=ref_edge_list.size(); i--; )
+ tmp_list.append( ref_edge_list.get_and_step() );
+ CubitUndo::note_result_entities( tmp_list );
+ }
+
return CUBIT_SUCCESS;
}
@@ -6183,9 +9634,11 @@
}
//if we can reuse vertices, we decide here
+ bool need_new_start_point = false;
+ bool need_new_end_point = false;
if( full )
{
- bool need_new_start_point = ref_vertex1->get_parents() > 0;
+ need_new_start_point = ref_vertex1->get_parents() > 0;
if (need_new_start_point)
{
bridge_list.reset();
@@ -6195,8 +9648,8 @@
}
else
{
- bool need_new_start_point = ref_vertex1->get_parents() > 0;
- bool need_new_end_point = ref_vertex3->get_parents() > 0;
+ need_new_start_point = ref_vertex1->get_parents() > 0;
+ need_new_end_point = ref_vertex3->get_parents() > 0;
if (need_new_start_point)
{
@@ -6213,16 +9666,38 @@
}
}
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<RefVertex*> vertices_to_save;
+ if( !need_new_start_point )
+ vertices_to_save.append( ref_vertex1 );
+ if( !need_new_end_point )
+ vertices_to_save.append( ref_vertex3 );
+
+ if( vertices_to_save.size() )
+ CubitUndo::save_state_with_cubit_file( vertices_to_save, true );
+ else
+ CubitUndo::save_state();
+ }
+
bridge_list.reset();
Point* point0 = dynamic_cast<Point*>(bridge_list.next(0));
Point* point1 = dynamic_cast<Point*>(bridge_list.next(1));
Point* point2 = dynamic_cast<Point*>(bridge_list.next(2));
Curve* curve = gme->create_arc_three( point0, point1, point2, full );
if (!curve)
+ {
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
return 0;
+ }
RefEdge* result = GeometryQueryTool::instance()->make_free_RefEdge(curve);
PRINT_INFO("Created curve %d\n", result->id());
+
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::note_result_entity( result );
+
return result;
}
@@ -6252,7 +9727,14 @@
if (!curve)
return 0;
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state();
+
RefEdge* result = GeometryQueryTool::instance()->make_free_RefEdge(curve);
+
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::note_result_entity( result );
+
PRINT_INFO("Created curve %d\n", result->id());
return result;
}
@@ -6278,20 +9760,22 @@
}
//if we can reuse vertices, we decide here
+ bool need_new_start_point, need_new_end_point;
if( full )
{
- bool need_new_start_point = ref_vertex3->get_parents() > 0;
+ need_new_start_point = ref_vertex2->get_parents() > 0;
if (need_new_start_point)
{
bridge_list.reset();
- Point *start_point = gme->make_Point( ref_vertex3->coordinates() );
+ bridge_list.step(1);
+ Point *start_point = gme->make_Point( ref_vertex2->coordinates() );
bridge_list.change_to( start_point );
}
}
else
{
- bool need_new_start_point = ref_vertex2->get_parents() > 0;
- bool need_new_end_point = ref_vertex3->get_parents() > 0;
+ need_new_start_point = ref_vertex2->get_parents() > 0;
+ need_new_end_point = ref_vertex3->get_parents() > 0;
if (need_new_start_point)
{
@@ -6308,7 +9792,20 @@
}
}
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<RefVertex*> vertices_to_save;
+ if( !need_new_start_point )
+ vertices_to_save.append( ref_vertex2 );
+ if( !need_new_end_point )
+ vertices_to_save.append( ref_vertex3 );
+ if( vertices_to_save.size() )
+ CubitUndo::save_state_with_cubit_file( vertices_to_save, true );
+ else
+ CubitUndo::save_state();
+ }
+
bridge_list.reset();
Point* point0 = dynamic_cast<Point*>(bridge_list.next(0));
Point* point1 = dynamic_cast<Point*>(bridge_list.next(1));
@@ -6316,10 +9813,18 @@
Curve* curve = gme->create_arc_center_edge( point0, point1, point2,
normal, radius, full );
if (!curve)
+ {
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
return 0;
+ }
RefEdge* result = GeometryQueryTool::instance()->make_free_RefEdge(curve);
PRINT_INFO("Created curve %d\n", result->id());
+
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::note_result_entity( result );
+
return result;
}
@@ -6350,6 +9855,9 @@
DLIList<Curve*> curve_list(count);
CAST_LIST( bridge_list, curve_list, Curve );
result = gme->create_curve_combine(curve_list, new_curve_ptr);
+ if (new_curve_ptr)
+ new_ref_edge_ptr = CAST_TO(new_curve_ptr->topology_entity(), RefEdge);
+
return result;
}
@@ -6366,50 +9874,86 @@
GeometryModifyEngine*
GeometryModifyTool::common_modify_engine( DLIList<TopologyEntity*>& topology_list,
DLIList<TopologyBridge*>& engine_bridges,
- CubitBoolean /*allow_virtual_engine*/ ) const
+ CubitBoolean allow_composites ) const
{
- topology_list.reset();
-
- TopologyEntity* topo_ptr = topology_list.get_and_step();
- if (!topo_ptr)
- return (GeometryModifyEngine*)NULL;
- DLIList<TopologyBridge*> first_bridge_list;
- topo_ptr->bridge_manager()->get_bridge_list( first_bridge_list );
-
- first_bridge_list.reset();
GeometryModifyEngine* gme_ptr = 0;
- for( int i = first_bridge_list.size(); i > 0; i-- )
+ if(allow_composites)
{
- TopologyBridge* bridge_ptr = first_bridge_list.get_and_step();
+ int i;
engine_bridges.clean_out();
- engine_bridges.append( bridge_ptr );
- gme_ptr = get_engine(bridge_ptr);
+ for(i=topology_list.size(); i--;)
+ {
+ TopologyEntity* topo_ptr = topology_list.get_and_step();
+ if (!topo_ptr)
+ return (GeometryModifyEngine*)NULL;
+ TopologyBridge *first_bridge = topo_ptr->bridge_manager()->topology_bridge();
+ GeometryQueryEngine *gqe = first_bridge->get_geometry_query_engine();
+ DLIList<TopologyBridge*> underlying_bridge_list;
+ gqe->get_underlying_bridges(first_bridge, underlying_bridge_list);
+ if(underlying_bridge_list.size() == 0)
+ underlying_bridge_list.append(first_bridge);
+ int k;
+ for(k=underlying_bridge_list.size(); k--;)
+ {
+ TopologyBridge *bridge_ptr = underlying_bridge_list.get_and_step();
+ engine_bridges.append( bridge_ptr );
+ GeometryModifyEngine *cur_gme = get_engine(bridge_ptr);
+ if(!gme_ptr)
+ gme_ptr = cur_gme;
+ else
+ {
+ if(gme_ptr != cur_gme)
+ {
+ gme_ptr = NULL;
+ k=0;
+ i=0;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ topology_list.reset();
- if( !gme_ptr )
- return (GeometryModifyEngine*)NULL;
+ TopologyEntity* topo_ptr = topology_list.get_and_step();
+ if (!topo_ptr)
+ return (GeometryModifyEngine*)NULL;
+ DLIList<TopologyBridge*> first_bridge_list;
+ topo_ptr->bridge_manager()->get_bridge_list( first_bridge_list );
- topology_list.reset();
- topology_list.step(); //skip first entry
- for( int j = topology_list.size(); j > 1; j-- )
+ first_bridge_list.reset();
+ for( int i = first_bridge_list.size(); i > 0; i-- )
{
- topo_ptr = topology_list.get_and_step();
- bridge_ptr = topo_ptr->bridge_manager()->topology_bridge(gme_ptr->get_gqe());
- if( bridge_ptr ) engine_bridges.append( bridge_ptr );
- else break;
- }
+ TopologyBridge* bridge_ptr = first_bridge_list.get_and_step();
+ engine_bridges.clean_out();
+ engine_bridges.append( bridge_ptr );
+ gme_ptr = get_engine(bridge_ptr);
- if( engine_bridges.size() == topology_list.size() )
- break;
+ if( !gme_ptr )
+ return (GeometryModifyEngine*)NULL;
- gme_ptr = 0;
+ topology_list.reset();
+ topology_list.step(); //skip first entry
+ for( int j = topology_list.size(); j > 1; j-- )
+ {
+ topo_ptr = topology_list.get_and_step();
+ bridge_ptr = topo_ptr->bridge_manager()->topology_bridge(gme_ptr->get_gqe());
+ if( bridge_ptr ) engine_bridges.append( bridge_ptr );
+ else break;
+ }
+
+ if( engine_bridges.size() == topology_list.size() )
+ break;
+
+ gme_ptr = 0;
+ }
}
-
if( !gme_ptr )
{
engine_bridges.clean_out();
PRINT_ERROR("Entities do not belong to the same geometry engine.\n");
}
-
return gme_ptr;
}
@@ -6424,7 +9968,7 @@
//-------------------------------------------------------------------------
GeometryModifyEngine*
GeometryModifyTool::common_modify_engine( DLIList<Body*>& input,
- DLIList<BodySM*>& output ) const
+ DLIList<BodySM*>& output) const
{
input.reset();
Body* body_ptr = input.get();
@@ -6467,7 +10011,8 @@
GeometryModifyTool::common_modify_engine( DLIList<RefFace*>& face_list,
DLIList<RefEdge*>& edge_list,
DLIList<Surface*>& surf_list,
- DLIList<Curve*>& curv_list ) const
+ DLIList<Curve*>& curv_list,
+ CubitBoolean allow_composites) const
{
int i;
const int count = face_list.size() + edge_list.size();
@@ -6481,17 +10026,27 @@
for (i = edge_list.size(); i--; )
entity_list.append(edge_list.get_and_step());
- GeometryModifyEngine* engine = common_modify_engine(entity_list, bridge_list);
+ GeometryModifyEngine* engine = common_modify_engine(entity_list, bridge_list, allow_composites);
if (!engine)
return 0;
entity_list.reset();
CAST_LIST(bridge_list, surf_list, Surface);
CAST_LIST(bridge_list, curv_list, Curve );
- if (surf_list.size() != face_list.size() || curv_list.size() != edge_list.size())
- return 0;
-
- return engine;
+ if(allow_composites)
+ {
+ if(surf_list.size() >= face_list.size() && curv_list.size() >= edge_list.size())
+ return engine;
+ else
+ return 0;
+ }
+ else
+ {
+ if (surf_list.size() != face_list.size() || curv_list.size() != edge_list.size())
+ return 0;
+ else
+ return engine;
+ }
}
//-------------------------------------------------------------------------
@@ -6505,7 +10060,8 @@
//-------------------------------------------------------------------------
GeometryModifyEngine*
GeometryModifyTool::common_modify_engine( DLIList<RefFace*>& face_list,
- DLIList<Surface*>& surf_list ) const
+ DLIList<Surface*>& surf_list,
+ CubitBoolean allow_composites) const
{
const int size = face_list.size();
DLIList<TopologyEntity*> topo_list(size);
@@ -6513,7 +10069,7 @@
GeometryModifyEngine* result;
CAST_LIST_TO_PARENT( face_list, topo_list );
- result = common_modify_engine( topo_list, geom_list );
+ result = common_modify_engine( topo_list, geom_list, allow_composites );
CAST_LIST( geom_list, surf_list, Surface );
return result;
@@ -6530,7 +10086,8 @@
//-------------------------------------------------------------------------
GeometryModifyEngine* GeometryModifyTool::common_modify_engine(
DLIList<RefEdge*>& edge_list,
- DLIList<Curve*>& curve_list ) const
+ DLIList<Curve*>& curve_list,
+ CubitBoolean allow_composites) const
{
const int size = edge_list.size();
DLIList<TopologyEntity*> topo_list(size);
@@ -6538,7 +10095,7 @@
GeometryModifyEngine* result;
CAST_LIST_TO_PARENT( edge_list, topo_list );
- result = common_modify_engine( topo_list, geom_list );
+ result = common_modify_engine( topo_list, geom_list, allow_composites );
CAST_LIST( geom_list, curve_list, Curve );
return result;
@@ -6555,7 +10112,8 @@
//-------------------------------------------------------------------------
GeometryModifyEngine*
GeometryModifyTool::common_modify_engine( DLIList<RefVertex*>& vertex_list,
- DLIList<Point*>& point_list ) const
+ DLIList<Point*>& point_list,
+ CubitBoolean allow_composites) const
{
const int size = vertex_list.size();
DLIList<TopologyEntity*> topo_list(size);
@@ -6563,12 +10121,78 @@
GeometryModifyEngine* result;
CAST_LIST_TO_PARENT( vertex_list, topo_list );
- result = common_modify_engine( topo_list, geom_list );
+ result = common_modify_engine( topo_list, geom_list, allow_composites );
CAST_LIST( geom_list, point_list, Point );
return result;
}
+//-------------------------------------------------------------------------
+// Purpose : Pull RefFaces with a common GeometryModifyEngine out of
+// the input ref_face_list. Place their surfaces in the
+// output surf_list, and return the common modify engine.
+//
+// Special Notes : the function returns a NULL pointer if a RefFace without
+// a modify engine is found in the input list.
+//
+// Creator : Steve Storm
+//
+// Creation Date : 03/02/08
+//-------------------------------------------------------------------------
+GeometryModifyEngine*
+GeometryModifyTool::pull_common_surfs( DLIList<RefFace*> &ref_face_list,
+ DLIList<RefFace*> &common_face_list,
+ DLIList<Surface*> &common_surf_list )
+{
+ int i;
+ RefFace *ref_face_ptr;
+ Surface *surf_ptr;
+
+ GeometryModifyEngine *gme1 = 0, *gme2 = 0;
+
+ ref_face_list.reset();
+ for( i=0; i<ref_face_list.size(); i++ )
+ {
+ ref_face_ptr = ref_face_list.get();
+ surf_ptr = ref_face_ptr->get_surface_ptr();
+
+ if( i==0 )
+ {
+ common_face_list.append( ref_face_ptr );
+ common_surf_list.append( surf_ptr );
+ gme1 = get_engine( surf_ptr );
+ if (!gme1)
+ {
+ PRINT_ERROR("Surface %d does not have a modify engine.\n", ref_face_ptr->id());
+ return 0;
+ }
+ ref_face_list.change_to( NULL );
+ ref_face_list.step();
+ continue;
+ }
+
+ gme2 = get_engine( surf_ptr );
+ if (!gme2)
+ {
+ PRINT_ERROR("Surface %d does not have a modify engine.\n", ref_face_ptr->id());
+ return 0;
+ }
+
+ if( gme2 == gme1 )
+ {
+ common_face_list.append( ref_face_ptr );
+ common_surf_list.append( surf_ptr );
+ ref_face_list.change_to( NULL );
+ }
+
+ ref_face_list.step();
+ }
+
+ ref_face_list.remove_all_with_value( NULL );
+
+ return gme1;
+}
+
// Separates the list of bodies so that there is one body per volume
// after a webcut. Checks the sepAfterWebcut flag.
CubitStatus GeometryModifyTool::separate_body_after_webcut( DLIList<Body*> &input_list,
@@ -6585,7 +10209,16 @@
{
Body *body_ptr = input_list.get_and_step();
temp_body_list.clean_out();
+
+ bool undo_setting = CubitUndo::get_undo_enabled();
+ if( undo_setting == true )
+ CubitUndo::set_undo_enabled( false );
+
split_body(body_ptr, temp_body_list);
+
+ if( undo_setting == true )
+ CubitUndo::set_undo_enabled( true );
+
output_list += temp_body_list;
}
return CUBIT_SUCCESS;
@@ -6786,7 +10419,7 @@
if( ref_face1 == ref_face2 )
{
PRINT_ERROR("Cannot create midplane between the same surface.\n",
- " Surface %d was entered twice\n", ref_face1->id() );
+ " Surface %d was entered twice\n", ref_face1->id() );
return CUBIT_FAILURE;
}
@@ -7053,7 +10686,7 @@
if( ref_face1 == ref_face2 )
{
PRINT_ERROR("Cannot create midplane between the same surface.\n",
- " Surface %d was entered twice\n", ref_face1->id() );
+ " Surface %d was entered twice\n", ref_face1->id() );
return CUBIT_FAILURE;
}
@@ -7142,23 +10775,37 @@
if ( midsurface_body_sm )
{
- Body *midsurface_body;
+ if(CubitUndo::get_undo_enabled())
+ CubitUndo::save_state();
- midsurface_body = GeometryQueryTool::instance()->make_Body(midsurface_body_sm);
-
- DLIList<RefFace*> ref_faces;
- midsurface_body->ref_faces( ref_faces );
-
+ DLIList<Surface*> mid_surfaces;
+ DLIList<Body*> new_bodies;
+ midsurface_body_sm->surfaces( mid_surfaces);
//make each surface of the body into its own body
int i;
- for( i=0; i<ref_faces.size(); i++ )
+ for( i=0; i<mid_surfaces.size(); i++ )
{
- RefEntity *new_entity_ptr;
- new_entity_ptr = GeometryModifyTool::instance()->copy_refentity(ref_faces.get_and_step());
- RefFace *ref_face_ptr = CAST_TO(new_entity_ptr, RefFace);
+ Surface *tmp_surface = mid_surfaces.get_and_step();
+ bool extended_from = false;
+ Surface* new_surface_ptr = gme1_ptr->make_Surface( tmp_surface, extended_from );
+
+ Body *new_Body = make_Body(new_surface_ptr);
+ new_bodies.append( new_Body );
+ DLIList<RefFace*> ref_faces;
+ new_Body->ref_faces(ref_faces);
+ RefFace *ref_face_ptr = ref_faces.get();
mid_surface_surfs.append( ref_face_ptr );
}
- GeometryQueryTool::instance()->delete_Body( midsurface_body );
+ gme1_ptr->get_gqe()->delete_solid_model_entities( midsurface_body_sm );
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( new_bodies.size() )
+ CubitUndo::note_result_bodies( new_bodies );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
return ret;
}
else
@@ -7197,7 +10844,8 @@
GeometryModifyTool::tweak_setup( DLIList<RefFace*> &input_faces,
const char* name,
DLIList<Body*> &output_bodies,
- DLIList<Surface*> &output_surfaces )
+ DLIList<Surface*> &output_surfaces,
+ CubitBoolean allow_composites)
{
if( input_faces.size() == 0 )
{
@@ -7229,19 +10877,26 @@
->query_model( query_input, DagType::body_type(), query_output );
CAST_LIST(query_output, output_bodies, Body);
- // Check for virtual geometry
- if ( contains_intermediate_geom(output_bodies))
+ if(allow_composites)
{
- PRINT_ERROR("%s surfaces on volumes containing virtual geometry\n"
- " is not allowed.\n"
- " Delete virtual geometry on these volumes before operation.\n",
- name);
- return 0;
+ if (!okay_to_modify( output_bodies, "TWEAK" ))
+ return 0;
}
+ else
+ {
+ if ( contains_intermediate_geom(output_bodies))
+ {
+ PRINT_ERROR("%s surfaces on volumes containing virtual geometry\n"
+ " is not allowed.\n"
+ " Delete virtual geometry on these volumes before operation.\n",
+ name);
+ return 0;
+ }
+ }
// Get engine and corresponding geom entities
GeometryModifyEngine* gme_ptr;
- gme_ptr = common_modify_engine( input_faces, output_surfaces );
+ gme_ptr = common_modify_engine( input_faces, output_surfaces, allow_composites );
if (!gme_ptr)
{
PRINT_ERROR("%s surfaces on volumes containing surfaces from different\n"
@@ -7348,9 +11003,6 @@
if( input_vertices.size() == 0 )
return 0;
-
-
-
// Get parent bodies
DLIList<ModelEntity*> query_input(input_vertices.size()), query_output;
CAST_LIST_TO_PARENT(input_vertices, query_input);
@@ -7381,10 +11033,1416 @@
}
//=============================================================================
-// 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.
+// Description: The user selects a surface they would like to idealize and also selects a radius
+// size for fillets. The user also specifies whether to consider internal and/or external fillets.
+// The program will identify fillets which meet the users criteria and tweak remove them automatically.
+// There is also a preview and exclude curve capability.
+// Author : Jonathan Bugman
+// Date : 10/23/2008
+//=============================================================================
+CubitStatus GeometryModifyTool::idealize_fillet_geometry(DLIList<RefEntity*> idealize_entity,
+ DLIList<RefEntity*> exclude_entity,
+ double fillet_rad,
+ CubitBoolean internal_flg,
+ CubitBoolean external_flg,
+ CubitBoolean preview)
+{
+ //cast the DLIList<RefEntity> to a DLIList<RefFace>
+ DLIList<RefFace*> face_to_idealize;
+ CAST_LIST(idealize_entity, face_to_idealize, RefFace);
+
+ //grabbing geometry tolerance
+ double geo_tol = GeometryQueryTool::instance()->get_sme_resabs_tolerance(),temp_fillet_radius;
+
+ //grabbing all the curve loops ONLY from surfaces which are a sheet body
+ int y, i, j, z;
+ DLIList<RefFace*> sheet_body_idealize_face;
+
+ for(i=0; i<face_to_idealize.size(); i++)
+ {
+ RefFace* target_face = face_to_idealize.get_and_step();
+ DLIList<Shell*> shell_list;
+ target_face->shells(shell_list);
+ for(j=0; j<shell_list.size(); j++)
+ {
+ Shell* target_shell = shell_list.get_and_step();
+ if(target_face->is_nonmanifold( (GroupingEntity*)target_shell ) )
+ {
+ sheet_body_idealize_face.append(face_to_idealize[i]);
+ }
+ }
+ }
+
+ face_to_idealize.clean_out();
+
+ //this section is going to remove all excluded curves loopsm from the 'master' loopsm list
+ DLIList<Curve*> exclude_cuves;
+ DLIList <Body*> old_body_list;
+ if(exclude_entity.size()>0)
+ {
+ //cast the exclude DLIList<RefEntity> to DLIList<RefEdge>
+ DLIList<RefEdge*> exclude_edge;
+ CAST_LIST(exclude_entity, exclude_edge, RefEdge);
+
+ //switching the DLIList<RefEdge> to DLIList<Curve>
+ GeometryModifyEngine* gme_ptr1;
+ gme_ptr1 = tweak_setup(exclude_edge,"idealize",old_body_list,exclude_cuves);
+ exclude_edge.clean_out();
+ }
+
+ //switching the DLIList<RefFace> to DLIList<Surface>
+ GeometryModifyEngine* gme_ptr;
+ DLIList<Surface*> sheet_body_idealize_surface;
+ gme_ptr = tweak_setup(sheet_body_idealize_face,"idealize",old_body_list,sheet_body_idealize_surface);
+ sheet_body_idealize_face.clean_out();
+
+ //grab all the loops from each sheet body surface
+ DLIList <LoopSM*> idealize_loopSM_list;
+ for(y=0;y<sheet_body_idealize_surface.size();y++)
+ {
+ sheet_body_idealize_surface[y]->loopsms(idealize_loopSM_list);
+ }
+ sheet_body_idealize_surface.clean_out();
+
+ //search through possible fillet curves filtering only for curves of type arc
+ //if it is an arc, does it have a straight line on both sides of it, if so'
+ //check the radius of the arc and if it passes test add it to the list of curves to be tweaked removed
+ DLIList <Curve*> master_curve_remove_list,possible_fillet_arcs,potential_fillet,internal_fillet, external_fillet, attached_curves;
+ CubitVector fillet_center_point, intersection_pt,arc_mid,test_point;
+ DLIList <Point*> arc_vertices;
+ for(y=0;y<idealize_loopSM_list.size();y++)
+ {
+ idealize_loopSM_list[y]->curves(possible_fillet_arcs);
+ //doing this as a performance boost, it'll keep the code out of the next couple of for loops for situations
+ //where there is no fillet possible, for instance, a hole with 2 curves will never be a fillet
+ if(possible_fillet_arcs.size()>3)
+ {
+ for(i=0;i<possible_fillet_arcs.size();i++)
+ {
+ if(possible_fillet_arcs[i]->geometry_type() == ARC_CURVE_TYPE &&
+ exclude_cuves.is_in_list(possible_fillet_arcs[i])==CUBIT_FALSE)
+ {
+ possible_fillet_arcs[i]->points(arc_vertices);
+ //don't need to check for one point as in a hole because I have a check that there needs to be
+ //at least 3 curves in the loop
+
+ //this is to check that there is only one curve attached to the arc
+ for(z=0;z<arc_vertices.size();z++)
+ {
+ arc_vertices[z]->curves(attached_curves);
+ if(attached_curves.size()!=2)
+ {
+ //I dont' think this break point is going to kick me far enough out of the for loop
+ break;
+ }
+ }
+
+ possible_fillet_arcs[i]->mid_point(arc_mid);
+ possible_fillet_arcs[i]->get_center_radius(fillet_center_point,temp_fillet_radius);
+ test_point = arc_mid + geo_tol * (fillet_center_point-arc_mid);
+ DLIList<Surface*> test_surf;
+ idealize_loopSM_list[y]->surfaces(test_surf);
+
+ //this may be dangerous but I'm assuming that a loop is on only one surface
+ CubitPointContainment cpc = test_surf[0]->point_containment(test_point);
+ if(temp_fillet_radius <= fillet_rad && cpc==CUBIT_PNT_INSIDE)
+ {
+ external_fillet.append(possible_fillet_arcs[i]);
+ }
+ else if(temp_fillet_radius <= fillet_rad && cpc==CUBIT_PNT_OUTSIDE)
+ {
+ internal_fillet.append(possible_fillet_arcs[i]);
+ }
+ }
+ }
+ }
+ possible_fillet_arcs.clean_out();
+ }
+
+ if(internal_flg==CUBIT_TRUE)
+ {
+ master_curve_remove_list+=internal_fillet;
+ }
+ if(external_flg==CUBIT_TRUE)
+ {
+ master_curve_remove_list+=external_fillet;
+ }
+
+ //if no arcs are found to be removed, warn the user.
+ if(master_curve_remove_list.size()==0)
+ {
+ PRINT_INFO( "Failed to find any fillets which met users requirements\n\n" );
+ //I'm returning success here even though no curves were found
+ return CUBIT_SUCCESS;
+ }
+ else if(preview == CUBIT_TRUE)
+ {
+ DLIList<BodySM*> new_bodysm_list;
+ bool old_error_flag = GET_ERROR_FLAG();
+ SET_ERROR_FLAG(false); // don't throw any tweak_remove errors
+
+ CubitStatus stat = gme_ptr->tweak_remove(master_curve_remove_list, new_bodysm_list,CUBIT_FALSE, CUBIT_TRUE );
+
+ SET_ERROR_FLAG(old_error_flag); // turn errors back on
+ if(stat==CUBIT_FAILURE)
+ {
+ PRINT_WARNING("At least one of the fillets which met your requirements \n"
+ " can't be preview due to the curve's geometry\n");
+ }
+
+ //output the number of holes or slots which were found
+ PRINT_INFO("Found %d fillets which met idealization parameters\n\n", master_curve_remove_list.size());
+ return CUBIT_SUCCESS;
+ }
+ else
+ {
+ DLIList<BodySM*> new_bodysm_list;
+ bool old_error_flag = GET_ERROR_FLAG();
+ SET_ERROR_FLAG(false); // don't throw any tweak_remove errors
+
+ //pass master_curve_remove_list to the tweak_remove command
+ CubitStatus stat = gme_ptr->tweak_remove(master_curve_remove_list, new_bodysm_list,CUBIT_FALSE, CUBIT_FALSE );
+ if(stat==CUBIT_FAILURE)
+ {
+ PRINT_WARNING("At least one of the fillets which met your requirements \n"
+ " can't be tweaked due to the curve's geometry\n");
+ }
+ SET_ERROR_FLAG(old_error_flag); // turn errors back on
+
+ //update DAG
+ DLIList<Body*> new_body_list;
+ stat = finish_sm_op( old_body_list, new_bodysm_list ,new_body_list );
+ //output the number of holes or slots which were found
+ PRINT_INFO("Found %d fillets which met idealization parameters\n\n", master_curve_remove_list.size());
+ return CUBIT_SUCCESS;
+ }
+}
+
+//=============================================================================
+// Description: The user selects a surface they would like to idealize and also selects a radius
+// size for holes and or selects a radius and length for slots. The program will identify
+// 'holes' and 'slots' which meet the users criteria and tweak remove them automatically.
+// There is also a preview and exclude curve capability.
+// Author : Jonathan Bugman
+// Date : 10/23/2008
+//=============================================================================
+CubitStatus GeometryModifyTool::idealize_hole_slot_geometry(DLIList<RefEntity*> idealize_entity,
+ DLIList<RefEntity*> exclude_entity,
+ double arc_radius,
+ double slot_arc_radius,
+ double slot_length,
+ CubitBoolean preview)
+{
+ //cast the DLIList<RefEntity> to a DLIList<RefFace>
+ DLIList<RefFace*> face_to_idealize;
+ CAST_LIST(idealize_entity, face_to_idealize, RefFace);
+
+ //grabbing geometry tolerance
+ double geo_tol = GeometryQueryTool::instance()->get_sme_resabs_tolerance();
+
+ //grabbing all the curve loops ONLY from surfaces which are a sheet body
+ int y=0, i=0, j=0;
+ DLIList<RefFace*> sheet_body_idealize_face;
+
+ for(i=0; i<face_to_idealize.size(); i++)
+ {
+ RefFace* target_face = face_to_idealize.get_and_step();
+ DLIList<Shell*> shell_list;
+ target_face->shells(shell_list);
+ for(j=0; j<shell_list.size(); j++)
+ {
+ Shell* target_shell = shell_list.get_and_step();
+ if(target_face->is_nonmanifold( (GroupingEntity*)target_shell ) )
+ {
+ sheet_body_idealize_face.append(face_to_idealize[i]);
+ }
+ }
+ }
+
+ //if no faces to idealize that pass requirements, error out a warning message
+ if(sheet_body_idealize_face.size()==0)
+ {
+ //I'm returning success here even though no surfaces found that meet shell requirements set above
+ {
+ PRINT_INFO( "Failed to find any feature(s) which met user requirements\n\n" );
+ }
+ return CUBIT_SUCCESS;
+ }
+
+ //temp_body_ptr = face_to_idealize[y]->body();
+ //if(temp_body_ptr->is_sheet_body())
+ //{
+ // sheet_body_idealize_face.append(face_to_idealize[y]);
+ //}
+
+ face_to_idealize.clean_out();
+
+ //switching the DLIList<RefFace> to DLIList<Surface>
+ GeometryModifyEngine* gme_ptr;
+ DLIList <Body*> old_body_list;
+ DLIList<Surface*> sheet_body_idealize_surface;
+ gme_ptr = tweak_setup(sheet_body_idealize_face,"idealize",old_body_list,sheet_body_idealize_surface);
+ sheet_body_idealize_face.clean_out();
+
+ //grab all the loops from each sheet body surface
+ DLIList <LoopSM*> idealize_loopSM_list;
+ for(y=0;y<sheet_body_idealize_surface.size();y++)
+ {
+ sheet_body_idealize_surface[y]->loopsms(idealize_loopSM_list);
+ }
+ sheet_body_idealize_surface.clean_out();
+
+ //this section is going to remove all excluded curves loopsm from the 'master' loopsm list
+ if(exclude_entity.size()>0)
+ {
+ //cast the exclude DLIList<RefEntity> to DLIList<RefEdge>
+ DLIList<RefEdge*> exclude_edge;
+ CAST_LIST(exclude_entity, exclude_edge, RefEdge);
+
+ //switching the DLIList<RefEdge> to DLIList<Curve>
+ DLIList<Curve*> exclude_cuves;
+ GeometryModifyEngine* gme_ptr1;
+ gme_ptr1 = tweak_setup(exclude_edge,"idealize",old_body_list,exclude_cuves);
+ exclude_edge.clean_out();
+
+ //grabbing all the curve loops from the given excluded curves
+ DLIList <LoopSM*> exclude_loops;
+ for(y=0;y<exclude_cuves.size();y++)
+ {
+ exclude_cuves[y]->loopsms(exclude_loops);
+ }
+ exclude_cuves.clean_out();
+
+ //remove the excluded loops from the list of sheet body loopsms
+ idealize_loopSM_list -= exclude_loops;
+ }
+
+ //removing all the external loops from the list as they will not be tweak removed
+ DLIList <LoopSM*> possible_internal_LoopSM_list;
+ for(y=0;y<idealize_loopSM_list.size();y++)
+ {
+ if(idealize_loopSM_list[y]->loop_type() == LOOP_TYPE_HOLE)
+ {
+ possible_internal_LoopSM_list.append(idealize_loopSM_list[y]);
+ }
+ }
+ idealize_loopSM_list.clean_out();
+ DLIList <Curve*> hole_curves_to_remove; //hole_curves_to_remove is the curves selected for removal out of the 'hole' search algorithm
+ DLIList <Curve*> master_curve_remove_list;
+ DLIList <LoopSM*> arc_LoopSM_list;
+ DLIList <Surface*> temp_list;
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ //this begins the hole search algorithm
+ //if no arc radius given, skip hole search algorithm
+ if(arc_radius!=CUBIT_DBL_MAX)
+ {
+ DLIList <LoopSM*> not_hole_loop; //loops which don't meet the all curves are arc type filter
+ DLIList <Curve*> possible_internal_arcs;
+
+ //search through possible internal curves filtering only for curves of type arc
+ //if one of the curves in a loop is not an arc, add that loop to the not_hole_loop list
+ for(y=0;y<possible_internal_LoopSM_list.size();y++)
+ {
+ possible_internal_arcs.clean_out();
+ possible_internal_LoopSM_list[y]->curves(possible_internal_arcs);
+ for(i=0;i<possible_internal_arcs.size();i++)
+ {
+ temp_list.clean_out();
+ possible_internal_arcs[i]->surfaces(temp_list);
+ //check whether or not curve is of arc type and whether it is attached to more than one surface
+ if( possible_internal_arcs[i]->geometry_type() != ARC_CURVE_TYPE || temp_list.size() != 1)
+ {
+ not_hole_loop.append(possible_internal_LoopSM_list[y]);
+ break;
+ }
+ }
+ }
+
+ //change name of possible_internal_LoopSM_list to arc_LoopSM_list
+ arc_LoopSM_list = possible_internal_LoopSM_list;
+ //subtract from the possible loops the loops which don't have curves which are all arcs or are attached to more than two surfaces
+ arc_LoopSM_list-=not_hole_loop;
+ not_hole_loop.clean_out();
+
+ //this next filter checks to make sure that all arcs of the same loop share the same
+ //radius center within the geometry tolerance
+ CubitVector arc_center_point, arc_center_point1;
+ DLIList <LoopSM*> not_center_arc_loop;
+ double rad_distance, temp_arc_radius , temp_arc_radius1;
+
+ //this for loop is going to check that each loops arc curves have the same center radius point
+ //if not you can remove that loop as a possibility for being added to the tweak_remove command
+ for(y=0;y<arc_LoopSM_list.size();y++)
+ {
+ //clean out curve list before grabbing a new loop
+ hole_curves_to_remove.clean_out();
+ arc_LoopSM_list[y]->curves(hole_curves_to_remove);
+ //iterate across the hole_curves_to_remove size
+ for (i=0;i<hole_curves_to_remove.size();i++)
+ {
+ //if you are on the first index, we need to set a baseline radius point
+ if(i==0)
+ {
+ hole_curves_to_remove[i]->get_center_radius(arc_center_point,temp_arc_radius);
+ //if this is the only arc in the loop go ahead and check if it meets specified arc parameter
+ //if it doesn't meet the users parameter add the loop to the not_center_arc_loop list
+ if(temp_arc_radius >= arc_radius && hole_curves_to_remove.size()==1)
+ {
+ not_center_arc_loop.append(arc_LoopSM_list[y]);
+ break;
+ }
+ }
+ //now compare the other arc center points to the baseline, if it ever fails the users parameter
+ //add the loop to the not_center_arc_loop list
+ else
+ {
+ hole_curves_to_remove[i]->get_center_radius(arc_center_point1,temp_arc_radius1);
+ rad_distance = arc_center_point.distance_between_squared(arc_center_point1);
+ if(rad_distance > geo_tol || temp_arc_radius >= arc_radius)
+ {
+ not_center_arc_loop.append(arc_LoopSM_list[y]);
+ break;
+ }
+ }
+ }
+ }
+
+ //remove loops which didn't have perfect circular holes from the arc_loopsm_list
+ arc_LoopSM_list -= not_center_arc_loop;
+ for(y=0;y<arc_LoopSM_list.size();y++)
+ {
+ arc_LoopSM_list[y]->curves(hole_curves_to_remove);
+ }
+ master_curve_remove_list+=hole_curves_to_remove;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ //this begins the slot search algorithm
+ DLIList<LoopSM*> removable_slot_loop;
+ if(slot_arc_radius!=CUBIT_DBL_MAX || slot_length!=CUBIT_DBL_MAX)
+ {
+ DLIList<LoopSM*> four_curve_possible_slot;
+ DLIList<LoopSM*> possible_slot;
+ DLIList<Curve*> internal_curves_in_loop;
+
+ //checks to make sure the loop has only four curves - may want to expand this in the future
+ for(y=0;y<possible_internal_LoopSM_list.size();y++)
+ {
+ possible_internal_LoopSM_list[y]->curves(internal_curves_in_loop);
+ if(internal_curves_in_loop.size()==4)
+ {
+ four_curve_possible_slot.append(possible_internal_LoopSM_list[y]);
+ }
+ internal_curves_in_loop.clean_out();
+ }
+
+
+ //check to make sure it alternates straight line, arc, etc...
+ for(y=0;y<four_curve_possible_slot.size();y++)
+ {
+ four_curve_possible_slot[y]->curves(internal_curves_in_loop);
+
+ if(internal_curves_in_loop[0]->geometry_type() == ARC_CURVE_TYPE &&
+ internal_curves_in_loop[1]->geometry_type() == STRAIGHT_CURVE_TYPE &&
+ internal_curves_in_loop[2]->geometry_type() == ARC_CURVE_TYPE &&
+ internal_curves_in_loop[3]->geometry_type() == STRAIGHT_CURVE_TYPE)
+ {
+ int num_of_surfs=0;
+ for(i=0;i<internal_curves_in_loop.size();i++)
+ {
+ temp_list.clean_out();
+ internal_curves_in_loop[i]->surfaces(temp_list);
+ num_of_surfs=num_of_surfs + temp_list.size();
+ }
+ if(num_of_surfs==4)
+ {
+ possible_slot.append(four_curve_possible_slot[y]);
+ }
+ }
+ else if(internal_curves_in_loop[0]->geometry_type() == STRAIGHT_CURVE_TYPE &&
+ internal_curves_in_loop[1]->geometry_type() == ARC_CURVE_TYPE &&
+ internal_curves_in_loop[2]->geometry_type() == STRAIGHT_CURVE_TYPE &&
+ internal_curves_in_loop[3]->geometry_type() == ARC_CURVE_TYPE)
+ {
+ int num_of_surfs=0;
+ for(i=0;i<internal_curves_in_loop.size();i++)
+ {
+ temp_list.clean_out();
+ internal_curves_in_loop[i]->surfaces(temp_list);
+ num_of_surfs=num_of_surfs + temp_list.size();
+ }
+ if(num_of_surfs==4)
+ {
+ possible_slot.append(four_curve_possible_slot[y]);
+ }
+ }
+ internal_curves_in_loop.clean_out();
+ }
+
+ CubitVector arc_center_point;
+ double temp_arc_radius = CUBIT_DBL_MAX, curve_length = CUBIT_DBL_MAX;
+
+ //check to make sure that the rad and/or length meet users parameters
+ for(y=0;y<possible_slot.size();y++)
+ {
+ possible_slot[y]->curves(internal_curves_in_loop);
+ //if user specified rad, then passed rad_counter should = 2 after for loop completes
+ //if length specified, length_counter should =2 after for loop completes
+ int rad_counter = 0, length_counter = 0;
+ for(i=0;i<internal_curves_in_loop.size();i++)
+ {
+ //if curve is an arc and user specified a radius enter if statement
+ if( internal_curves_in_loop[i]->geometry_type() == ARC_CURVE_TYPE && slot_arc_radius!=CUBIT_DBL_MAX )
+ {
+ //check the radius against the user inputed value
+ internal_curves_in_loop[i]->get_center_radius(arc_center_point,temp_arc_radius);
+ if(temp_arc_radius <= slot_arc_radius)
+ {
+ //if it passes rad test, add to rad_counter
+ rad_counter++;
+ }
+ }
+ else if(internal_curves_in_loop[i]->geometry_type() == STRAIGHT_CURVE_TYPE && slot_length!=CUBIT_DBL_MAX )
+ {
+ //check the length against the user inputed value
+ curve_length = internal_curves_in_loop[i]->get_arc_length();
+ if(curve_length <= slot_length)
+ {
+ //if it passes rad test, add to length_counter
+ length_counter++;
+ }
+ }
+ }
+
+ //checks that if user specified length and radius constraint that its parameter passes for all four curves
+ if(slot_length!=CUBIT_DBL_MAX && slot_arc_radius!=CUBIT_DBL_MAX && rad_counter==2 && length_counter==2)
+ {
+ removable_slot_loop.append(possible_slot[y]);
+ }
+
+ //if user only specified one length or arc parameter, it only needs to meet 2 criteria
+ else if((slot_length!=CUBIT_DBL_MAX && length_counter==2) || (slot_arc_radius!=CUBIT_DBL_MAX && rad_counter==2))
+ {
+ removable_slot_loop.append(possible_slot[y]);
+ }
+ internal_curves_in_loop.clean_out();
+ }
+ //add removable loops curves to the master_curve_remove_list list
+ for(y=0;y<removable_slot_loop.size();y++)
+ {
+ removable_slot_loop[y]->curves(master_curve_remove_list);
+ }
+ }
+
+ //if no arcs are found to be removed, warn the user.
+ if(master_curve_remove_list.size()==0)
+ {
+ //I'm returning success here even though no curves were found
+ {
+ PRINT_INFO( "Failed to find any feature(s) which met user requirements\n\n" );
+ }
+ return CUBIT_SUCCESS;
+ }
+ else if(preview == CUBIT_TRUE)
+ {
+ GfxPreview::clear();
+
+ for(i=0; i<master_curve_remove_list.size();i++)
+ {
+ CubitStatus result;
+ GMem g_mem;
+
+ // get the graphics
+ result = master_curve_remove_list[i]->get_geometry_query_engine()->
+ get_graphics( master_curve_remove_list[i], &g_mem );
+
+ if (result==CUBIT_FAILURE || g_mem.pointListCount == 0)
+ {
+ PRINT_WARNING("Unable to preview a curve\n" );
+ double len = master_curve_remove_list[i]->
+ length_from_u(master_curve_remove_list[i]->start_param(),master_curve_remove_list[i]->end_param());
+
+ PRINT_WARNING("Curve len: %f\n",len);
+ }
+
+ // Draw the polyline
+ GfxPreview::draw_polyline( g_mem.point_list(), g_mem.pointListCount, CUBIT_BLUE );
+
+ }
+
+ //output the number of holes or slots which were found
+ PRINT_INFO("Found %d holes and %d slots which met idealization parameters\n\n", arc_LoopSM_list.size(),removable_slot_loop.size());
+ GfxPreview::flush();
+ return CUBIT_SUCCESS;
+ }
+ else
+ {
+ DLIList<BodySM*> new_bodysm_list;
+ //pass master_curve_remove_list to the tweak_remove command
+ CubitStatus stat = gme_ptr->tweak_remove(master_curve_remove_list, new_bodysm_list,CUBIT_FALSE, CUBIT_FALSE );
+
+ //update DAG
+ DLIList<Body*> new_body_list;
+ stat = finish_sm_op( old_body_list, new_bodysm_list ,new_body_list );
+ //output the number of holes or slots which were found
+ PRINT_INFO("Found %d holes, and %d slots which met idealization parameters\n\n", arc_LoopSM_list.size(), removable_slot_loop.size());
+ return CUBIT_SUCCESS;
+ }
+}
+
+//=============================================================================
+// Description: Create drop down surfaces from the external edges of a surface to another surface with options
+// Use it primarially when you have a doubler plate situation and you need
+// to connect them together with surfaces to represent a weld
+// Author : Jonathan Bugman
+// Date : 02/07/2008
+//=============================================================================
+CubitStatus GeometryModifyTool::create_surface_doubler(DLIList<RefEntity*> doubler_entity,
+ DLIList<RefEntity*> target_entity,
+ DLIList<Body*> &body_list_out,
+ CubitBoolean internal_flg,
+ CubitBoolean extend_flg,
+ CubitPlane *limit_plane,
+ CubitVector sweep_direction,
+ CubitBoolean preview)
+{
+ //need to switch the DLIList<RefEntity> to a DLIList<RefFace>
+ DLIList<RefFace*> doubler_face;
+ DLIList<RefFace*> target_face;
+ CAST_LIST( doubler_entity, doubler_face, RefFace);
+ CAST_LIST( target_entity, target_face, RefFace);
+
+ DLIList <Surface*> doubler_surface;
+ DLIList <Surface*> target_surface;
+ DLIList <Body*> old_body_list;
+ DLIList<RefFace*> tweak_face;
+ DLIList<Surface*> tweak_surface;
+ tweak_face+=doubler_face;
+ tweak_face+=target_face;
+ GeometryModifyEngine* gme_ptr;
+ int ii=0, i=0;
+
+ gme_ptr = tweak_setup(tweak_face,"doubler",old_body_list,tweak_surface);
+ int z;
+ for(z=0;z<doubler_face.size();z++)
+ {
+ doubler_surface.append(tweak_surface[z]);
+ }
+ for(z;z<tweak_face.size();z++)
+ {
+ target_surface.append(tweak_surface[z]);
+ }
+
+ DLIList<BodySM*> all_kept_bodies;
+ DLIList<BodySM*> body_convert;
+ DLIList<Surface*> copied_doubler_surface;
+ DLIList <BodySM*> tweak_target_bodySM;
+
+ for(z=0;z<doubler_surface.size();z++)
+ {
+ copied_doubler_surface.append(gme_ptr->make_Surface(doubler_surface[z]));
+ body_convert.append(copied_doubler_surface[z]->bodysm());
+ }
+
+ //each workflow is dependent on whether or not a sweep_direction is specified
+ if(sweep_direction == CubitVector(0,0,0))
+ {
+ DLIList<BodySM*> united_bodies;
+ DLIList<BodySM*> separate_bodies;
+ //this section takes all the doublers, unites them, and then splits them. If only one body
+ //then skip the aforementioned two steps.
+ if(doubler_surface.size()==1)
+ {
+ separate_bodies=body_convert;
+ }
+ else
+ {
+ if(gme_ptr->unite(body_convert,united_bodies) == CUBIT_FAILURE || united_bodies.size()==0 )
+ {
+ PRINT_ERROR( "Command failed at unite command\n" );
+ return CUBIT_FAILURE;
+ }
+
+ if(gme_ptr->split_body(united_bodies[0],separate_bodies) == CUBIT_FAILURE || separate_bodies.size()==0)
+ {
+ PRINT_ERROR( "Command failed at separate command\n" );
+ return CUBIT_FAILURE;
+ }
+ }
+ for(z=0; z<separate_bodies.size();z++)
+ {
+ DLIList<Surface*> body_surface;
+ separate_bodies[z]->surfaces(body_surface);
+
+ DLIList<CubitVector> doubler_surface_center_points;
+ int d=0;
+ for(d=0;d<body_surface.size();d++)
+ {
+ doubler_surface_center_points.append(body_surface[d]->bounding_box().center());
+ }
+ CubitVector doubler_normal,doubler_center_pt,doubler_to_target_vector,target_center_pt;
+ double extrude_distance = 0.0;
+
+ //make sure that the normal of the surface is pointing towards the target surface
+ //the thicken command thickens in the direction of the surface normal, normals are checked using dot product check
+ CubitVector center_pt = body_surface[0]->bounding_box().center();
+ body_surface[0]->closest_point(center_pt,&doubler_center_pt,&doubler_normal);
+ //adding this for loop because of l bracket doublers may have the first target surface perpendicular to an opposite side doubler surface
+ //resulting in the code erroneously failing
+ double dot=0.0;
+ int mm;
+ for(mm=0; mm<target_surface.size();mm++)
+ {
+ target_surface[mm]->closest_point_trimmed(doubler_center_pt, target_center_pt);
+ doubler_to_target_vector = target_center_pt - doubler_center_pt;
+ dot = doubler_to_target_vector.x()*doubler_normal.x()+doubler_to_target_vector.y()*doubler_normal.y()+doubler_to_target_vector.z()*doubler_normal.z();
+ if(fabs(dot)>1E-6)
+ {
+ mm=target_surface.size();
+ }
+ }
+ if(fabs(dot)<1E-6)
+ {
+ PRINT_ERROR( "Doubler and target surface are touching or are perpendicular to each other\n" );
+ for(ii =0;ii<separate_bodies.size();ii++)
+ {
+ GeometryQueryEngine* gqe = separate_bodies[ii]->get_geometry_query_engine();
+ gqe->delete_solid_model_entities(separate_bodies[ii]);
+ }
+ return CUBIT_FAILURE;
+ }
+ else if(dot < 0)
+ {
+ if(gme_ptr->reverse_body(separate_bodies[z])==CUBIT_FAILURE)
+ {
+ PRINT_ERROR( "Command failed at reverse body command.\n" );
+ for(ii =0;ii<separate_bodies.size();ii++)
+ {
+ GeometryQueryEngine* gqe = separate_bodies[ii]->get_geometry_query_engine();
+ gqe->delete_solid_model_entities(separate_bodies[ii]);
+ }
+ return CUBIT_FAILURE;
+ }
+ extrude_distance = 0.0001;
+ }
+ else
+ {
+ extrude_distance = 0.0001;
+ }
+
+ DLIList<BodySM*> thickened_doubler_bodySM;
+ DLIList<BodySM*> current_body;
+ current_body.append(separate_bodies[z]);
+
+ if(gme_ptr->thicken(current_body,thickened_doubler_bodySM,extrude_distance,CUBIT_FALSE) == CUBIT_FAILURE || thickened_doubler_bodySM.size()==0)
+ {
+ PRINT_ERROR( "Command failed at thicken command, this may be due to using a non-ACIS geometry engine\n" );
+ for(ii =0;ii<separate_bodies.size();ii++)
+ {
+ GeometryQueryEngine* gqe = separate_bodies[ii]->get_geometry_query_engine();
+ gqe->delete_solid_model_entities(separate_bodies[ii]);
+ }
+ return CUBIT_FAILURE;
+ }
+
+ //need to grab the newly created surface opposite the user selected one from the thicken function to carry it through for the tweak target
+ DLIList<Surface*> thicken_surfaces;
+ thickened_doubler_bodySM[0]->surfaces(thicken_surfaces);
+ DLIList <Surface*> post_thicken_doublers;
+
+ int y=0;
+ for(y=0;y<doubler_surface_center_points.size();y++)
+ {
+ doubler_center_pt = doubler_surface_center_points[y];
+ int r=0;
+ for(r=0;r<thicken_surfaces.size();r++)
+ {
+ CubitVector test_center_pt = thicken_surfaces[r]->bounding_box().center();
+ if((test_center_pt-doubler_center_pt).length()<=.000001)
+ {
+ post_thicken_doublers.append(thicken_surfaces[r]);
+ }
+ }
+ }
+
+ DLIList <LoopSM*> doubler_loopSM_list;
+ DLIList <Curve*> doubler_external_curves;
+ Curve* test_external_curves1;
+ Curve* test_external_curves2;
+
+ //need to do this in order to grab all curves, not just external IMPORTANT:THIS HAS TO BE DONE BEFORE THE tweak? COMMAND!
+ for(y=0;y<post_thicken_doublers.size();y++)
+ {
+ post_thicken_doublers[y]->loopsms(doubler_loopSM_list);
+ }
+ for(i=0;i<doubler_loopSM_list.size();i++)
+ {
+ doubler_loopSM_list[i]->curves(doubler_external_curves);
+ }
+
+ doubler_loopSM_list.clean_out();
+ tweak_target_bodySM.clean_out();
+ DLIList <LoopSM*> test_loopSM_list;
+ DLIList <Curve*> thicken_external_curves;
+ DLIList <Surface*> tweak_target_surface = thicken_surfaces;
+
+ //stepping through the surfaces from the thicken body
+ for(i=0; i < thicken_surfaces.size(); i++)
+ {
+ thicken_surfaces[i]->loopsms(test_loopSM_list);
+ //grabbing the external curves from the current thicken_surface
+ test_loopSM_list[0]->curves(thicken_external_curves);
+ test_loopSM_list.clean_out();
+ int j=0;
+ for(j=0;j<thicken_external_curves.size();j++)
+ {
+ //step through the first curve
+ test_external_curves1 = thicken_external_curves[j];
+ int k=0;
+ for(k=0; k<doubler_external_curves.size();k++)
+ {
+ //while stepping through the doubler plate curves, compare them to the test_test_surface curves
+ test_external_curves2 = doubler_external_curves[k];
+
+ //if the two are equal, they are touching the doulber and therefore are either the side surfaces or the doubler
+ if(test_external_curves2 == test_external_curves1)
+ {
+ //remove the surface from the tweak_target_surface list
+ tweak_target_surface.remove_all_with_value(thicken_surfaces[i]);
+ break;
+ }
+ }
+ if(test_external_curves2 == test_external_curves1)
+ {
+ break;
+ }
+
+ }
+ thicken_external_curves.clean_out();
+ }
+
+ //pass the found opposite surface into the tweak_target routine
+ if(gme_ptr->tweak_target(tweak_target_surface,target_surface,tweak_target_bodySM,extend_flg,limit_plane) == CUBIT_FAILURE || tweak_target_bodySM.size()==0)
+ {
+ PRINT_ERROR( "Command failed at Tweak_Target routine\n" );
+ for(ii =0;ii<thickened_doubler_bodySM.size();ii++)
+ {
+ GeometryQueryEngine* gqe = thickened_doubler_bodySM[ii]->get_geometry_query_engine();
+ gqe->delete_solid_model_entities(thickened_doubler_bodySM[ii]);
+ }
+ return CUBIT_FAILURE;
+ }
+
+ //fill out a tweak_body_surface list from tweak_target routine
+ DLIList<Surface*> tweak_body_surfaces;
+ tweak_target_bodySM[0]->surfaces(tweak_body_surfaces);
+ DLIList <Curve*> tweak_external_curves;
+ doubler_external_curves.clean_out();
+
+ //refilling DLIList's as needed based on internal_flg
+ //if we are not keeping internal surfaces we do not want it's curves in the doubler_external_curves list
+ //otherwise if we are, we do want the curves in the list for the following sections for loop
+ if(internal_flg==CUBIT_FALSE)
+ {
+ int j=0;
+ for(i=0;i<post_thicken_doublers.size();i++)
+ {
+ post_thicken_doublers[i]->loopsms(doubler_loopSM_list);
+ for(j=0;j<doubler_loopSM_list.size();j++)
+ {
+ LoopType loop_type = doubler_loopSM_list[j]->loop_type();
+ if(loop_type == LOOP_TYPE_EXTERNAL ||
+ loop_type == LOOP_TYPE_U_PERIODIC ||
+ loop_type == LOOP_TYPE_V_PERIODIC)
+ {
+ doubler_loopSM_list[j]->curves(doubler_external_curves);
+ break;
+ }
+ }
+ doubler_loopSM_list.clean_out();
+ }
+ }
+ else
+ {
+ for(i=0;i<post_thicken_doublers.size();i++)
+ {
+ post_thicken_doublers[i]->loopsms(doubler_loopSM_list);
+ }
+ for(i=0;i<doubler_loopSM_list.size();i++)
+ {
+ doubler_loopSM_list[i]->curves(doubler_external_curves);
+ }
+
+ }
+
+ DLIList <Surface*> surfaces_to_keep;
+ for(i=0;i<tweak_body_surfaces.size();i++)
+ {
+ tweak_body_surfaces[i]->loopsms(test_loopSM_list);
+
+ if(test_loopSM_list.size()==0)
+ {
+ PRINT_ERROR( "Command failed to find any doubler drop down curves\n" );
+ for(ii =0;ii<thickened_doubler_bodySM.size();ii++)
+ {
+ GeometryQueryEngine* gqe = thickened_doubler_bodySM[ii]->get_geometry_query_engine();
+ gqe->delete_solid_model_entities(thickened_doubler_bodySM[ii]);
+ }
+ return CUBIT_FAILURE;
+ }
+
+ test_loopSM_list[0]->curves(tweak_external_curves);
+ test_loopSM_list.clean_out();
+
+ int j=0;
+ for(j=0;j<tweak_external_curves.size();j++)
+ {
+ test_external_curves1 = tweak_external_curves[j];
+
+ int k=0;
+ for(k=0; k<doubler_external_curves.size();k++)
+ {
+ //while stepping through the doubler plate curves, compare them to the test_loop_list
+ test_external_curves2 = doubler_external_curves[k];
+
+ if(test_external_curves2 == test_external_curves1)
+ {
+ surfaces_to_keep.append(tweak_body_surfaces[i]);
+ break;
+ }
+ }
+ if(test_external_curves2 == test_external_curves1)
+ {
+ break;
+ }
+ }
+ tweak_external_curves.clean_out();
+ }
+
+ if(surfaces_to_keep.size()==0)
+ {
+ PRINT_ERROR( "Failed to find and keep surfaces\n" );
+ for(ii =0;ii<tweak_target_bodySM.size();ii++)
+ {
+ GeometryQueryEngine* gqe = tweak_target_bodySM[ii]->get_geometry_query_engine();
+ gqe->delete_solid_model_entities(tweak_target_bodySM[ii]);
+ }
+ return CUBIT_FAILURE;
+ }
+
+ //do this to remove the copied_doubler_surface since we no longer need the surface anymore
+ int c=0;
+ for(c=0;c<post_thicken_doublers.size();c++)
+ {
+ surfaces_to_keep.remove_all_with_value(post_thicken_doublers[c]);
+ }
+
+ DLIList <Surface*> surfaces_to_remove = tweak_body_surfaces;
+ surfaces_to_remove -= surfaces_to_keep;
+ DLIList<BodySM*> resulting_bodies;
+
+ //remove all surfaces in the surfaces_to_remove list
+ if(gme_ptr->tweak_remove(surfaces_to_remove,resulting_bodies,CUBIT_FALSE) == CUBIT_FAILURE || resulting_bodies.size()==0)
+ {
+ PRINT_ERROR( "Command failed at Tweak_Remove routine\n" );
+ for(ii =0;ii<tweak_target_bodySM.size();ii++)
+ {
+ GeometryQueryEngine* gqe = tweak_target_bodySM[ii]->get_geometry_query_engine();
+ gqe->delete_solid_model_entities(tweak_target_bodySM[ii]);
+ }
+ return CUBIT_FAILURE;
+ }
+ all_kept_bodies+=resulting_bodies;
+ }
+ }
+ else
+ {
+ DLIList<BodySM*> swept_bodies;
+ DLIList<BodySM*> swept_doubler_bodySM;
+
+ //take the copied_doubler_surface and extrude it along the sweep_direction to create a body
+ for(z=0;z<copied_doubler_surface.size();z++)
+ {
+ DLIList<GeometryEntity*> DLIList_copied_doubler_surface;
+ DLIList_copied_doubler_surface.append(copied_doubler_surface[z]);
+ if(gme_ptr->sweep_translational(DLIList_copied_doubler_surface,swept_doubler_bodySM,sweep_direction*0.0001,0.0,0,CUBIT_FALSE,CUBIT_FALSE) == CUBIT_FAILURE || swept_doubler_bodySM.size()==0)
+ {
+ PRINT_ERROR( "Command failed at sweep->extrude command\n" );
+ for(ii =0;ii<body_convert.size();ii++)
+ {
+ GeometryQueryEngine* gqe = body_convert[ii]->get_geometry_query_engine();
+ gqe->delete_solid_model_entities(body_convert[ii]);
+ }
+ return CUBIT_FAILURE;
+ }
+ swept_bodies+=swept_doubler_bodySM;
+ swept_doubler_bodySM.clean_out();
+ }
+
+ DLIList<BodySM*> united_bodies;
+ DLIList<BodySM*> separate_bodies;
+ //if more than one body, unite and split the newly created bodies, if only one body skip this step
+ //as the unite will fail
+ if(swept_bodies.size()==1)
+ {
+ separate_bodies=swept_bodies;
+ }
+ else
+ {
+ if(gme_ptr->unite(swept_bodies,united_bodies) == CUBIT_FAILURE || united_bodies.size()==0 )
+ {
+ PRINT_ERROR( "Command failed at unite command\n" );
+ return CUBIT_FAILURE;
+ }
+
+ if(gme_ptr->split_body(united_bodies[0],separate_bodies) == CUBIT_FAILURE || separate_bodies.size()==0)
+ {
+ PRINT_ERROR( "Command failed at separate command\n" );
+ return CUBIT_FAILURE;
+ }
+ }
+
+ //create another copy of copied_doubler_surface since copied_doubler_surface is going to be manipulated
+ DLIList<Surface*> temp_copied_doubler_surface=copied_doubler_surface;
+ for(z=0;z<separate_bodies.size();z++)
+ {
+ //need to grab the newly created surface opposite the user selected one from the thicken function to carry it through for the tweak target
+ //this will need to be changed to a for loop to account for multiple thickened bodies if we impliment multiple doubler surfaces
+ DLIList<Surface*> thicken_surfaces;
+ separate_bodies[z]->surfaces(thicken_surfaces);
+
+ //initializing a lot of variables to be used in the next few steps
+ DLIList<Surface*> master_surface_remove_list;
+ DLIList <Curve*> thicken_external_curves;
+ DLIList<Surface*> tweak_target_surface;
+ DLIList<Surface*> surfaces_to_remove;
+
+ //using a centerpoint of the surfaces, I want to find out which surface from the recently swept bodies corresponds to the surface of the body closest the target
+ //this has to be done because sweep_translational moves the source surface. Thicken on the otherhand does and doesn't based on number of surfaces being thickened.
+ int y=0;
+ for(y=0;y<temp_copied_doubler_surface.size();y++)
+ {
+ CubitVector doubler_center_pt = temp_copied_doubler_surface[y]->bounding_box().center();
+ int r=0;
+ for(r=0;r<thicken_surfaces.size();r++)
+ {
+ CubitVector test_center_pt = thicken_surfaces[r]->bounding_box().center();
+ if((test_center_pt-doubler_center_pt).length()<=.000001)
+ {
+ tweak_target_surface.append(thicken_surfaces[r]);
+ surfaces_to_remove.append(temp_copied_doubler_surface[y]);
+ }
+ }
+ }
+ //remove the manipulated surfaces from the temp_copied_doubler_surface list
+ temp_copied_doubler_surface-=surfaces_to_remove;
+ surfaces_to_remove.clean_out();
+
+ //grab all the curves of the doubler
+ DLIList <Curve*> doubler_external_curves;
+ DLIList <LoopSM*> doubler_loopSM_list;
+ for(y=0;y<tweak_target_surface.size();y++)
+ {
+ tweak_target_surface[y]->loopsms(doubler_loopSM_list);
+ }
+
+ for(i=0;i<doubler_loopSM_list.size();i++)
+ {
+ doubler_loopSM_list[i]->curves(doubler_external_curves);
+ }
+
+ Surface* temp_test_surface;
+ DLIList <Surface*> doubler_surface_for_this_body = thicken_surfaces;
+ Curve* test_external_curves1;
+ Curve* test_external_curves2;
+ DLIList <LoopSM*> test_loopSM_list;
+
+ for(i=0; i < thicken_surfaces.size(); i++)
+ {
+ //step through the thickened bodies surfaces
+ thicken_surfaces[i]->loopsms(test_loopSM_list);
+ temp_test_surface = thicken_surfaces[i];
+ //grabbing the external curve loop from the face and making it a DLIList <RefEdge*>
+ test_loopSM_list[0]->curves(thicken_external_curves);
+
+ int j=0;
+ for(j=0;j<thicken_external_curves.size();j++)
+ {
+ //step through the loop list
+ test_external_curves1 = thicken_external_curves[j];
+
+ int k=0;
+ for(k=0; k<doubler_external_curves.size();k++)
+ {
+ //while stepping through the doubler plate curves, compare them to the test_loop_list
+ test_external_curves2 = doubler_external_curves[k];
+
+ if(test_external_curves2 == test_external_curves1)
+ {
+ doubler_surface_for_this_body.remove_all_with_value(thicken_surfaces[i]);
+ break;
+ }
+ }
+ if(test_external_curves2 == test_external_curves1)
+ {
+ break;
+ }
+ }
+
+ thicken_external_curves.clean_out();
+ thicken_external_curves.reset();
+ test_loopSM_list.clean_out();
+ }
+
+ //DLIList <BodySM*> tweak_target_bodySM
+ tweak_target_bodySM.clean_out();
+ if(gme_ptr->tweak_target(tweak_target_surface,target_surface,tweak_target_bodySM,extend_flg,limit_plane) == CUBIT_FAILURE || tweak_target_bodySM.size()==0)
+ {
+ PRINT_ERROR( "Command failed at Tweak_Target routine\n" );
+ for(ii =0;ii<body_convert.size();ii++)
+ {
+ GeometryQueryEngine* gqe = body_convert[ii]->get_geometry_query_engine();
+ gqe->delete_solid_model_entities(body_convert[ii]);
+ }
+ return CUBIT_FAILURE;
+ }
+
+ //make note of the doubler_surface and add it to the delete list
+ master_surface_remove_list+=doubler_surface_for_this_body;
+
+ //clean out these DLIList's as they will be used later on
+ doubler_loopSM_list.clean_out();
+ doubler_external_curves.clean_out();
+
+ //refilling DLIList's as needed based on internal_flg
+ //basically if surfaces share a curve, that surface will be kept so if you don't want the internal surfaces
+ //create the list without the internal curves and they'll be removed
+ if(internal_flg==CUBIT_FALSE)
+ {
+ int j=0;
+ for(i=0;i<doubler_surface_for_this_body.size();i++)
+ {
+ doubler_surface_for_this_body[i]->loopsms(doubler_loopSM_list);
+ for(j=0;j<doubler_loopSM_list.size();j++)
+ {
+ LoopType loop_type = doubler_loopSM_list[j]->loop_type();
+ if(loop_type == LOOP_TYPE_EXTERNAL ||
+ loop_type == LOOP_TYPE_U_PERIODIC ||
+ loop_type == LOOP_TYPE_V_PERIODIC)
+ {
+ doubler_loopSM_list[j]->curves(doubler_external_curves);
+ break;
+ }
+
+ }
+ doubler_loopSM_list.clean_out();
+ }
+ }
+ else
+ {
+ for(i=0;i<doubler_surface_for_this_body.size();i++)
+ {
+ doubler_surface_for_this_body[i]->loopsms(doubler_loopSM_list);
+ }
+ for(i=0;i<doubler_loopSM_list.size();i++)
+ {
+ doubler_loopSM_list[i]->curves(doubler_external_curves);
+ }
+ }
+
+ //recreate the thicken_surfaces list based now on the bodies after the tweak_target command
+ thicken_surfaces.clean_out();
+ tweak_target_bodySM[0]->surfaces(thicken_surfaces);
+
+ DLIList <Surface*> surfaces_to_keep;
+ surfaces_to_remove = thicken_surfaces;
+ DLIList <Curve*> tweak_external_curves;
+
+ for(i=0;i<thicken_surfaces.size();i++)
+ {
+ thicken_surfaces[i]->loopsms(test_loopSM_list);
+ //grabs the external curves from face
+ test_loopSM_list[0]->curves(tweak_external_curves);
+
+ int j=0;
+ for(j=0;j<tweak_external_curves.size();j++)
+ {
+ //step through the loop list
+ test_external_curves1 = tweak_external_curves[j];
+
+ int k=0;
+ for(k=0; k<doubler_external_curves.size();k++)
+ {
+ //while stepping through the doubler plate curves, compare them to the test_loop_list
+ test_external_curves2 = doubler_external_curves[k];
+
+ if(test_external_curves2 == test_external_curves1)
+ {
+ surfaces_to_keep.append(thicken_surfaces[i]);
+ break;
+ }
+ }
+ if(test_external_curves2 == test_external_curves1)
+ {
+ break;
+ }
+ }
+ test_loopSM_list.clean_out();
+ tweak_external_curves.clean_out();
+ }
+
+ if(surfaces_to_keep.size()==0)
+ {
+ PRINT_ERROR( "Failed to find and keep tweak_target surfaces\n" );
+ for(ii =0;ii<tweak_target_bodySM.size();ii++)
+ {
+ GeometryQueryEngine* gqe = tweak_target_bodySM[ii]->get_geometry_query_engine();
+ gqe->delete_solid_model_entities(tweak_target_bodySM[ii]);
+ }
+ return CUBIT_FAILURE;
+ }
+
+ //subtract surfaces
+ surfaces_to_remove -= surfaces_to_keep;
+ master_surface_remove_list+=surfaces_to_remove;
+
+ DLIList<BodySM*> resulting_bodies;
+
+ if(gme_ptr->tweak_remove(master_surface_remove_list,resulting_bodies,CUBIT_FALSE) == CUBIT_FAILURE || resulting_bodies.size()==0)
+ {
+ PRINT_ERROR( "Command failed at Tweak_Remove routine\n" );
+ for(ii =0;ii<tweak_target_bodySM.size();ii++)
+ {
+ GeometryQueryEngine* gqe = tweak_target_bodySM[ii]->get_geometry_query_engine();
+ gqe->delete_solid_model_entities(tweak_target_bodySM[ii]);
+ }
+ return CUBIT_FAILURE;
+ }
+
+ //all_kept_bodies is a list of bodies that will eventually be passed into finish_sm_op at the end
+ all_kept_bodies+=resulting_bodies;
+ }
+ }
+
+ if(preview==CUBIT_FALSE)
+ {
+ DLIList<BodySM*> bodies_to_unite;
+ //check to see if their is only one body. If only one body skip over the unite and split because
+ //the unite command will fail (there is a check at the beginning to return cubit_failure)
+ //append the original doubler surfaces to the resulting body list
+
+ for(i=0;i<doubler_surface.size();i++)
+ {
+ all_kept_bodies.insert_first(doubler_surface[i]->bodysm());
+ }
+ if(all_kept_bodies.size()!=1)
+ {
+ if(gme_ptr->unite(all_kept_bodies,bodies_to_unite) == CUBIT_FAILURE || bodies_to_unite.size()==0 )
+ {
+ PRINT_ERROR( "Command failed at unite command\n" );
+ return CUBIT_FAILURE;
+ }
+ all_kept_bodies.clean_out();
+ if(gme_ptr->split_body(bodies_to_unite[0],all_kept_bodies) == CUBIT_FAILURE || all_kept_bodies.size()==0)
+ {
+ PRINT_ERROR( "Command failed at separate command\n" );
+ return CUBIT_FAILURE;
+ }
+ }
+ else
+ {
+ PRINT_WARNING( "Command may have failed at finding doubler surface(s) and appending them to the drop-down surfaces\n" );
+ return CUBIT_FAILURE;
+ }
+
+ //update DAG
+ CubitStatus stat;
+ stat = finish_sm_op( old_body_list, all_kept_bodies ,body_list_out );
+ return CUBIT_SUCCESS;
+ }
+ else
+ {
+ DLIList<Curve*> kept_curves;
+ for(i =0;i<all_kept_bodies.size();i++)
+ {
+ all_kept_bodies[i]->curves(kept_curves);
+ }
+
+ GfxPreview::clear();
+
+ for(i=0; i<kept_curves.size();i++)
+ {
+ CubitStatus result;
+ GMem g_mem;
+
+ // get the graphics
+ result = kept_curves[i]->get_geometry_query_engine()->
+ get_graphics( kept_curves[i], &g_mem );
+
+ if (result==CUBIT_FAILURE || g_mem.pointListCount == 0)
+ {
+ PRINT_WARNING("Unable to preview a curve\n" );;
+ double len = kept_curves[i]->
+ length_from_u(kept_curves[i]->start_param(),kept_curves[i]->end_param());
+
+ PRINT_WARNING("Curve len: %f\n",len);
+ }
+
+ // Draw the polyline
+ GfxPreview::draw_polyline( g_mem.point_list(), g_mem.pointListCount, CUBIT_BLUE );
+ }
+ GfxPreview::flush();
+ for(ii =0;ii<tweak_target_bodySM.size();ii++)
+ {
+ GeometryQueryEngine* gqe = tweak_target_bodySM[ii]->get_geometry_query_engine();
+ gqe->delete_solid_model_entities(tweak_target_bodySM[ii]);
+ }
+ return CUBIT_SUCCESS;
+ }
+}
+
+//=============================================================================
+// 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 GeometryModifyTool::tweak_bend( DLIList<Body*> &bend_bodies,
+ DLIList<Body*> &new_body_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 )
+{
+ if (CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE)
+ {
+ if (keep_old_body)
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( bend_bodies );
+ }
+
+ DLIList<BodySM*> new_body_sm_list;
+ DLIList<BodySM*> bend_bodies_sm;
+ GeometryModifyEngine* engine;
+ engine = common_modify_engine(bend_bodies, bend_bodies_sm);
+
+ if (!preview)
+ {
+ //do_attribute_setup();
+ //push_vg_attributes_before_modify(bend_bodies_sm);
+ }
+
+ CubitStatus result = engine->tweak_bend(
+ bend_bodies_sm,
+ new_body_sm_list,
+ neutral_root,
+ bend_axis,
+ bend_direction,
+ radius,
+ angle,
+ bend_regions,
+ width,
+ center_bend,
+ num_points,
+ keep_old_body,
+ preview);
+
+ if (result == CUBIT_FAILURE)
+ {
+ if (!preview)
+ {
+ //remove_pushed_attributes(bend_bodies_sm, bend_bodies);
+ //do_attribute_cleanup();
+ }
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::remove_last_undo();
+ return CUBIT_FAILURE;
+ }
+
+ if (preview == CUBIT_FALSE)
+ {
+ //restore_vg_after_modify(new_body_sm_list, bend_bodies, engine);
+ //remove_pushed_attributes(new_body_sm_list, bend_bodies);
+
+ // Update DAG
+ CubitStatus stat = finish_sm_op( bend_bodies, new_body_sm_list, new_body_list );
+ if (CubitUndo::get_undo_enabled())
+ {
+ if (stat == CUBIT_SUCCESS)
+ CubitUndo::note_result_bodies( new_body_list );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
+ //do_attribute_cleanup();
+
+ // Update graphics
+ /*
+ bend_bodies.reset();
+ int i = 0;
+ for (i = 0; i < bend_bodies.size(); i++)
+ {
+ Body* body_ptr = bend_bodies.get_and_step();
+ body_ptr->notify_all_observers( GEOMETRY_MODIFIED );
+ }//*/
+
+ // get list of entities to update
+ DLIList<RefEntity*> entities_to_update;
+ int i;
+ for(i=0; i < new_body_sm_list.size(); i++)
+ {
+ BodySM* bodysm = new_body_sm_list.get_and_step();
+ DLIList<TopologyBridge*> to_check;
+ DLIList<TopologyBridge*> tmp;
+ DLIList<Surface*> surfs;
+ bodysm->surfaces(surfs);
+ DLIList<Curve*> curves;
+ bodysm->curves(curves);
+ DLIList<Point*> points;
+ bodysm->points(points);
+ to_check.append(bodysm);
+ to_check.append(bodysm->lump());
+ CAST_LIST_TO_PARENT(surfs, tmp);
+ to_check += tmp;
+ CAST_LIST_TO_PARENT(curves, tmp);
+ to_check += tmp;
+ CAST_LIST_TO_PARENT(points, tmp);
+ to_check += tmp;
+
+ int k;
+ for(k=0; k<to_check.size(); k++)
+ if(BridgeManager* m = to_check.get_and_step()->bridge_manager())
+ if(TopologyEntity* t = m->topology_entity())
+ entities_to_update.append(CAST_TO(t, RefEntity));
+
+ }
+ // Update graphics
+ while (entities_to_update.size())
+ entities_to_update.pop()->notify_all_observers(GEOMETRY_MODIFIED);
+
+ return stat;
+ }
+
+ return CUBIT_SUCCESS;
+}
+
+
+
+//=============================================================================
+// Description: Chamfer curves on solid and 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.
// Author : Steve Storm
// Date : 03/25/05
//=============================================================================
@@ -7395,30 +12453,6 @@
CubitBoolean keep_old_body,
CubitBoolean preview )
{
- // Make sure curves are not part of a sheet body
- // Get unique volumes that the curves are attached to
- DLIList<RefVolume*> ref_volume_list;
- int i;
- RefEdge *ref_edge_ptr;
- for( i=ref_edge_list.size(); i--; )
- {
- ref_edge_ptr = ref_edge_list.get_and_step();
- DLIList<RefVolume*> tmp_ref_volume_list;
- ref_edge_ptr->ref_volumes( tmp_ref_volume_list );
- ref_volume_list.merge_unique( tmp_ref_volume_list );
- }
-
- RefVolume *ref_volume_ptr;
- for( i=ref_volume_list.size(); i--; )
- {
- ref_volume_ptr = ref_volume_list.get_and_step();
- if( ref_volume_ptr->is_sheet() )
- {
- PRINT_ERROR( "Cannot chamfer curves on sheet bodies\n" );
- return CUBIT_FAILURE;
- }
- }
-
DLIList<Curve*> curve_list(ref_edge_list.size());
DLIList<Body*> old_body_list;
GeometryModifyEngine* gme_ptr;
@@ -7427,6 +12461,14 @@
if( !gme_ptr )
return CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ if( keep_old_body )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( ref_edge_list );
+ }
+
// Do chamfering
DLIList<BodySM*> new_bodysm_list;
if( gme_ptr->tweak_chamfer( curve_list, left_offset, new_bodysm_list,
@@ -7436,13 +12478,414 @@
if( preview == CUBIT_FALSE )
{
// Update DAG
- if (!finish_sm_op( old_body_list, new_bodysm_list, new_body_list ))
- return CUBIT_FAILURE;
+ CubitStatus stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list );
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( stat == CUBIT_SUCCESS )
+ CubitUndo::note_result_bodies( new_body_list );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
+ return stat;
}
-
return CUBIT_SUCCESS;
}
+void GeometryModifyTool::propagate_from_small_edge(RefEdge *edge,
+ DLIList<RefEdge*> &small_edges,
+ DLIList<RefFace*> &narrow_faces,
+ DLIList<RefFace*> &processed_faces,
+ double small_edge_length)
+{
+ int i, j;
+ // First find any small edges connected to this edge.
+ DLIList<RefVertex*> edge_verts;
+ edge->ref_vertices(edge_verts);
+ for(i=edge_verts.size(); i--;)
+ {
+ RefVertex *vert = edge_verts.get_and_step();
+ DLIList<RefEdge*> vert_edges;
+ vert->ref_edges(vert_edges);
+ for(j=vert_edges.size(); j--;)
+ {
+ RefEdge *cur_edge = vert_edges.get_and_step();
+ if(cur_edge != edge && !cur_edge->marked())
+ {
+ // Mark of > 0 means it has been processed.
+ cur_edge->marked(1);
+ if(cur_edge->get_arc_length() < small_edge_length)
+ {
+ small_edges.append(cur_edge);
+ // Mark of 2 means it is a small edge.
+ cur_edge->marked(2);
+ propagate_from_small_edge(cur_edge, small_edges, narrow_faces,
+ processed_faces, small_edge_length);
+ }
+ }
+ }
+ }
+ // Now look at adjacent narrow faces and recursively process them.
+ DLIList<RefFace*> edge_faces;
+ edge->ref_faces(edge_faces);
+ for(i=edge_faces.size(); i--;)
+ {
+ RefFace *cur_face = edge_faces.get_and_step();
+ if(!cur_face->marked())
+ {
+ cur_face->marked(1);
+ if(GeomMeasureTool::narrow_region_exists(cur_face, small_edge_length))
+ {
+ DLIList<CubitVector> split_pos1_list;
+ DLIList<CubitVector> split_pos2_list;
+ GeomMeasureTool::find_split_points_for_narrow_regions(cur_face,
+ small_edge_length, split_pos1_list, split_pos2_list);
+ if(split_pos1_list.size() == 0)
+ {
+ narrow_faces.append_unique(cur_face);
+ propagate_over_narrow_face(cur_face, edge, processed_faces,
+ small_edges, narrow_faces, small_edge_length);
+ }
+ }
+ }
+ }
+}
+
+void GeometryModifyTool::propagate_over_narrow_face(RefFace *narrow_face,
+ RefEdge *edge,
+ DLIList<RefFace*> &processed_faces,
+ DLIList<RefEdge*> &small_edges,
+ DLIList<RefFace*> &narrow_faces,
+ double small_edge_length)
+{
+ int i, j;
+ processed_faces.append(narrow_face);
+ DLIList<RefEdge*> face_edges;
+ narrow_face->ref_edges(face_edges);
+ for(i=face_edges.size(); i--;)
+ {
+ RefEdge *cur_edge = face_edges.get_and_step();
+ if(cur_edge != edge && !cur_edge->marked())
+ {
+ cur_edge->marked(1);
+ if(cur_edge->get_arc_length() < small_edge_length)
+ {
+ cur_edge->marked(2);
+ small_edges.append(cur_edge);
+ propagate_from_small_edge(cur_edge, small_edges,
+ narrow_faces, processed_faces, small_edge_length);
+ }
+ else
+ {
+ DLIList<RefFace*> edge_faces;
+ cur_edge->ref_faces(edge_faces);
+ for(j=edge_faces.size(); j--;)
+ {
+ RefFace *cur_face = edge_faces.get_and_step();
+ if(cur_face != narrow_face)
+ {
+ if(!cur_face->marked())
+ {
+ cur_face->marked(1);
+ if(GeomMeasureTool::narrow_region_exists(cur_face, small_edge_length))
+ {
+ DLIList<CubitVector> split_pos1_list;
+ DLIList<CubitVector> split_pos2_list;
+ GeomMeasureTool::find_split_points_for_narrow_regions(cur_face,
+ small_edge_length, split_pos1_list, split_pos2_list);
+ if(split_pos1_list.size() == 0)
+ {
+ narrow_faces.append_unique(cur_face);
+ propagate_over_narrow_face(cur_face, edge, processed_faces,
+ small_edges, narrow_faces, small_edge_length);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+CubitStatus GeometryModifyTool::remove_topology( DLIList<RefEdge*> &ref_edge_list,
+ DLIList<RefFace*> &ref_face_list,
+ double backoff_distance,
+ double small_curve_size,
+ DLIList<Body*> &new_body_list,
+ CubitBoolean propagate,
+ CubitBoolean preview)
+{
+ int i, j;
+ CubitStatus ret = CUBIT_SUCCESS;
+ DLIList<Surface*> surf_list;
+ DLIList<Curve*> curve_list;
+ DLIList<Body*> old_body_list;
+ GeometryModifyEngine *gme_ptr1=NULL, *gme_ptr2=NULL, *gme_ptr=NULL;
+ Body *b1=NULL, *b2=NULL, *b=NULL;
+
+ if(ref_edge_list.size())
+ b1 = ref_edge_list.get()->body();
+ if(ref_face_list.size())
+ b2 = ref_face_list.get()->body();
+
+ if(b1 && b2)
+ {
+ if(b1 == b2)
+ b = b1;
+ }
+ else if(b1)
+ b = b1;
+ else if(b2)
+ b = b2;
+
+ if(b)
+ old_body_list.append(b);
+ else
+ {
+ PRINT_ERROR("Failed to find an owning body for the topology being removed.\n");
+ ret = CUBIT_FAILURE;
+ }
+
+ if(ret == CUBIT_SUCCESS)
+ {
+ if (!okay_to_modify( old_body_list, "REMOVE_TOPOLOGY" ))
+ ret = CUBIT_FAILURE;
+ else
+ {
+ // Remove any edges from the list that aren't small enough.
+ DLIList<RefEdge*> edges_to_remove;
+ for(i=ref_edge_list.size(); i--;)
+ {
+ RefEdge* re = ref_edge_list.get_and_step();
+ if(re->get_arc_length() > small_curve_size)
+ {
+ edges_to_remove.append(re);
+ PRINT_INFO("Ignoring curve %d as it is not a small curve based on the input. "
+ "Try a larger small_curve_size value.\n", re->id());
+ }
+ }
+ ref_edge_list -= edges_to_remove;
+
+ // Remove any faces from the list that don't have at least one small edge.
+ DLIList<RefFace*> faces_to_remove;
+ for(i=ref_face_list.size(); i--;)
+ {
+ DLIList<RefEdge*> face_edges;
+ RefFace* rf = ref_face_list.get_and_step();
+ rf->ref_edges(face_edges);
+ int face_ok = 0;
+ for(j=face_edges.size(); j && !face_ok; j--)
+ {
+ RefEdge* cur_edge = face_edges.get_and_step();
+ if(cur_edge->get_arc_length() <= small_curve_size)
+ face_ok = 1;
+ }
+ if(!face_ok)
+ {
+ faces_to_remove.append(rf);
+ PRINT_INFO("Ignoring surface %d as it does not have at least one small curve in it based on the input. "
+ "Try a larger small_curve_size value.\n", rf->id());
+ }
+ }
+ ref_face_list -= faces_to_remove;
+ }
+
+ if(ref_face_list.size() > 0 || ref_edge_list.size() > 0)
+ {
+ // If told to do so propagate the topology to be removed to include
+ // other narrow surfaces and small edges.
+ if(propagate)
+ {
+ // Get all of the small edges into a single list.
+ DLIList<RefEdge*> small_edges = ref_edge_list;
+ for(i=ref_face_list.size(); i--;)
+ {
+ RefFace *face = ref_face_list.get_and_step();
+ DLIList<RefEdge*> edges;
+ face->ref_edges(edges);
+ for(j=edges.size(); j--;)
+ {
+ RefEdge *edge = edges.get_and_step();
+ if(edge->get_arc_length() < small_curve_size)
+ small_edges.append(edge);
+ }
+ }
+ small_edges.uniquify_ordered();
+
+ DLIList<RefFace*> processed_faces;
+ DLIList<RefEdge*> copy_of_small_edges = small_edges;
+ DLIList<RefFace*> narrow_faces;
+
+ DLIList<RefFace*> all_faces;
+ DLIList<RefEdge*> all_edges;
+
+ // Set all of the marked flags to 0.
+ b->ref_faces(all_faces);
+ for(i=all_faces.size(); i>0; i--)
+ all_faces.get_and_step()->marked(0);
+
+ b->ref_edges(all_edges);
+ for(i=all_edges.size(); i>0; i--)
+ all_edges.get_and_step()->marked(0);
+
+ // Mark of >0 means it has been processed.
+ // Mark of 2 means it is a small edge.
+ for(i=small_edges.size(); i>0; i--)
+ small_edges.get_and_step()->marked(2);
+
+ // First look at all of the edges connected to small edges
+ // to see if there are other small edges.
+ while(copy_of_small_edges.size())
+ {
+ RefEdge *edge = copy_of_small_edges.extract();
+ propagate_from_small_edge(edge, small_edges,
+ narrow_faces, processed_faces, small_curve_size);
+ }
+
+ ref_face_list += narrow_faces;
+ ref_face_list.uniquify_ordered();
+
+ ref_edge_list = small_edges;
+ ref_edge_list.uniquify_ordered();
+ // Append to face list here so we don't lose the ones that were passed in.
+ }
+ }
+ else
+ {
+ PRINT_WARNING("No entities to remove.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+
+ if(ret == CUBIT_SUCCESS)
+ {
+ if(ref_edge_list.size())
+ {
+ for(i=ref_edge_list.size(); i--;)
+ {
+ RefEdge *re = ref_edge_list.get_and_step();
+ Curve *cur = re->get_curve_ptr();
+ DLIList<TopologyBridge*> tmp_curve_list;
+ GeometryQueryEngine *gqe = cur->get_geometry_query_engine();
+ gqe->get_underlying_curves(cur, tmp_curve_list);
+ if(tmp_curve_list.size() == 0)
+ tmp_curve_list.append(cur);
+ for(int p=tmp_curve_list.size(); p--;)
+ {
+ Curve *crv = dynamic_cast<Curve*>(tmp_curve_list.get_and_step());
+ if(!gme_ptr1)
+ gme_ptr1 = get_engine(crv);
+ curve_list.append(crv);
+ }
+ }
+ }
+ if(ref_face_list.size())
+ {
+ for(i=ref_face_list.size(); i--;)
+ {
+ RefFace *rf = ref_face_list.get_and_step();
+ Surface *sur = rf->get_surface_ptr();
+ DLIList<TopologyBridge*> tmp_surf_list;
+ GeometryQueryEngine *gqe = sur->get_geometry_query_engine();
+ gqe->get_underlying_surfaces(sur, tmp_surf_list);
+ if(tmp_surf_list.size() == 0)
+ tmp_surf_list.append(sur);
+ for(int p=tmp_surf_list.size(); p--;)
+ {
+ Surface *srf = dynamic_cast<Surface*>(tmp_surf_list.get_and_step());
+ if(!gme_ptr2)
+ gme_ptr2 = get_engine(srf);
+ surf_list.append(srf);
+ }
+ }
+ }
+ if(gme_ptr1 && gme_ptr2)
+ {
+ if(gme_ptr1 == gme_ptr2)
+ gme_ptr = gme_ptr1;
+ }
+ else if(gme_ptr1)
+ gme_ptr = gme_ptr1;
+ else if(gme_ptr2)
+ gme_ptr = gme_ptr2;
+
+ if(!gme_ptr)
+ {
+ PRINT_ERROR("Failed to find a geometry modify engine.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+
+ if(ret == CUBIT_SUCCESS)
+ {
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ DLIList<Body*> bodies;
+ int i;
+ for( i=ref_face_list.size(); i--; )
+ {
+ RefFace* ref_face = ref_face_list.get_and_step();
+ bodies.append( ref_face->body() );
+ }
+ for( i=ref_edge_list.size(); i--; )
+ {
+ RefEdge* ref_edge = ref_edge_list.get_and_step();
+ bodies.append( ref_edge->body() );
+ }
+ bodies.uniquify_unordered();
+ CubitUndo::save_state_with_cubit_file( bodies );
+ }
+
+ if(preview == CUBIT_FALSE)
+ do_attribute_setup();
+
+ DLIList<BodySM*> body_sm_list(old_body_list.size());
+ GeometryModifyEngine* gme = common_modify_engine(old_body_list, body_sm_list);
+
+ if(preview == CUBIT_FALSE)
+ push_vg_attributes_before_modify(body_sm_list);
+
+ DLIList<BodySM*> new_bodysm_list;
+ if(gme_ptr->remove_topology(curve_list, surf_list, backoff_distance, small_curve_size,
+ new_bodysm_list, preview) == CUBIT_FAILURE)
+ {
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
+
+ if(!preview)
+ remove_pushed_attributes(new_bodysm_list, old_body_list);
+
+ ret = CUBIT_FAILURE;
+ }
+ else
+ {
+ if( preview == CUBIT_FALSE )
+ {
+ restore_vg_after_modify(new_bodysm_list, old_body_list, gme);
+ remove_pushed_attributes(new_bodysm_list, old_body_list);
+
+ // Update DAG
+ ret = finish_sm_op( old_body_list, new_bodysm_list, new_body_list );
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( ret == CUBIT_FAILURE)
+ CubitUndo::remove_last_undo();
+ else
+ CubitUndo::note_result_bodies( new_body_list );
+ }
+ }
+ }
+
+ if(preview == CUBIT_FALSE)
+ do_attribute_cleanup();
+ }
+
+ return ret;
+}
+
//=============================================================================
// 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.
@@ -7576,6 +13019,14 @@
curve3 = dynamic_cast<Curve*>(bridge);
}
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ if( keep_old_body )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( ref_vertex_list );
+ }
+
// Do chamfering
DLIList<BodySM*> new_bodysm_list;
if( gme_ptr->tweak_chamfer( point_list, offset1, new_bodysm_list, curve1, offset2,
@@ -7585,8 +13036,16 @@
if( preview == CUBIT_FALSE )
{
// Update DAG
- if (!finish_sm_op( old_body_list, new_bodysm_list, new_body_list ))
- return CUBIT_FAILURE;
+ CubitStatus stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list );
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( stat == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+ else if( keep_old_body )
+ CubitUndo::note_result_bodies( new_body_list );
+ }
+ return stat;
}
return CUBIT_SUCCESS;
@@ -7594,7 +13053,7 @@
//=============================================================================
// Description: Create a round fillet (or blend) at the given curves on solid
-// bodies.
+// or sheet bodies.
// Author : Steve Storm
// Date : 03/25/05
//=============================================================================
@@ -7604,30 +13063,6 @@
CubitBoolean keep_old_body,
CubitBoolean preview )
{
- // Make sure curves are not part of a sheet body
- // Get unique volumes that the curves are attached to
- DLIList<RefVolume*> ref_volume_list;
- int i;
- RefEdge *ref_edge_ptr;
- for( i=ref_edge_list.size(); i--; )
- {
- ref_edge_ptr = ref_edge_list.get_and_step();
- DLIList<RefVolume*> tmp_ref_volume_list;
- ref_edge_ptr->ref_volumes( tmp_ref_volume_list );
- ref_volume_list.merge_unique( tmp_ref_volume_list );
- }
-
- RefVolume *ref_volume_ptr;
- for( i=ref_volume_list.size(); i--; )
- {
- ref_volume_ptr = ref_volume_list.get_and_step();
- if( ref_volume_ptr->is_sheet() )
- {
- PRINT_ERROR( "Cannot fillet curves on sheet bodies\n" );
- return CUBIT_FAILURE;
- }
- }
-
DLIList<Curve*> curve_list(ref_edge_list.size());
DLIList<Body*> old_body_list;
GeometryModifyEngine* gme_ptr;
@@ -7636,6 +13071,14 @@
if( !gme_ptr )
return CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ if( keep_old_body )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( ref_edge_list );
+ }
+
// Do filleting
DLIList<BodySM*> new_bodysm_list;
if( gme_ptr->tweak_fillet(curve_list, radius, new_bodysm_list, keep_old_body,
@@ -7645,17 +13088,25 @@
if( preview == CUBIT_FALSE )
{
// Update DAG
- if (!finish_sm_op( old_body_list, new_bodysm_list, new_body_list ))
- return CUBIT_FAILURE;
+ CubitStatus stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list );
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( stat == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+ else if( keep_old_body )
+ CubitUndo::note_result_bodies( new_body_list );
+ }
+
+ return stat;
}
-
return CUBIT_SUCCESS;
}
//=============================================================================
// 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.
+// or sheet body. The fillet has a variable radius from the start
+// to the end of the curve.
// Author : Steve Storm
// Date : 03/25/05
//=============================================================================
@@ -7666,23 +13117,6 @@
CubitBoolean keep_old_body,
CubitBoolean preview )
{
- // Make sure curve is not part of a sheet body
- // Get unique volumes that the curves are attached to
- DLIList<RefVolume*> ref_volume_list;
- ref_edge_ptr->ref_volumes( ref_volume_list );
-
- int i;
- RefVolume *ref_volume_ptr;
- for( i=ref_volume_list.size(); i--; )
- {
- ref_volume_ptr = ref_volume_list.get_and_step();
- if( ref_volume_ptr->is_sheet() )
- {
- PRINT_ERROR( "Cannot fillet curves on sheet bodies\n" );
- return CUBIT_FAILURE;
- }
- }
-
DLIList<Curve*> curve_list(1);
DLIList<Body*> old_body_list;
GeometryModifyEngine* gme_ptr;
@@ -7694,26 +13128,52 @@
if( !gme_ptr )
return CUBIT_FAILURE;
- Curve *curve_ptr = curve_list.get();
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ if( keep_old_body )
+ CubitUndo::save_state();
+ else
+ {
+ DLIList<RefEdge*> edges(1);
+ edges.append( ref_edge_ptr );
+ CubitUndo::save_state_with_cubit_file( edges );
+ }
+ }
// Do filleting
BodySM *new_bodysm_ptr;
- if( gme_ptr->tweak_fillet( curve_ptr, start_radius, end_radius, new_bodysm_ptr,
- keep_old_body, preview ) == CUBIT_FAILURE )
- return CUBIT_FAILURE;
+ Curve *curve_ptr = curve_list.get();
+ CubitStatus stat = gme_ptr->tweak_fillet( curve_ptr, start_radius,
+ end_radius, new_bodysm_ptr,
+ keep_old_body, preview );
+ if( CubitUndo::get_undo_enabled() )
+ if( stat == CUBIT_FAILURE)
+ CubitUndo::remove_last_undo();
+
+ if( stat == CUBIT_FAILURE )
+ return stat;
+
if( preview == CUBIT_FALSE )
{
// Update DAG
DLIList<BodySM*> new_bodysm_list;
new_bodysm_list.append( new_bodysm_ptr );
DLIList<Body*> new_body_list;
- if (!finish_sm_op( old_body_list, new_bodysm_list, new_body_list ))
- return CUBIT_FAILURE;
+ stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list );
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( stat == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+ else if( keep_old_body )
+ CubitUndo::note_result_bodies( new_body_list );
+ }
+
new_body_ptr = new_body_list.get();
+
+ return stat;
}
-
return CUBIT_SUCCESS;
}
@@ -7738,19 +13198,42 @@
if( !gme_ptr )
return CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ if( keep_old_body )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( ref_vertex_list );
+ }
+
// Do filleting
DLIList<BodySM*> new_bodysm_list;
- if( gme_ptr->tweak_fillet( point_list, radius, new_bodysm_list, keep_old_body,
- preview ) == CUBIT_FAILURE )
- return CUBIT_FAILURE;
+ CubitStatus stat = gme_ptr->tweak_fillet( point_list, radius,
+ new_bodysm_list, keep_old_body,
+ preview );
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ if( stat == CUBIT_FAILURE)
+ CubitUndo::remove_last_undo();
+
+ if( stat == CUBIT_FAILURE )
+ return stat;
+
if( preview == CUBIT_FALSE )
{
// Update DAG
- if (!finish_sm_op( old_body_list, new_bodysm_list, new_body_list ))
- return CUBIT_FAILURE;
+ stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list );
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( stat == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+ else if( keep_old_body )
+ CubitUndo::note_result_bodies( new_body_list );
+ }
+
+ return stat;
}
-
return CUBIT_SUCCESS;
}
@@ -7769,20 +13252,72 @@
DLIList<Body*> old_body_list;
GeometryModifyEngine* gme_ptr;
- gme_ptr = tweak_setup( ref_face_list, "Moving", old_body_list, surface_list );
+ gme_ptr = tweak_setup( ref_face_list, "Moving", old_body_list, surface_list, CUBIT_TRUE );
if (!gme_ptr)
return CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ if( keep_old_body )
+ CubitUndo::save_state();
+ else
+ {
+ int i;
+ DLIList<RefEdge*> ref_edges;
+ for( i=ref_face_list.size(); i--; )
+ ref_face_list.get_and_step()->ref_edges( ref_edges );
+ ref_edges.uniquify_unordered();
+ CubitUndo::save_state_with_cubit_file( ref_edges );
+ }
+ }
+
+ int i;
+ DLIList<BodySM*> body_sms;
+ for(i=old_body_list.size(); i--;)
+ {
+ BodySM* bsm = old_body_list.get_and_step()->get_body_sm_ptr();
+ if(bsm)
+ body_sms.append_unique(bsm);
+ }
+
+ if(!preview)
+ {
+ do_attribute_setup();
+ push_vg_attributes_before_modify(body_sms);
+ }
+
// Do move
DLIList<BodySM*> new_bodysm_list;
- if( gme_ptr->tweak_move( surface_list, delta, new_bodysm_list, keep_old_body,
- preview ) == CUBIT_FAILURE )
- return CUBIT_FAILURE;
+ CubitStatus stat = gme_ptr->tweak_move( surface_list, delta,
+ new_bodysm_list, keep_old_body,
+ preview );
+
+ if( CubitUndo::get_undo_enabled() )
+ if( stat == CUBIT_FAILURE)
+ CubitUndo::remove_last_undo();
+
+ if( stat == CUBIT_FAILURE )
+ {
+ if(!preview)
+ {
+ remove_pushed_attributes(new_bodysm_list, old_body_list);
+ do_attribute_cleanup();
+ }
+ return stat;
+ }
+ else
+ {
+ if(!preview)
+ {
+ restore_vg_after_modify(new_bodysm_list, old_body_list, gme_ptr);
+ remove_pushed_attributes(new_bodysm_list, old_body_list);
+ }
+ }
+
// loop body sm list and find surfaces that need updating.
// this is to account for some cases where the topology doesn't change, but the geometry does.
DLIList<RefEntity*> entities_to_update;
- int i;
for(i=0; i<new_bodysm_list.size(); i++)
{
BodySM* bodysm = new_bodysm_list.get_and_step();
@@ -7831,15 +13366,114 @@
}
}
- // Update DAG
- if (!finish_sm_op( old_body_list, new_bodysm_list, new_body_list ))
- return CUBIT_FAILURE;
+ if( preview == CUBIT_FALSE )
+ {
+ // Update DAG
+ stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list );
- // Update graphics
- while (entities_to_update.size())
- entities_to_update.pop()->notify_all_observers( GEOMETRY_MODIFIED );
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( stat == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+ else if( keep_old_body )
+ CubitUndo::note_result_bodies( new_body_list );
+ }
- return CUBIT_SUCCESS;
+ // Update graphics
+ while (entities_to_update.size())
+ entities_to_update.pop()->notify_all_observers( GEOMETRY_MODIFIED );
+
+ do_attribute_cleanup();
+ }
+
+
+ //collect all the new faces
+ DLIList<RefFace*> new_faces;
+ for( i=new_body_list.size(); i--; )
+ {
+ Body *new_body = new_body_list.get_and_step();
+ DLIList<RefFace*> tmp_faces;
+ new_body->ref_faces( tmp_faces );
+ new_faces += tmp_faces;
+ }
+
+ //unmerge any merged adjacent surfaces or
+ //merged curves in unmerged adjacent surfaces
+ DLIList<RefFace*> adjacent_faces_to_unmerge;
+ DLIList<RefEdge*> adjacent_edges_to_unmerge;
+ for(i=ref_face_list.size(); i--;)
+ {
+ RefFace *tweaked_face = ref_face_list.get_and_step();
+ if( !new_faces.move_to( tweaked_face ) )
+ continue;
+
+ //get all the edges of the face you tweaked
+ DLIList<RefEdge*> tweaked_face_edges;
+ tweaked_face->ref_edges( tweaked_face_edges );
+ adjacent_edges_to_unmerge += tweaked_face_edges;
+
+ //get all the adjacent faces to this edge
+ int j;
+ for( j=tweaked_face_edges.size(); j--; )
+ {
+ RefEdge *tmp_edge = tweaked_face_edges.get_and_step();
+ DLIList<RefFace*> tmp_faces;
+ tmp_edge->ref_faces( tmp_faces );
+ tmp_faces.remove( tweaked_face );
+ adjacent_faces_to_unmerge += tmp_faces;
+ }
+
+ //get all edges not in the surface,
+ //sharing vertices with the surface
+ DLIList<RefVertex*> ref_vertices;
+ tweaked_face->ref_vertices( ref_vertices );
+ for( j=ref_vertices.size(); j--; )
+ {
+ RefVertex *tmp_vert = ref_vertices.get_and_step();
+ DLIList<RefEdge*> ref_edges;
+ tmp_vert->ref_edges( ref_edges );
+
+ int k;
+ for( k=ref_edges.size(); k--; )
+ {
+ RefEdge *tmp_edge = ref_edges.get_and_step();
+ if( !tweaked_face_edges.move_to( tmp_edge ) )
+ adjacent_edges_to_unmerge.append( tmp_edge );
+ }
+ }
+ }
+
+ //unmerge any adjacent faces
+ adjacent_faces_to_unmerge.uniquify_unordered();
+ for( i=adjacent_faces_to_unmerge.size(); i--; )
+ {
+ RefFace *ref_face = adjacent_faces_to_unmerge.get_and_step();
+
+ DLIList<TopologyBridge*> bridge_list;
+ ref_face->bridge_manager()->get_bridge_list(bridge_list);
+ if (bridge_list.size() > 1)
+ {
+ if( MergeTool::instance()->unmerge( ref_face ) )
+ PRINT_WARNING("Unmerging Surface %d\n", ref_face->id() );
+ }
+ }
+
+ //unmerge any adjacent edges
+ adjacent_edges_to_unmerge.uniquify_unordered();
+ for( i=adjacent_edges_to_unmerge.size(); i--; )
+ {
+ RefEdge *ref_edge = adjacent_edges_to_unmerge.get_and_step();
+ DLIList<TopologyBridge*> bridge_list;
+ ref_edge->bridge_manager()->get_bridge_list(bridge_list);
+ if (bridge_list.size() > 1)
+ {
+ if( MergeTool::instance()->unmerge( ref_edge) )
+ PRINT_WARNING("Unmerging Curve %d\n", ref_edge->id() );
+ }
+ }
+
+
+ return stat;
}
//=============================================================================
@@ -7861,24 +13495,48 @@
if (!gme_ptr)
return CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ if( keep_old_body )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( ref_edge_list );
+ }
+
// Do move
DLIList<BodySM*> new_bodysm_list;
- if( gme_ptr->tweak_move( curve_list, delta, new_bodysm_list, keep_old_body,
- preview )
- == CUBIT_FAILURE )
- return CUBIT_FAILURE;
+ CubitStatus stat = gme_ptr->tweak_move( curve_list, delta,
+ new_bodysm_list, keep_old_body,
+ preview );
- // Update DAG
- if (!finish_sm_op( old_body_list, new_bodysm_list, new_body_list ))
- return CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled() )
+ if( stat == CUBIT_FAILURE)
+ CubitUndo::remove_last_undo();
+ if( stat == CUBIT_FAILURE )
+ return stat;
+
+ if( preview == CUBIT_FALSE )
+ {
+ // Update DAG
+ stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list );
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( stat == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+ else if( keep_old_body )
+ CubitUndo::note_result_bodies( new_body_list );
+ }
+ }
+
// Update graphics
DLIList<Body*> moved_bodies(new_body_list);
moved_bodies.intersect(old_body_list);
while (moved_bodies.size())
moved_bodies.pop()->notify_sub_all_observers( GEOMETRY_MODIFIED );
- return CUBIT_SUCCESS;
+ return stat;
}
//=============================================================================
@@ -7887,30 +13545,153 @@
// Author : Steve Storm
// Date : 03/25/05
//=============================================================================
-CubitStatus GeometryModifyTool::tweak_offset( DLIList<RefFace*>& ref_face_list,
+CubitStatus GeometryModifyTool::tweak_offset( DLIList<RefFace*> &ref_face_list,
double offset_distance,
- DLIList<Body*>& new_body_list,
+ DLIList<RefFace*> *add_ref_face_list_ptr,
+ DLIList<double> *add_offset_list_ptr,
+ DLIList<Body*> &new_body_list,
CubitBoolean keep_old_body,
CubitBoolean preview )
{
+ DLIList<RefFace*> all_ref_face_list(ref_face_list.size());
+ all_ref_face_list = ref_face_list;
+ if( add_ref_face_list_ptr->size() )
+ all_ref_face_list += *add_ref_face_list_ptr;
+
DLIList<Surface*> surface_list(ref_face_list.size());
DLIList<Body*> old_body_list;
GeometryModifyEngine* gme_ptr;
- gme_ptr = tweak_setup( ref_face_list, "Offsetting", old_body_list, surface_list );
+ gme_ptr = tweak_setup( ref_face_list, "Offsetting", old_body_list, surface_list, CUBIT_TRUE );
if (!gme_ptr)
return CUBIT_FAILURE;
+ DLIList<Surface*> add_surface_list;
+ if( add_ref_face_list_ptr && add_ref_face_list_ptr->size() )
+ {
+ DLIList<Body*> old_body_list2;
+ GeometryModifyEngine* gme_ptr2 = tweak_setup( *add_ref_face_list_ptr, "Offsetting",
+ old_body_list2, add_surface_list, CUBIT_TRUE );
+ if (!gme_ptr2)
+ return CUBIT_FAILURE;
+ if( gme_ptr != gme_ptr2 )
+ {
+ PRINT_ERROR("Offsetting surfaces on volumes containing surfaces from different\n"
+ " geometry engines is not allowed.\n");
+ return CUBIT_FAILURE;
+ }
+ old_body_list.merge_unique( old_body_list2 );
+ }
+
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ if( keep_old_body )
+ CubitUndo::save_state();
+ else
+ {
+ int i;
+ DLIList<RefEdge*> ref_edges;
+ for( i=ref_face_list.size(); i--; )
+ all_ref_face_list.get_and_step()->ref_edges( ref_edges );
+ ref_edges.uniquify_unordered();
+ CubitUndo::save_state_with_cubit_file( ref_edges );
+ }
+ }
+
+ int i;
+ if(!preview)
+ {
+ DLIList<BodySM*> body_sms;
+ for(i=old_body_list.size(); i--;)
+ {
+ BodySM* bsm = old_body_list.get_and_step()->get_body_sm_ptr();
+ if(bsm)
+ body_sms.append_unique(bsm);
+ }
+
+ do_attribute_setup();
+ push_vg_attributes_before_modify(body_sms);
+ }
+
// Do offset
DLIList<BodySM*> new_bodysm_list;
- if( gme_ptr->tweak_offset( surface_list, offset_distance, new_bodysm_list,
- keep_old_body, preview ) == CUBIT_FAILURE )
- return CUBIT_FAILURE;
+ CubitStatus stat;
+ if( add_surface_list.size() )
+ stat = gme_ptr->tweak_offset( surface_list, offset_distance,
+ &add_surface_list, add_offset_list_ptr,
+ new_bodysm_list, keep_old_body, preview );
+ else
+ stat = gme_ptr->tweak_offset( surface_list, offset_distance, NULL, NULL,
+ new_bodysm_list, keep_old_body, preview );
+ if( CubitUndo::get_undo_enabled() )
+ if( stat == CUBIT_FAILURE)
+ CubitUndo::remove_last_undo();
+
+ if( stat == CUBIT_FAILURE )
+ {
+ if(!preview)
+ {
+ remove_pushed_attributes(new_bodysm_list, old_body_list);
+ do_attribute_cleanup();
+ }
+ return stat;
+ }
+ else
+ {
+ if(!preview)
+ {
+ restore_vg_after_modify(new_bodysm_list, old_body_list, gme_ptr);
+ remove_pushed_attributes(new_bodysm_list, old_body_list);
+ }
+ }
+
+ // Collect all of the old faces to be compared later with the new faces...DJQ
+ DLIList<RefFace*> old_faces;
+ for (i = 0; i < old_body_list.size(); i++)
+ {
+ Body *old_body = old_body_list.get_and_step();
+ DLIList<RefFace*> tmp_faces;
+ old_body->ref_faces(tmp_faces);
+ old_faces +=tmp_faces;
+ }
+
+ if( preview == CUBIT_FALSE )
+ {
+ // Update DAG
+ stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list );
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( stat == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+ else if( keep_old_body )
+ CubitUndo::note_result_bodies( new_body_list );
+ }
+ do_attribute_cleanup();
+ }
+
+ //collect all the new faces
+ DLIList<RefFace*> new_faces;
+ for( i=new_body_list.size(); i--; )
+ {
+ Body *new_body = new_body_list.get_and_step();
+ DLIList<RefFace*> tmp_faces;
+ new_body->ref_faces( tmp_faces );
+ new_faces += tmp_faces;
+ }
+
+ // Compare the new_faces list with the old_faces list to determine which faces are created
+ // Add these faces to the all_ref_face_list to check for its neighbors...DJQ
+ DLIList<RefFace*> difference = new_faces;
+ difference -= old_faces;
+ all_ref_face_list += difference;
+
// loop body sm list and find surfaces that need updating.
- // this is to account for some cases where the topology doesn't change, but the geometry does.
+ // this is to account for some cases where the topology
+ //doesn't change, but the geometry does.
+
DLIList<RefEntity*> entities_to_update;
- int i;
for(i=0; i<new_bodysm_list.size(); i++)
{
BodySM* bodysm = new_bodysm_list.get_and_step();
@@ -7924,7 +13705,7 @@
if(man)
{
RefFace* ref_face = CAST_TO(man->topology_entity(), RefFace);
- if(ref_face && ref_face_list.is_in_list(ref_face))
+ if(ref_face && all_ref_face_list.is_in_list(ref_face))
{
// get neighbors
DLIList<Point*> neighbor_points;
@@ -7959,15 +13740,87 @@
}
}
- // Update DAG
- if (!finish_sm_op( old_body_list, new_bodysm_list, new_body_list ))
- return CUBIT_FAILURE;
+ //unmerge any merged adjacent surfaces or
+ //merged curves in unmerged adjacent surfaces
+ DLIList<RefFace*> adjacent_faces_to_unmerge;
+ DLIList<RefEdge*> adjacent_edges_to_unmerge;
+ for(i=ref_face_list.size(); i--;)
+ {
+ RefFace *tweaked_face = ref_face_list.get_and_step();
+ if( !new_faces.move_to( tweaked_face ) )
+ continue;
+
+ //get all the edges of the face you tweaked
+ DLIList<RefEdge*> tweaked_face_edges;
+ tweaked_face->ref_edges( tweaked_face_edges );
+ adjacent_edges_to_unmerge += tweaked_face_edges;
+
+ //get all the adjacent faces to this edge
+ int j;
+ for( j=tweaked_face_edges.size(); j--; )
+ {
+ RefEdge *tmp_edge = tweaked_face_edges.get_and_step();
+ DLIList<RefFace*> tmp_faces;
+ tmp_edge->ref_faces( tmp_faces );
+ tmp_faces.remove( tweaked_face );
+ adjacent_faces_to_unmerge += tmp_faces;
+ }
+
+ //get all edges not in the surface,
+ //sharing vertices with the surface
+ DLIList<RefVertex*> ref_vertices;
+ tweaked_face->ref_vertices( ref_vertices );
+ for( j=ref_vertices.size(); j--; )
+ {
+ RefVertex *tmp_vert = ref_vertices.get_and_step();
+ DLIList<RefEdge*> ref_edges;
+ tmp_vert->ref_edges( ref_edges );
+
+ int k;
+ for( k=ref_edges.size(); k--; )
+ {
+ RefEdge *tmp_edge = ref_edges.get_and_step();
+ if( !tweaked_face_edges.move_to( tmp_edge ) )
+ adjacent_edges_to_unmerge.append( tmp_edge );
+ }
+ }
+ }
+
+ //unmerge any adjacent faces
+ adjacent_faces_to_unmerge.uniquify_unordered();
+ for( i=adjacent_faces_to_unmerge.size(); i--; )
+ {
+ RefFace *ref_face = adjacent_faces_to_unmerge.get_and_step();
+
+ DLIList<TopologyBridge*> bridge_list;
+ ref_face->bridge_manager()->get_bridge_list(bridge_list);
+ if (bridge_list.size() > 1)
+ {
+ if( MergeTool::instance()->unmerge( ref_face ) )
+ PRINT_WARNING("Unmerging Surface %d\n", ref_face->id() );
+ }
+ }
+
+ //unmerge any adjacent edges
+ adjacent_edges_to_unmerge.uniquify_unordered();
+ for( i=adjacent_edges_to_unmerge.size(); i--; )
+ {
+ RefEdge *ref_edge = adjacent_edges_to_unmerge.get_and_step();
+ DLIList<TopologyBridge*> bridge_list;
+ ref_edge->bridge_manager()->get_bridge_list(bridge_list);
+ if (bridge_list.size() > 1)
+ {
+ if( MergeTool::instance()->unmerge( ref_edge) )
+ PRINT_WARNING("Unmerging Curve %d\n", ref_edge->id() );
+ }
+ }
+
// Update graphics
while (entities_to_update.size())
entities_to_update.pop()->notify_all_observers( GEOMETRY_MODIFIED );
- return CUBIT_SUCCESS;
+ return stat;
}
//=============================================================================
@@ -7976,12 +13829,19 @@
// Author : Steve Storm
// Date : 03/25/05
//=============================================================================
-CubitStatus GeometryModifyTool::tweak_offset( DLIList<RefEdge*>& ref_edge_list,
+CubitStatus GeometryModifyTool::tweak_offset( DLIList<RefEdge*> &ref_edge_list,
double offset_distance,
- DLIList<Body*>& new_body_list,
+ DLIList<RefEdge*> *add_ref_edge_list_ptr,
+ DLIList<double> *add_offset_list_ptr,
+ DLIList<Body*> &new_body_list,
CubitBoolean keep_old_body,
CubitBoolean preview )
{
+ DLIList<RefEdge*> all_ref_edge_list(ref_edge_list.size());
+ all_ref_edge_list = ref_edge_list;
+ if( add_ref_edge_list_ptr )
+ all_ref_edge_list += *add_ref_edge_list_ptr;
+
DLIList<Curve*> curve_list(ref_edge_list.size());
DLIList<Body*> old_body_list;
GeometryModifyEngine* gme_ptr;
@@ -7990,119 +13850,250 @@
if (!gme_ptr)
return CUBIT_FAILURE;
+ DLIList<Curve*> add_curve_list;
+ if( add_ref_edge_list_ptr && add_ref_edge_list_ptr->size() )
+ {
+ DLIList<Body*> old_body_list2;
+ GeometryModifyEngine* gme_ptr2 = tweak_setup( *add_ref_edge_list_ptr, "Offsetting",
+ old_body_list2, add_curve_list );
+ if (!gme_ptr2)
+ return CUBIT_FAILURE;
+ if( gme_ptr != gme_ptr2 )
+ {
+ PRINT_ERROR("Offsetting curves on entities containing surfaces from different\n"
+ " geometry engines is not allowed.\n");
+ return CUBIT_FAILURE;
+ }
+ old_body_list.merge_unique( old_body_list2 );
+ }
+
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ if( keep_old_body )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( all_ref_edge_list );
+ }
+
// Do offset
DLIList<BodySM*> new_bodysm_list;
- if( gme_ptr->tweak_offset( curve_list, offset_distance, new_bodysm_list,
- keep_old_body, preview ) == CUBIT_FAILURE )
+ CubitStatus stat;
+ if( add_curve_list.size() )
+ stat = gme_ptr->tweak_offset( curve_list, offset_distance, &add_curve_list,
+ add_offset_list_ptr, new_bodysm_list, keep_old_body, preview );
+ else
+ stat = gme_ptr->tweak_offset( curve_list, offset_distance, NULL, NULL,
+ new_bodysm_list, keep_old_body, preview );
+
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ if( stat == CUBIT_FAILURE)
+ CubitUndo::remove_last_undo();
+
+ if( stat == CUBIT_FAILURE )
return CUBIT_FAILURE;
// Update DAG
- if (!finish_sm_op( old_body_list, new_bodysm_list, new_body_list ))
- return CUBIT_FAILURE;
+ if( preview == CUBIT_FALSE )
+ {
+ stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list );
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( stat == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+ else if( keep_old_body )
+ CubitUndo::note_result_bodies( new_body_list );
+ }
+ }
+
// Update graphics
DLIList<Body*> moved_bodies(new_body_list);
moved_bodies.intersect(old_body_list);
while (moved_bodies.size())
moved_bodies.pop()->notify_sub_all_observers( GEOMETRY_MODIFIED );
- return CUBIT_SUCCESS;
+ return stat;
}
-//=============================================================================
-// 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/25/05
-//=============================================================================
-CubitStatus GeometryModifyTool::tweak_remove( DLIList<RefFace*> &ref_face_list,
+
+CubitStatus GeometryModifyTool::tweak_remove_individually(
+ DLIList<RefFace*> &ref_face_list,
DLIList<Body*> &new_body_list,
- CubitBoolean extend_adjoining,
CubitBoolean keep_surface,
CubitBoolean keep_old_body,
- CubitBoolean individual,
CubitBoolean preview )
{
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ if( keep_old_body )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( ref_face_list );
+ }
+
// Split things up if individual
- if (individual && extend_adjoining )
+ //build a surfae to volume map
+ std::map<RefFace*, RefVolume*> surface_to_volume_map;
+
+ int i;
+ for (i = ref_face_list.size(); i--; )
{
- //build a surfae to volume map
- std::map<RefFace*, RefVolume*> surface_to_volume_map;
+ RefFace *tmp_face = ref_face_list.get_and_step();
+ RefVolume *tmp_vol = tmp_face->ref_volume();
+ surface_to_volume_map.insert( std::map<RefFace*, RefVolume*>::value_type( tmp_face, tmp_vol));
+ }
- int i;
- for (i = ref_face_list.size(); i--; )
- {
- RefFace *tmp_face = ref_face_list.get_and_step();
- RefVolume *tmp_vol = tmp_face->ref_volume();
- surface_to_volume_map.insert( std::map<RefFace*, RefVolume*>::value_type( tmp_face, tmp_vol));
- }
+ DLIList<RefFace*> one_ref_face;
+ DLIList<Body*> tmp_new_body_list;
+ CubitStatus total_rv = CUBIT_FAILURE;
+ bool extend = true;
- DLIList<RefFace*> one_ref_face;
- CubitStatus total_rv = CUBIT_FAILURE;
+ // Succeed if any one surface succeeds.
+ for (i = ref_face_list.size(); i--; )
+ {
+ //make sure that the surface to remove is still in the body...
+ //that it hasn't been removed from a previous tweak operation
+ RefFace *tmp_face = ref_face_list.get_and_step();
+ std::map<RefFace*, RefVolume*>::iterator tmp_iter;
+ tmp_iter = surface_to_volume_map.find( tmp_face );
+ RefVolume *tmp_vol = tmp_iter->second;
+ DLIList<RefFace*> ref_face_list;
+ tmp_vol->ref_faces( ref_face_list );
+ if( !ref_face_list.move_to( tmp_face ) )
+ continue;
- // Succeed if any one surface succeeds.
- for (i = ref_face_list.size(); i--; )
+ one_ref_face.clean_out();
+ one_ref_face.append( tmp_face );
+ int id = one_ref_face.get()->id();
+
+ //See if the owning body of the face is a multi-volume body
+ Body *owning_body = one_ref_face.get()->body();
+ int number_volumes_before = owning_body->num_ref_volumes();
+
+ tmp_new_body_list.clean_out();
+
+ CubitStatus rv = this->tweak_remove(one_ref_face, tmp_new_body_list,
+ extend, keep_surface, keep_old_body, preview );
+ if (rv)
{
- //make sure that the surface to remove is still in the body...
- //that it hasn't been removed from a previous tweak operation
- RefFace *tmp_face = ref_face_list.get_and_step();
- std::map<RefFace*, RefVolume*>::iterator tmp_iter;
- tmp_iter = surface_to_volume_map.find( tmp_face );
- RefVolume *tmp_vol = tmp_iter->second;
- DLIList<RefFace*> ref_face_list;
- tmp_vol->ref_faces( ref_face_list );
- if( !ref_face_list.move_to( tmp_face ) )
- continue;
+ total_rv = CUBIT_SUCCESS;
+ if( !preview )
+ PRINT_INFO("Successfully removed Surface %d\n\n", id);
+ else
+ PRINT_INFO("Successfully removed Surface %d in preview\n\n", id);
- one_ref_face.clean_out();
- one_ref_face.append( tmp_face );
- int id = one_ref_face.get()->id();
- CubitStatus rv = this->tweak_remove(one_ref_face, new_body_list,
- extend_adjoining, keep_surface, keep_old_body, false, preview );
- if (rv)
+ //see if we have a multi-volume body or multiple bodies
+ //if so, we know the original volume was destroyed, so we
+ //cannot remove any more surfaces because the check above is
+ //highly likely to crash
+ bool volume_destroyed = false;
+ int number_volumes_after = tmp_new_body_list.get()->num_ref_volumes();
+ if( number_volumes_after > number_volumes_before )
+ volume_destroyed = true;
+
+ new_body_list += tmp_new_body_list;
+
+ if( volume_destroyed == true )
{
- new_body_list.uniquify_unordered();
- total_rv = CUBIT_SUCCESS;
- if( !preview )
- PRINT_INFO("Successfully removed Surface %d\n\n", id);
- else
- PRINT_INFO("Successfully removed Surface %d in preview\n\n", id);
-
- //see if we have a multi-volume body or multiple bodies
- //if so, we know the original volume was destroyed, so we
- //cannot remove any more surfaces because the check above is
- //highly likely to crash
- bool volume_destroyed = false;
- if( new_body_list.size() > 1 )
- volume_destroyed = true;
- else if( new_body_list.size() )
+ PRINT_WARNING("Unable to remove more surfaces because multiple bodies\n"
+ " have been produced from removing surfaces individually\n" );
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
{
- if( new_body_list.get()->num_ref_volumes() > 1 )
- volume_destroyed = true;
+ if( total_rv == CUBIT_FAILURE ) //didn't remove any surfaces
+ CubitUndo::remove_last_undo();
+ else
+ CubitUndo::note_result_bodies( new_body_list );
}
- if( volume_destroyed == true && i )
- {
- PRINT_WARNING("Unable to remove more surfaces because multiple bodies\n"
- " have been produced from removing surfaces individually\n" );
- return total_rv;
- }
+ return total_rv;
}
+ }
+ else
+ {
+ if( !preview )
+ PRINT_INFO("Unable to remove Surface %d\n\n", id);
else
- {
- if( !preview )
- PRINT_INFO("Unable to remove Surface %d\n\n", id);
- else
- PRINT_INFO("Unable to remove Surface %d in preview\n\n", id);
- }
+ PRINT_INFO("Unable to remove Surface %d in preview\n\n", id);
}
- return total_rv;
}
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ if( total_rv == CUBIT_FAILURE)
+ CubitUndo::remove_last_undo();
+ else if( keep_old_body || keep_surface )
+ CubitUndo::note_result_bodies( new_body_list );
+ }
+
+ return total_rv;
+}
+
+
+//=============================================================================
+// 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/25/05
+//=============================================================================
+CubitStatus GeometryModifyTool::tweak_remove_together(
+ DLIList<RefFace*> &ref_face_list,
+ DLIList<Body*> &new_body_list,
+ CubitBoolean extend_adjoining,
+ CubitBoolean keep_surface,
+ CubitBoolean keep_old_body,
+ CubitBoolean preview )
+{
+
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ if( keep_old_body )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( ref_face_list );
+ }
+
+ CubitStatus stat = tweak_remove( ref_face_list, new_body_list,
+ extend_adjoining, keep_surface,
+ keep_old_body, preview );
+
+ if( stat == CUBIT_FAILURE )
+ {
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ CubitUndo::remove_last_undo();
+
+ return CUBIT_FAILURE;
+ }
+
+
+ if( preview == CUBIT_FALSE )
+ {
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( stat == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+ else if( keep_old_body || keep_surface )
+ CubitUndo::note_result_bodies( new_body_list );
+ }
+ }
+
+ return CUBIT_SUCCESS;
+}
+
+//private funcion...should not be called from outside this class
+CubitStatus GeometryModifyTool::tweak_remove( DLIList<RefFace*> &ref_face_list,
+ DLIList<Body*> &new_body_list,
+ CubitBoolean extend_adjoining,
+ CubitBoolean keep_surface,
+ CubitBoolean keep_old_body,
+ CubitBoolean preview )
+{
DLIList<Surface*> surface_list(ref_face_list.size());
DLIList<Body*> old_body_list;
GeometryModifyEngine* gme_ptr;
+ // clear any preview previews
+ GfxPreview::clear();
+
//collect all neighboring surfaces to those in the list
int i,j;
DLIList<RefFace*> neighboring_surfaces;
@@ -8119,15 +14110,70 @@
neighboring_surfaces.uniquify_unordered();
neighboring_surfaces += ref_face_list;
- gme_ptr = tweak_setup( ref_face_list, "Removing", old_body_list, surface_list );
+ gme_ptr = tweak_setup( ref_face_list, "Removing", old_body_list, surface_list, CUBIT_TRUE );
if (!gme_ptr)
return CUBIT_FAILURE;
+ DLIList<Surface*> kept_surface_list;
+ if( keep_surface )
+ {
+ int kk;
+ for( kk=surface_list.size(); kk--; )
+ {
+ Surface *new_surf = gme_ptr->make_Surface( surface_list.get_and_step() );
+ kept_surface_list.append( new_surf );
+ }
+ }
+
+ DLIList<BodySM*> body_sms;
+ for(i=old_body_list.size(); i--;)
+ {
+ BodySM* bsm = old_body_list.get_and_step()->get_body_sm_ptr();
+ if(bsm)
+ body_sms.append_unique(bsm);
+ }
+
+ if(!preview)
+ {
+ do_attribute_setup();
+ push_vg_attributes_before_modify(body_sms);
+ }
+
// Do remove
DLIList<BodySM*> new_bodysm_list;
- if( gme_ptr->tweak_remove( surface_list, new_bodysm_list, extend_adjoining,
- keep_surface, keep_old_body, preview ) == CUBIT_FAILURE )
+ CubitStatus removal_status =
+ gme_ptr->tweak_remove( surface_list,
+ new_bodysm_list,
+ extend_adjoining,
+ keep_old_body,
+ preview );
+
+
+ if( removal_status == CUBIT_FAILURE )
+ {
+ if(!preview)
+ remove_pushed_attributes(new_bodysm_list, old_body_list);
+ if( keep_surface )
+ {
+ int kk;
+ for( kk=kept_surface_list.size(); kk--; )
+ {
+ Surface *surf = kept_surface_list.get_and_step();
+ gme_ptr->get_gqe()->delete_solid_model_entities( surf );
+ }
+ }
+ if(!preview)
+ do_attribute_cleanup();
return CUBIT_FAILURE;
+ }
+ else
+ {
+ if(!preview)
+ {
+ restore_vg_after_modify(new_bodysm_list, old_body_list, gme_ptr);
+ remove_pushed_attributes(new_bodysm_list, old_body_list);
+ }
+ }
// loop body sm list and find surfaces that need updating.
// this is to account for some cases where the topology doesn't change, but the geometry does.
@@ -8188,17 +14234,38 @@
}
- // Update DAG
- if (!finish_sm_op( old_body_list, new_bodysm_list, new_body_list ))
- return CUBIT_FAILURE;
+ DLIList<Body*> kept_surface_bodies;
+ if( preview == CUBIT_FALSE && keep_surface )
+ {
+ int kk;
+ for( kk=kept_surface_list.size(); kk--; )
+ {
+ Surface *surf = kept_surface_list.get_and_step();
+ Body *new_body = make_Body( surf );
+ kept_surface_bodies.append( new_body );
+ }
+ }
- // Update graphics
+ // Update DAG
+ CubitStatus stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list );
+
+ if(!preview)
+ do_attribute_cleanup();
+
+ if( keep_surface )
+ new_body_list += kept_surface_bodies;
+
+ if( stat == CUBIT_FAILURE)
+ return CUBIT_FAILURE;
+
+ // Update graphics
while (entities_to_update.size())
entities_to_update.pop()->notify_all_observers( GEOMETRY_MODIFIED );
- return CUBIT_SUCCESS;
+ return CUBIT_SUCCESS;
}
+
//=============================================================================
// Description: Function to remove curves from a sheet body and then extend the
// remaining curves or fill the gap or hole.
@@ -8214,23 +14281,128 @@
DLIList<Body*> old_body_list;
GeometryModifyEngine* gme_ptr;
+ // clear any preview previews
+ GfxPreview::clear();
+
gme_ptr = tweak_setup( ref_edge_list, "Removing", old_body_list, curve_list );
if( !gme_ptr )
return CUBIT_FAILURE;
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ if( keep_old_body )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( ref_edge_list );
+ }
+
// Do remove
DLIList<BodySM*> new_bodysm_list;
- if( gme_ptr->tweak_remove( curve_list, new_bodysm_list, keep_old_body, preview )
- == CUBIT_FAILURE )
- return CUBIT_FAILURE;
+ CubitStatus stat = gme_ptr->tweak_remove( curve_list, new_bodysm_list,
+ keep_old_body, preview );
+ //collect all neighboring curves to those in the list
+ int i, j;
+ DLIList<RefEdge*> neighboring_curves;
+ for( i=ref_edge_list.size(); i--; )
+ {
+ RefEdge *tmp_edge = ref_edge_list.get_and_step();
+ DLIList<RefVertex*> tmp_ref_vertex_list;
+ tmp_edge->ref_vertices( tmp_ref_vertex_list );
+ for( j=tmp_ref_vertex_list.size(); j--; )
+ tmp_ref_vertex_list.get_and_step()->ref_edges( neighboring_curves );
+ }
- // Update DAG
- if (!finish_sm_op( old_body_list, new_bodysm_list, new_body_list ))
- return CUBIT_FAILURE;
+ //uniquify and add other curves
+ neighboring_curves.uniquify_unordered();
+ //neighboring_curves += ref_edge_list;
- return CUBIT_SUCCESS;
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ if( stat == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+
+ if( stat == CUBIT_FAILURE)
+ return stat;
+
+ // loop body sm list and find curves that need updating.
+ // this is to account for some cases where the topology doesn't change, but the geometry does.
+ DLIList<RefEntity*> entities_to_update;
+ for(i=0; i<new_bodysm_list.size(); i++)
+ {
+ BodySM* bodysm = new_bodysm_list.get_and_step();
+ DLIList<Curve*> curves;
+ bodysm->curves(curves);
+ int j;
+ // find a surface that is also found in our input list
+ for(j=0; j<curves.size(); j++, curves.step())
+ {
+ BridgeManager* man = curves.get()->bridge_manager();
+ if(man)
+ {
+ RefEdge* ref_edge = CAST_TO(man->topology_entity(), RefEdge);
+ if( ref_edge && neighboring_curves.is_in_list(ref_edge) )
+ {
+ // get neighbors
+ DLIList<Point*> neighbor_points;
+ curves.get()->points(neighbor_points);
+ DLIList<Curve*> neighbor_curves;
+ DLIList<Surface*> neighbor_surfaces;
+ DLIList<TopologyBridge*> neighbors;
+ DLIList<TopologyBridge*> tmp;
+ int k;
+ for(k=0; k<neighbor_points.size(); k++)
+ neighbor_points.get_and_step()->surfaces(neighbor_surfaces);
+ for(k=0; k<neighbor_points.size(); k++)
+ neighbor_points.get_and_step()->curves(neighbor_curves);
+
+ CAST_LIST_TO_PARENT(neighbor_points, tmp);
+ neighbors += tmp;
+ neighbor_curves.uniquify_unordered();
+ CAST_LIST_TO_PARENT(neighbor_curves, tmp);
+ neighbors += tmp;
+ neighbor_surfaces.uniquify_unordered();
+ CAST_LIST_TO_PARENT(neighbor_surfaces, tmp);
+ neighbors += tmp;
+ //neighbors.append(curves.get()->lump());
+ //neighbors.append(curves.get()->bodysm());
+
+ for(k=0; k<neighbors.size(); k++)
+ {
+ if(BridgeManager* m = neighbors.get_and_step()->bridge_manager())
+ {
+ if(TopologyEntity* t = m->topology_entity())
+ {
+ entities_to_update.append(CAST_TO(t, RefEntity));
+ RefEntity *ref_ent = CAST_TO(t, RefEntity );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if(preview == CUBIT_FALSE )
+ {
+ // Update DAG
+ stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list );
+
+ // Update graphics
+ while (entities_to_update.size())
+ entities_to_update.pop()->notify_all_observers( GEOMETRY_MODIFIED );
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( stat == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+ else if( keep_old_body )
+ CubitUndo::note_result_bodies( new_body_list );
+ }
+ }
+
+ return stat;
}
+
//=============================================================================
// Description: Tweak specified faces of a volume or volumes up to a target
// surface or set of connected target surfaces.
@@ -8240,6 +14412,8 @@
CubitStatus GeometryModifyTool::tweak_target( DLIList<RefFace*> &ref_face_list,
DLIList<RefFace*> &target_face_list,
DLIList<Body*> &new_body_list,
+ CubitBoolean extend_flg,
+ CubitPlane *limit_plane,
CubitBoolean reverse_flg,
CubitBoolean keep_old_body,
CubitBoolean preview )
@@ -8249,12 +14423,12 @@
DLIList<Body*> old_body_list;
GeometryModifyEngine *gme_ptr1, *gme_ptr2;
- gme_ptr1 = tweak_setup( ref_face_list, "Tweaking", old_body_list, surface_list );
+ gme_ptr1 = tweak_setup( ref_face_list, "Tweaking", old_body_list, surface_list, CUBIT_TRUE );
if (!gme_ptr1)
return CUBIT_FAILURE;
DLIList<Body*> old_body_list2;
- gme_ptr2 = tweak_setup( target_face_list, "Tweaking", old_body_list2, target_surf_list );
+ gme_ptr2 = tweak_setup( target_face_list, "Tweaking", old_body_list2, target_surf_list, CUBIT_TRUE );
if (!gme_ptr2)
return CUBIT_FAILURE;
@@ -8264,16 +14438,101 @@
return CUBIT_FAILURE;
}
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ if( keep_old_body )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( ref_face_list );
+ }
+
+ int i;
+ DLIList<Body*> all_bodies = old_body_list;
+ all_bodies += old_body_list2;
+ DLIList<BodySM*> body_sms;
+ for(i=all_bodies.size(); i--;)
+ {
+ BodySM* bsm = all_bodies.get_and_step()->get_body_sm_ptr();
+ if(bsm)
+ body_sms.append_unique(bsm);
+ }
+
+ if(!preview)
+ {
+ do_attribute_setup();
+ push_vg_attributes_before_modify(body_sms);
+ }
+
// Do tweak to target
DLIList<BodySM*> new_bodysm_list;
- if( gme_ptr1->tweak_target( surface_list, target_surf_list, new_bodysm_list,
- reverse_flg, keep_old_body, preview ) == CUBIT_FAILURE )
+ CubitStatus stat = gme_ptr1->tweak_target( surface_list, target_surf_list,
+ new_bodysm_list, extend_flg,
+ limit_plane, reverse_flg,
+ keep_old_body, preview );
+
+
+ if( stat == CUBIT_FAILURE )
+ {
+ if(!preview)
+ remove_pushed_attributes(new_bodysm_list, all_bodies);
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ CubitUndo::remove_last_undo();
+ if(!preview)
+ do_attribute_cleanup();
return CUBIT_FAILURE;
+ }
+ else
+ {
+ if(!preview)
+ {
+ restore_vg_after_modify(new_bodysm_list, all_bodies, gme_ptr1);
+ remove_pushed_attributes(new_bodysm_list, all_bodies);
+ }
+ }
+ // Collect all the old_faces to be compared against new_faces later...DJQ
+ DLIList<RefFace*> old_faces;
+ for (i = 0; i < old_body_list.size(); i++)
+ {
+ Body *old_body = old_body_list.get_and_step();
+ DLIList<RefFace*> tmp_faces;
+ old_body->ref_faces(tmp_faces);
+ old_faces +=tmp_faces;
+ }
+
+ // Update DAG
+ stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list );
+
+ if(!preview)
+ do_attribute_cleanup();
+
+ if( stat == CUBIT_FAILURE )
+ {
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ CubitUndo::remove_last_undo();
+ return CUBIT_FAILURE;
+ }
+
+ //collect all the new faces
+ DLIList<RefFace*> new_faces;
+ for( i=new_body_list.size(); i--; )
+ {
+ Body *new_body = new_body_list.get_and_step();
+ DLIList<RefFace*> tmp_faces;
+ new_body->ref_faces( tmp_faces );
+ new_faces += tmp_faces;
+ }
+
+ // Compare the new_faces list with the old_faces list to determine which faces are created
+ // Add these faces to the all_ref_face_list to check for its neighbors...DJQ
+ DLIList<RefFace*> difference = new_faces;
+ difference -= old_faces;
+ ref_face_list += difference;
+
+
// loop body sm list and find surfaces that need updating.
// this is to account for some cases where the topology doesn't change, but the geometry does.
DLIList<RefEntity*> entities_to_update;
- int i;
for(i=0; i<new_bodysm_list.size(); i++)
{
BodySM* bodysm = new_bodysm_list.get_and_step();
@@ -8304,6 +14563,11 @@
for(k=0; k<neighbor_points.size(); k++)
neighbor_points.get_and_step()->curves(neighbor_curves);
+ for (int i = 0; i < neighbor_points.size(); i++)
+ {
+ int id = neighbor_points.get_and_step()->get_saved_id();
+ int temp = id;
+ }
CAST_LIST_TO_PARENT(neighbor_points, tmp);
neighbors += tmp;
neighbor_curves.uniquify_unordered();
@@ -8324,14 +14588,89 @@
}
}
- // Update DAG
- if (!finish_sm_op( old_body_list, new_bodysm_list, new_body_list ))
- return CUBIT_FAILURE;
+ //unmerge any merged adjacent surfaces or
+ //merged curves in unmerged adjacent surfaces
+ DLIList<RefFace*> adjacent_faces_to_unmerge;
+ DLIList<RefEdge*> adjacent_edges_to_unmerge;
+ for(i=ref_face_list.size(); i--;)
+ {
+ RefFace *tweaked_face = ref_face_list.get_and_step();
+ if( !new_faces.move_to( tweaked_face ) )
+ continue;
+ //get all the edges of the face you tweaked
+ DLIList<RefEdge*> tweaked_face_edges;
+ tweaked_face->ref_edges( tweaked_face_edges );
+ adjacent_edges_to_unmerge += tweaked_face_edges;
+
+ //get all the adjacent faces to this edge
+ int j;
+ for( j=tweaked_face_edges.size(); j--; )
+ {
+ RefEdge *tmp_edge = tweaked_face_edges.get_and_step();
+ DLIList<RefFace*> tmp_faces;
+ tmp_edge->ref_faces( tmp_faces );
+ tmp_faces.remove( tweaked_face );
+ adjacent_faces_to_unmerge += tmp_faces;
+ }
+
+ //get all edges not in the surface,
+ //sharing vertices with the surface
+ DLIList<RefVertex*> ref_vertices;
+ tweaked_face->ref_vertices( ref_vertices );
+ for( j=ref_vertices.size(); j--; )
+ {
+ RefVertex *tmp_vert = ref_vertices.get_and_step();
+ DLIList<RefEdge*> ref_edges;
+ tmp_vert->ref_edges( ref_edges );
+
+ int k;
+ for( k=ref_edges.size(); k--; )
+ {
+ RefEdge *tmp_edge = ref_edges.get_and_step();
+ if( !tweaked_face_edges.move_to( tmp_edge ) )
+ adjacent_edges_to_unmerge.append( tmp_edge );
+ }
+ }
+ }
+
+ //unmerge any adjacent faces
+ adjacent_faces_to_unmerge.uniquify_unordered();
+ for( i=adjacent_faces_to_unmerge.size(); i--; )
+ {
+ RefFace *ref_face = adjacent_faces_to_unmerge.get_and_step();
+
+ DLIList<TopologyBridge*> bridge_list;
+ ref_face->bridge_manager()->get_bridge_list(bridge_list);
+ if (bridge_list.size() > 1)
+ {
+ if( MergeTool::instance()->unmerge( ref_face ) )
+ PRINT_WARNING("Unmerging Surface %d\n", ref_face->id() );
+ }
+ }
+
+ //unmerge any adjacent edges
+ adjacent_edges_to_unmerge.uniquify_unordered();
+ for( i=adjacent_edges_to_unmerge.size(); i--; )
+ {
+ RefEdge *ref_edge = adjacent_edges_to_unmerge.get_and_step();
+ DLIList<TopologyBridge*> bridge_list;
+ ref_edge->bridge_manager()->get_bridge_list(bridge_list);
+ if (bridge_list.size() > 1)
+ {
+ if( MergeTool::instance()->unmerge( ref_edge) )
+ PRINT_WARNING("Unmerging Curve %d\n", ref_edge->id() );
+ }
+ }
+
+ if( CubitUndo::get_undo_enabled() && keep_old_body )
+ CubitUndo::note_result_bodies( new_body_list );
+
// Update graphics
while (entities_to_update.size())
entities_to_update.pop()->notify_all_observers( GEOMETRY_MODIFIED );
+
return CUBIT_SUCCESS;
}
@@ -8352,7 +14691,7 @@
DLIList<Body*> old_body_list;
GeometryModifyEngine* gme_ptr;
- gme_ptr = tweak_setup( ref_face_list, "Tweaking", old_body_list, surface_list );
+ gme_ptr = tweak_setup( ref_face_list, "Tweaking", old_body_list, surface_list, CUBIT_TRUE );
if (!gme_ptr)
return CUBIT_FAILURE;
@@ -8385,18 +14724,63 @@
return CUBIT_FAILURE;
}
+ int i;
+ DLIList<BodySM*> body_sms;
+ for(i=old_body_list.size(); i--;)
+ {
+ BodySM* bsm = old_body_list.get_and_step()->get_body_sm_ptr();
+ if(bsm)
+ body_sms.append_unique(bsm);
+ }
+
+ if(!preview)
+ {
+ do_attribute_setup();
+ push_vg_attributes_before_modify(body_sms);
+ }
+
// Do tweak to target
DLIList<BodySM*> new_bodysm_list;
- if( gme_ptr->tweak_target( surface_list, target_surf_list, new_bodysm_list,
- reverse_flg, keep_old_body, preview ) == CUBIT_FAILURE )
+ CubitStatus stat = gme_ptr->tweak_target( surface_list, target_surf_list,
+ new_bodysm_list, CUBIT_TRUE,
+ NULL, reverse_flg, keep_old_body,
+ preview );
+
+
+ if( stat == CUBIT_FAILURE )
+ {
+ if(!preview)
+ remove_pushed_attributes(new_bodysm_list, old_body_list);
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ CubitUndo::remove_last_undo();
+ if(!preview)
+ do_attribute_cleanup();
return CUBIT_FAILURE;
+ }
+ else
+ {
+ if(!preview)
+ {
+ restore_vg_after_modify(new_bodysm_list, old_body_list, gme_ptr);
+ remove_pushed_attributes(new_bodysm_list, old_body_list);
+ }
+ }
// Delete temporary sheet body
bodysm_ptr->get_geometry_query_engine()->delete_solid_model_entities( bodysm_ptr );
// Update DAG
- if (!finish_sm_op( old_body_list, new_bodysm_list, new_body_list ))
+ stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list );
+
+ if(!preview)
+ do_attribute_cleanup();
+
+ if( stat == CUBIT_FAILURE )
+ {
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ CubitUndo::remove_last_undo();
return CUBIT_FAILURE;
+ }
// Update graphics
DLIList<Body*> moved_bodies(new_body_list);
@@ -8416,9 +14800,12 @@
CubitStatus GeometryModifyTool::tweak_target( DLIList<RefEdge*> &ref_edge_list,
DLIList<RefFace*> &target_face_list,
DLIList<Body*> &new_body_list,
+ CubitBoolean extend_flg,
+ CubitPlane *limit_plane,
CubitBoolean reverse_flg,
CubitBoolean keep_old,
- CubitBoolean preview )
+ CubitBoolean preview,
+ double max_area_increase /*= 0%*/ )
{
DLIList<Curve*> curve_list(ref_edge_list.size());
DLIList<Surface*> target_surf_list(target_face_list.size());
@@ -8440,16 +14827,45 @@
return CUBIT_FAILURE;
}
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ if( keep_old )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( ref_edge_list );
+ }
+
// Do tweak to target
DLIList<BodySM*> new_bodysm_list;
- if( gme_ptr1->tweak_target( curve_list, target_surf_list, new_bodysm_list,
- reverse_flg, keep_old, preview ) == CUBIT_FAILURE )
+ CubitStatus stat = gme_ptr1->tweak_target( curve_list, target_surf_list,
+ new_bodysm_list, extend_flg,
+ limit_plane, reverse_flg,
+ keep_old, preview, max_area_increase );
+
+ if( stat == CUBIT_FAILURE )
+ {
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ CubitUndo::remove_last_undo();
return CUBIT_FAILURE;
+ }
// Update DAG
- if (!finish_sm_op( old_body_list, new_bodysm_list, new_body_list ))
+ stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list );
+
+
+ if( stat == CUBIT_FAILURE )
+ {
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ CubitUndo::remove_last_undo();
return CUBIT_FAILURE;
+ }
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ if( keep_old )
+ CubitUndo::note_result_bodies( new_body_list );
+ }
+
// Update graphics
DLIList<Body*> moved_bodies(new_body_list);
moved_bodies.intersect(old_body_list);
@@ -8509,19 +14925,44 @@
return CUBIT_FAILURE;
}
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ if( keep_old )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( ref_edge_list );
+ }
+
// Do tweak to target
DLIList<BodySM*> new_bodysm_list;
- if( gme_ptr->tweak_target( curve_list, target_surf_list, new_bodysm_list,
- reverse_flg, keep_old, preview ) == CUBIT_FAILURE )
+ CubitStatus stat = gme_ptr->tweak_target( curve_list, target_surf_list,
+ new_bodysm_list, CUBIT_TRUE,
+ NULL, reverse_flg, keep_old,
+ preview );
+
+ if( stat == CUBIT_FAILURE )
+ {
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ CubitUndo::remove_last_undo();
return CUBIT_FAILURE;
+ }
// Delete temporary sheet body
bodysm_ptr->get_geometry_query_engine()->delete_solid_model_entities( bodysm_ptr );
// Update DAG
- if (!finish_sm_op( old_body_list, new_bodysm_list, new_body_list ))
+ stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list );
+
+ if( stat == CUBIT_FAILURE )
+ {
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ CubitUndo::remove_last_undo();
return CUBIT_FAILURE;
+ }
+ if( CubitUndo::get_undo_enabled() && keep_old )
+ CubitUndo::note_result_bodies( new_body_list );
+
// Update graphics
DLIList<Body*> moved_bodies(new_body_list);
moved_bodies.intersect(old_body_list);
@@ -8541,9 +14982,12 @@
CubitStatus GeometryModifyTool::tweak_target( DLIList<RefEdge*> &ref_edge_list,
DLIList<RefEdge*> &target_edge_list,
DLIList<Body*> &new_body_list,
+ CubitBoolean extend_flg,
+ CubitPlane *limit_plane,
CubitBoolean reverse_flg,
CubitBoolean keep_old,
- CubitBoolean preview )
+ CubitBoolean preview,
+ double max_area_increase /*= 0*/ )
{
DLIList<Curve*> curve_list(ref_edge_list.size());
DLIList<Curve*> target_curve_list(target_edge_list.size());
@@ -8565,26 +15009,245 @@
return CUBIT_FAILURE;
}
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ if( keep_old )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( ref_edge_list );
+ }
+
// Do tweak to target
DLIList<BodySM*> new_bodysm_list;
- if( gme_ptr1->tweak_target( curve_list, target_curve_list, new_bodysm_list,
- reverse_flg, keep_old, preview ) == CUBIT_FAILURE )
+ CubitStatus stat = gme_ptr1->tweak_target( curve_list, target_curve_list,
+ new_bodysm_list, extend_flg,
+ limit_plane, reverse_flg,
+ keep_old, preview, max_area_increase );
+
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ if( stat == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+
+ if( stat == CUBIT_FAILURE)
+ return stat;
+
+ if( preview == CUBIT_FALSE )
+ {
+ // Update DAG
+ stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list );
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( stat == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+ else if( keep_old )
+ CubitUndo::note_result_bodies( new_body_list );
+ }
+ }
+
+ // Update graphics
+ DLIList<Body*> moved_bodies(new_body_list);
+ moved_bodies.intersect(old_body_list);
+ while (moved_bodies.size())
+ moved_bodies.pop()->notify_sub_all_observers( GEOMETRY_MODIFIED );
+
+ return stat;
+}
+
+//=============================================================================
+// Description: 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 given location will be
+// projected to be on the planar surface(s) before being used.
+// Author : Steve Storm
+// Date : 09/09/08
+//=============================================================================
+CubitStatus
+GeometryModifyTool::tweak_target( RefVertex *ref_vertex_ptr,
+ DLIList<RefFace*> &modify_ref_face_list,
+ CubitVector &target_loc,
+ Body *&new_Body_ptr,
+ CubitBoolean keep_old,
+ CubitBoolean preview )
+{
+ if( modify_ref_face_list.size() == 0 )
+ {
+ PRINT_ERROR( "No surfaces found to modify\n" );
return CUBIT_FAILURE;
+ }
- // Update DAG
- if (!finish_sm_op( old_body_list, new_bodysm_list, new_body_list ))
+ int i;
+ RefFace *ref_face_ptr;
+
+ // Check to make sure vertex is part of all given surfaces
+ modify_ref_face_list.reset();
+ for( i=modify_ref_face_list.size(); i--; )
+ {
+ ref_face_ptr = modify_ref_face_list.get_and_step();
+
+ if( !ref_face_ptr->is_directly_related( ref_vertex_ptr ) )
+ {
+ PRINT_ERROR( "Vertex %d is not part of 'modify' Surface %d\n",
+ ref_vertex_ptr->id(), ref_face_ptr->id() );
+ return CUBIT_FAILURE;
+ }
+ }
+
+ GeometryModifyEngine *gme_ptr;
+ DLIList<RefVertex*> ref_vertex_list(1);
+ ref_vertex_list.append( ref_vertex_ptr );
+ DLIList<Body*> old_body_list;
+ DLIList<Point*> point_list(1);
+ gme_ptr = tweak_setup( ref_vertex_list, "Tweaking", old_body_list, point_list );
+ if( !gme_ptr )
return CUBIT_FAILURE;
+ // We already made sure the vertex is part of all of the modify faces, so
+ // just use the common_modify_engine function to get the surface_list
+ DLIList<Surface*> surface_list;
+ if( !common_modify_engine( modify_ref_face_list, surface_list ) )
+ return CUBIT_FAILURE;
+
+ // Make sure part of a sheet body, not a solid body
+ Body *body_ptr = ref_vertex_ptr->body();
+ if( !body_ptr->is_sheet_body() )
+ {
+ PRINT_ERROR( "Vertex %d is not in a sheet body - Body %d is solid.\n"
+ " Tweaking a vertex to a target currently not possible on solid bodies.\n",
+ ref_vertex_ptr->id(), body_ptr->id() );
+ return CUBIT_FAILURE;
+ }
+
+ // Make sure all the given surfaces are planar
+ modify_ref_face_list.reset();
+ for( i=modify_ref_face_list.size(); i--; )
+ {
+ ref_face_ptr = modify_ref_face_list.get_and_step();
+
+ if( !ref_face_ptr->is_planar() )
+ {
+ PRINT_ERROR( "Surfaces to modify must be planar - Surface %d is not planar\n", ref_face_ptr->id() );
+ return CUBIT_FAILURE;
+ }
+ }
+
+ // Make sure all curves (on modify surfaces) attached to the given vertex are linear
+ // Get all attached curves
+ int j;
+ DLIList<RefEdge*> ref_edge_list;
+ ref_vertex_ptr->ref_edges( ref_edge_list );
+ RefEdge *ref_edge_ptr;
+ for( i=ref_edge_list.size(); i--; )
+ {
+ ref_edge_ptr = ref_edge_list.get_and_step();
+
+ // Check to see if this edge is linear, if it is in one of the modify surfaces
+ modify_ref_face_list.reset();
+ for( j=modify_ref_face_list.size(); j--; )
+ {
+ ref_face_ptr = modify_ref_face_list.get_and_step();
+ if( ref_face_ptr->is_directly_related( ref_edge_ptr ) )
+ {
+ Curve *curve_ptr = ref_edge_ptr->get_curve_ptr();
+ GeometryType curve_type = curve_ptr->geometry_type();
+ if( curve_type != STRAIGHT_CURVE_TYPE )
+ {
+ PRINT_ERROR( "Curve %d is not linear. Curves that are in the 'modify'\n"
+ " surfaces attached to the tweak vertex must be linear.\n",
+ ref_edge_ptr->id() );
+ return CUBIT_FAILURE;
+ }
+ else
+ break;
+ }
+ }
+ }
+
+ // Project the location to the given surfaces and make sure all of these locations
+ // are the same
+ modify_ref_face_list.reset();
+
+ CubitVector ref_loc( target_loc ); // Reference location
+ ref_face_ptr = modify_ref_face_list.get_and_step();
+ ref_face_ptr->move_to_surface( ref_loc );
+ int ref_surf_id = ref_face_ptr->id();
+
+ for( i=modify_ref_face_list.size()-1; i--; )
+ {
+ ref_face_ptr = modify_ref_face_list.get_and_step();
+
+ CubitVector proj_loc( target_loc );
+ ref_face_ptr->move_to_surface( proj_loc );
+
+ if( !ref_loc.about_equal( proj_loc ) )
+ {
+ PRINT_ERROR( "Target location must project to all of the 'modify' surfaces at\n"
+ " exactly the same location - the tweaked Vertex %d will move to this\n"
+ " common (same) projected location, tweaking the modify surfaces with it.\n"
+ " Given target location = %f, %f, %f\n"
+ " Projected location on Surface %d = %f, %f, %f\n"
+ " Projected location on Surface %d = %f, %f, %f\n",
+ ref_vertex_ptr->id(),
+ target_loc.x(), target_loc.y(), target_loc.z(),
+ ref_surf_id, ref_loc.x(), ref_loc.y(), ref_loc.z(),
+ ref_face_ptr->id(), proj_loc.x(), proj_loc.y(), proj_loc.z() );
+
+ return CUBIT_FAILURE;
+ }
+ }
+
+ // It looks like the inputs are valid so get ready to do the tweak
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ {
+ if( keep_old )
+ CubitUndo::save_state();
+ else
+ CubitUndo::save_state_with_cubit_file( ref_vertex_list );
+ }
+
+ Point *point_ptr = point_list.get();
+
+ // Do tweak to target
+ BodySM *new_bodysm_ptr;
+ CubitStatus stat = gme_ptr->tweak_target( point_ptr, surface_list,
+ ref_loc,
+ new_bodysm_ptr,
+ keep_old, preview );
+
+ if( CubitUndo::get_undo_enabled() && preview == CUBIT_FALSE )
+ if( stat == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+
+ if( stat == CUBIT_FAILURE)
+ return stat;
+
+ DLIList<BodySM*> new_bodysm_list;
+ new_bodysm_list.append( new_bodysm_ptr );
+ DLIList<Body*> new_body_list;
+
+ if( preview == CUBIT_FALSE )
+ {
+ // Update DAG
+ stat = finish_sm_op( old_body_list, new_bodysm_list, new_body_list );
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( stat == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+ else if( keep_old )
+ CubitUndo::note_result_bodies( new_body_list );
+ }
+ }
+
// Update graphics
DLIList<Body*> moved_bodies(new_body_list);
moved_bodies.intersect(old_body_list);
while (moved_bodies.size())
moved_bodies.pop()->notify_sub_all_observers( GEOMETRY_MODIFIED );
- return CUBIT_SUCCESS;
+ return stat;
}
-
// KGM
#if 0
bool GeometryModifyTool::contains_intermediate_geometry(DLIList<RefFace*>& ref_face_list) const
@@ -8598,15 +15261,16 @@
}
#endif
+/*
//the following surface tool operations added by Tyronne Lim (CAT) ********************
CubitStatus GeometryModifyTool::create_net_surface( DLIList<Surface*>& ref_face_list, BodySM *& new_body,
DLIList<DLIList<CubitVector*>*> &vec_lists_u,
DLIList<DLIList<CubitVector*>*> &vec_lists_v,
double net_tol, CubitBoolean heal )
-{
+{
GeometryModifyEngine* GMEPtr = get_engine(ref_face_list.get());
return GMEPtr->create_net_surface( ref_face_list, new_body, vec_lists_u, vec_lists_v, net_tol, heal );
-}
+} */
CubitStatus GeometryModifyTool::create_net_surface( DLIList<RefEdge*>& u_curves, DLIList<RefEdge*>& v_curves,
double net_tol, CubitBoolean heal )
@@ -8643,14 +15307,29 @@
DLIList<Curve*> curves_in_v(bridge_list.size());
CAST_LIST( bridge_list, curves_in_v, Curve );
- BodySM *new_body = NULL;
- if( !GME_ptr->create_net_surface( curves_in_u, curves_in_v, new_body, net_tol, heal ) )
+ BodySM *new_smbody = NULL;
+ if( !GME_ptr->create_net_surface( curves_in_u, curves_in_v, new_smbody, net_tol, heal ) )
return CUBIT_FAILURE;
- if( GeometryQueryTool::instance()->make_Body( new_body ) )
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::save_state();
+
+ Body* new_body = NULL;
+ new_body = GeometryQueryTool::instance()->make_Body( new_smbody );
+ if( new_body )
+ {
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::note_result_body(new_body);
+
return CUBIT_SUCCESS;
+ }
else
+ {
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::remove_last_undo();
+
return CUBIT_FAILURE;
+ }
}
CubitStatus GeometryModifyTool::create_offset_surface( RefFace* ref_face_ptr, double offset_distance )
@@ -8661,18 +15340,235 @@
Surface *tmp_surf = NULL;
tmp_surf = CAST_TO( bridge_ptr, Surface );
- BodySM *new_body;
- if( !GMEPtr->create_offset_surface( tmp_surf, new_body, offset_distance ) )
+ BodySM *new_smbody;
+ if( !GMEPtr->create_offset_surface( tmp_surf, new_smbody, offset_distance ) )
return CUBIT_FAILURE;
- if( GeometryQueryTool::instance()->make_Body( new_body ) )
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::save_state();
+
+ Body* new_body = NULL;
+ new_body = GeometryQueryTool::instance()->make_Body( new_smbody );
+ if( new_body )
+ {
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::note_result_body(new_body);
+
return CUBIT_SUCCESS;
+ }
else
+ {
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::remove_last_undo();
+
return CUBIT_FAILURE;
+ }
}
-CubitStatus GeometryModifyTool::create_offset_body( Body *body_ptr, Body *&new_body, double offset_distance )
+//-----------------------------------------------------------------------------
+// Purpose : This function creates a sheet body or bodies by offsetting
+// the given faces. An 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.
+//
+// Special Notes :
+//
+// Creator : Steve Storm
+//
+// Creation Date : 05/04/08
+//-----------------------------------------------------------------------------
+CubitStatus
+GeometryModifyTool::create_offset_sheet( DLIList<RefFace*> &ref_face_list,
+ double offset_distance,
+ DLIList<RefFace*> *add_ref_face_list_ptr,
+ DLIList<double> *add_offset_list_ptr,
+ DLIList<Body*> &new_body_list,
+ CubitBoolean preview )
{
+ if( !ref_face_list.size() )
+ {
+ return CUBIT_SUCCESS;
+ }
+ else
+ {
+ for (int i = 0; i < ref_face_list.size(); i++)
+ {
+ RefFace *temp = ref_face_list.get_and_step();
+ if (temp->get_surface_ptr()->is_cylindrical() == 16)
+ {
+ DLIList<Curve*> curves;
+ CubitVector loc;
+ double rad;
+ temp->get_surface_ptr()->curves(curves);
+ curves.reset();
+ int j = 0;
+ while (curves.get()->geometry_type() != ELLIPSE_CURVE_TYPE && curves.get()->geometry_type() != ARC_CURVE_TYPE)
+ {
+ curves.step();
+ if (j == curves.size())
+ {
+ break;
+ }
+ j++;
+ }
+ curves.get()->get_center_radius(loc, rad);
+ if (offset_distance >= rad)
+ {
+ CubitVector norm, close, result;
+ double angle;
+ temp->get_surface_ptr()->closest_point(loc, &close, &norm);
+ result.set(loc.x()-close.x(), loc.y()-close.y(), loc.z()-close.z());
+ angle = result.interior_angle(norm);
+ if (angle < GEOMETRY_RESABS && angle > -GEOMETRY_RESABS)
+ {
+ PRINT_ERROR("Offset is greater than the radius of curvature for surface %i.\n", temp->id());
+ PRINT_WARNING("No body will be created for surface %i.\n", temp->id());
+ if (ref_face_list.size() > 1)
+ {
+ ref_face_list.remove_all_with_value(temp);
+ }
+ else
+ {
+ return CUBIT_FAILURE;
+ }
+ }
+ }
+ }
+ }
+ for (int i = 0; i < add_ref_face_list_ptr->size(); i++)
+ {
+ RefFace *temp = ref_face_list.get_and_step();
+ if (temp->get_surface_ptr()->is_cylindrical() == 16)
+ {
+ DLIList<Curve*> curves;
+ CubitVector loc;
+ double rad;
+ temp->get_surface_ptr()->curves(curves);
+ curves.reset();
+ while (curves.get()->geometry_type() != ELLIPSE_CURVE_TYPE && curves.get()->geometry_type() != ARC_CURVE_TYPE)
+ {
+ curves.step();
+ }
+ curves.get()->get_center_radius(loc, rad);
+ if (offset_distance >= rad)
+ {
+ CubitVector norm, close, result;
+ double angle;
+ temp->get_surface_ptr()->closest_point(loc, &close, &norm);
+ result.set(loc.x()-close.x(), loc.y()-close.y(), loc.z()-close.z());
+ angle = result.interior_angle(norm);
+ if (angle < GEOMETRY_RESABS && angle > -GEOMETRY_RESABS)
+ {
+ PRINT_ERROR("Offset is greater than the radius of curvature for surface %i.\n", temp->id());
+ PRINT_WARNING("No body will be created for surface %i.\n", temp->id());
+ add_ref_face_list_ptr->remove_all_with_value(temp);
+ }
+ }
+ }
+ }
+ }
+
+ DLIList<RefFace*> all_ref_face_list(ref_face_list.size());
+ all_ref_face_list = ref_face_list;
+ if( add_ref_face_list_ptr->size() )
+ all_ref_face_list += *add_ref_face_list_ptr;
+
+ // Check for virtual geometry
+ DLIList<RefEntity*> ref_ent_list;
+ CAST_LIST_TO_PARENT(all_ref_face_list, ref_ent_list);
+ if ( GeometryQueryTool::instance()->contains_intermediate_geometry(ref_ent_list) )
+ {
+ PRINT_ERROR("OFFSETTING surfaces containing virtual geometry is not\n"
+ " allowed. Delete virtual geometry on these surfaces\n"
+ " before operation.\n" );
+ return CUBIT_FAILURE;
+ }
+
+ // Look for a common GeometryModifyEngine for all of the RefFaces
+ int count = all_ref_face_list.size();
+ DLIList<TopologyBridge*> bridge_list(count);
+ DLIList<TopologyEntity*> entity_list(count);
+ CAST_LIST_TO_PARENT( all_ref_face_list, entity_list );
+
+ GeometryModifyEngine* GME_ptr =
+ common_modify_engine( entity_list, bridge_list );
+ if(! GME_ptr )
+ {
+ PRINT_ERROR("Cannot construct offset sheet(s) using surfaces that\n"
+ " do not share a common geometry engine.\n");
+ return CUBIT_FAILURE;
+ }
+
+ // Get Surfaces from the RefFaces
+ DLIList<Surface*> surface_list(ref_face_list.size());
+ int i;
+ RefFace *ref_face_ptr;
+ for( i=ref_face_list.size(); i--; )
+ {
+ ref_face_ptr = ref_face_list.get_and_step();
+ surface_list.append( ref_face_ptr->get_surface_ptr() );
+ }
+
+ DLIList<Surface*> add_surf_list;
+ if( add_ref_face_list_ptr->size() )
+ {
+ for( i=add_ref_face_list_ptr->size(); i--; )
+ {
+ ref_face_ptr = add_ref_face_list_ptr->get_and_step();
+ add_surf_list.append( ref_face_ptr->get_surface_ptr() );
+ }
+ }
+
+ DLIList<BodySM*> BodySM_list;
+ if( add_surf_list.size() )
+ {
+ if( GME_ptr->create_offset_sheet( surface_list, offset_distance, &add_surf_list,
+ add_offset_list_ptr, BodySM_list, preview ) == CUBIT_FAILURE )
+ return CUBIT_FAILURE;
+ }
+ else
+ {
+ if( GME_ptr->create_offset_sheet( surface_list, offset_distance, NULL,
+ NULL, BodySM_list, preview ) == CUBIT_FAILURE )
+ return CUBIT_FAILURE;
+ }
+
+ if( !BodySM_list.size() )
+ return CUBIT_FAILURE;
+
+ BodySM *bodysm_ptr;
+ Body* body_ptr;
+ for( i=BodySM_list.size(); i--; )
+ {
+ DLIList<Surface*> surfs;
+ bodysm_ptr = BodySM_list.get_and_step();
+ bodysm_ptr->surfaces(surfs);
+ if (!surfs.size())
+ {
+ PRINT_WARNING("Empty body created. Body deleted.\n");
+ PRINT_WARNING("Empty body likely due to an offset larger than the radius of curvature of a surface.\n");
+ bodysm_ptr->get_geometry_query_engine()->delete_solid_model_entities(bodysm_ptr);
+ break;
+ }
+
+ body_ptr = GeometryQueryTool::instance()->make_Body( bodysm_ptr );
+ if( body_ptr )
+ new_body_list.append( body_ptr );
+ }
+
+ if( new_body_list.size() )
+ return CUBIT_SUCCESS;
+ else
+ return CUBIT_FAILURE;
+}
+
+CubitStatus
+GeometryModifyTool::create_offset_body( Body *body_ptr, Body *&new_body,
+ double offset_distance )
+{
GeometryModifyEngine* GMEPtr = get_engine(body_ptr);
BodySM *body_sm = body_ptr->get_body_sm_ptr();
@@ -8686,20 +15582,44 @@
if( !GMEPtr->create_offset_body( body_sm, new_body_sm, offset_distance ) )
return CUBIT_FAILURE;
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::save_state();
+
new_body = GeometryQueryTool::instance()->make_Body( new_body_sm );
if( new_body )
+ {
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::note_result_body(new_body);
+
return CUBIT_SUCCESS;
+ }
else
+ {
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::remove_last_undo();
+
return CUBIT_FAILURE;
+ }
}
-CubitStatus GeometryModifyTool::create_skin_surface( DLIList<RefEdge*>& ref_edges, Body*& new_body )
+CubitStatus GeometryModifyTool::create_skin_surface( DLIList<RefEdge*>& ref_edges, Body*& new_body,
+ DLIList<RefEdge*>& guides)
{
DLIList<TopologyBridge*> bridge_list;
DLIList<TopologyEntity*> entity_list;
CAST_LIST_TO_PARENT( ref_edges, entity_list );
+ DLIList<TopologyBridge*> guide_bridge_list;
+ DLIList<TopologyEntity*> guide_entity_list;
+ CAST_LIST_TO_PARENT(guides, guide_entity_list);
+
+ if (ref_edges.size() < 2)
+ {
+ PRINT_ERROR("Must specify at least 2 curves to create a skinned surface.\n");
+ return CUBIT_FAILURE;
+ }
+
GeometryModifyEngine* GME_ptr =
common_modify_engine( entity_list, bridge_list );
if(! GME_ptr )
@@ -8709,20 +15629,48 @@
return CUBIT_FAILURE;
}
+ if (guides.size() > 0)
+ {
+ GeometryModifyEngine* GME_ptr2 =
+ common_modify_engine( guide_entity_list, guide_bridge_list );
+ if (GME_ptr != GME_ptr2)
+ {
+ PRINT_ERROR("Performing create skin with geometry from\n"
+ "different modeling engines is not allowed.\n");
+ return CUBIT_FAILURE;
+ }
+ }
+
DLIList<Curve*> curves_to_skin(bridge_list.size());
CAST_LIST( bridge_list, curves_to_skin, Curve );
+ DLIList<Curve*> guide_curves(guide_bridge_list.size());
+ CAST_LIST(guide_bridge_list, guide_curves, Curve);
+
BodySM *new_body_sm = NULL;
- if( !GME_ptr->create_skin_surface( curves_to_skin, new_body_sm ) )
+ if( !GME_ptr->create_skin_surface( curves_to_skin, new_body_sm, guide_curves ) )
return CUBIT_FAILURE;
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::save_state();
+
new_body = NULL;
new_body = GeometryQueryTool::instance()->make_Body( new_body_sm );
if( new_body )
+ {
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::note_result_body(new_body);
+
return CUBIT_SUCCESS;
+ }
else
+ {
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::remove_last_undo();
+
return CUBIT_FAILURE;
+ }
}
@@ -8755,6 +15703,9 @@
loft_surfaces.reset();
BodySM* new_body_sm = 0;
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state();
+
CubitStatus result = result_ptr->loft_surfaces_to_body(
loft_surfaces.get_and_step(),
takeoff1,
@@ -8770,14 +15721,97 @@
if(result && new_body_sm)
{
new_body = GeometryQueryTool::instance()->make_Body(new_body_sm);
+
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::note_result_body(new_body);
}
-
+ else
+ {
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
+ }
return result;
}
-CubitStatus GeometryModifyTool::create_surface( DLIList<CubitVector*>& vec_list, Body *&new_body,
- RefFace *ref_face_ptr,CubitBoolean project_points )
+CubitStatus GeometryModifyTool::create_surface( DLIList<RefVertex*> &vert_list,
+ Body *&new_body )
{
+ //determine which vertices are free and which are not...
+ //copy ones that are not
+ vert_list.reset();
+ DLIList<Point*> points;
+ GeometryModifyEngine *GMEPtr = get_engine( vert_list.get()->get_point_ptr() );
+
+ DLIList<RefVertex*> free_ref_vertices;
+ int i;
+ for( i=vert_list.size(); i--; )
+ {
+ RefVertex *tmp_vert = vert_list.get_and_step();
+
+ if( tmp_vert->num_parent_ref_entities() == 0 )
+ free_ref_vertices.append( tmp_vert );
+
+ Point *tmp_point = tmp_vert->get_point_ptr();
+ if( GMEPtr != get_engine( tmp_point ) )
+ {
+ PRINT_INFO("Vertices are not from same modeling engine.\n");
+ return CUBIT_FAILURE;
+ }
+
+ if( tmp_vert->get_parents() == 0 )
+ {
+ points.append( tmp_point );
+ }
+ else
+ {
+ Point *new_point = GMEPtr->make_Point( tmp_vert->coordinates() );
+ points.append( new_point );
+ }
+ }
+
+ BodySM* body_sm = NULL;
+ CubitStatus stat = GMEPtr->create_surface( points, body_sm );
+
+ if( stat == CUBIT_FAILURE )
+ return stat;
+
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::save_state();
+
+ if( body_sm )
+ new_body = GeometryQueryTool::instance()->make_Body(body_sm);
+
+ if (new_body)
+ {
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::note_result_body(new_body);
+
+ stat = CUBIT_SUCCESS;
+ }
+ else
+ {
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::remove_last_undo();
+
+ stat = CUBIT_FAILURE;
+ }
+
+ for( i=free_ref_vertices.size(); i--; )
+ {
+ RefVertex *free_vertex = free_ref_vertices.get_and_step();
+ CubitObserver::notify_static_observers( free_vertex, TOP_LEVEL_ENTITY_DESTRUCTED );
+ CGMHistory::Event evt(CGMHistory::TOP_LEVEL_ENTITY_DELETED, free_vertex );
+ GeometryQueryTool::instance()->history().add_event(evt);
+ }
+
+ return stat;
+}
+
+CubitStatus GeometryModifyTool::create_surface( DLIList<CubitVector*>& vec_list,
+ Body *&new_body,
+ RefFace *ref_face_ptr,
+ CubitBoolean project_points )
+{
GeometryModifyEngine* GMEPtr = gmeList.get();
if( ref_face_ptr )
{
@@ -8796,12 +15830,28 @@
if( stat == CUBIT_FAILURE )
return stat;
+
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::save_state();
+
if( body_sm )
new_body = GeometryQueryTool::instance()->make_Body(body_sm);
- if( !new_body )
- return CUBIT_FAILURE;
+
+ if (new_body)
+ {
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::note_result_body(new_body);
+
+ stat = CUBIT_SUCCESS;
+ }
else
- return CUBIT_SUCCESS;
+ {
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::remove_last_undo();
+
+ stat = CUBIT_FAILURE;
+ }
+ return stat;
}
CubitStatus GeometryModifyTool::create_weld_surface( CubitVector &root,
@@ -8825,6 +15875,9 @@
return CUBIT_FAILURE;
}
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::save_state();
+
surfaces.reset();
BodySM* new_body_sm = 0;
CubitStatus result = GMEPtr->create_weld_surface(
@@ -8838,6 +15891,16 @@
if(result && new_body_sm)
{
new_body = GeometryQueryTool::instance()->make_Body(new_body_sm);
+ if (new_body)
+ {
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::note_result_body(new_body);
+ }
+ else
+ {
+ if (CubitUndo::get_undo_enabled())
+ CubitUndo::remove_last_undo();
+ }
}
return result;
}
@@ -8862,7 +15925,10 @@
entity->get_child_ref_entities(children);
children.last();
for (int i = children.size(); i--; )
+ {
+ //PRINT_INFO("Removing dead entity on %s %d\n", children.get()->class_name(), children.get()->id() );
remove_dead_entity_names( children.step_and_get() );
+ }
}
//-------------------------------------------------------------------------
@@ -8884,6 +15950,529 @@
return 0;
}
+CubitStatus GeometryModifyTool::tolerant_imprint( DLIList<RefFace*> &ref_faces,
+ DLIList<RefEdge*> &ref_edge_list,
+ DLIList<Body*> &new_bodies,
+ bool merge )
+{
+ if( ref_faces.size() > 2 )
+ return CUBIT_FAILURE;
+
+ ref_faces.reset();
+ RefFace *face1 = ref_faces.get_and_step();
+ RefFace *face2 = ref_faces.get_and_step();
+
+ if(ref_edge_list.size() > 0)
+ {
+ //collect all the bodies containing any edge on these 2 surfaces
+ //so you can merge them afterward
+ DLIList<Body*> bodies_to_merge;
+ if( merge )
+ {
+ DLIList<RefEdge*> tmp_edges;
+ face1->ref_edges( tmp_edges);
+
+ int j;
+ for( j=tmp_edges.size(); j--; )
+ {
+ RefEdge *tmp_edge = tmp_edges.get_and_step();
+ DLIList<Body*> body_list;
+ tmp_edge->bodies( body_list );
+ bodies_to_merge += body_list;
+ }
+
+ for( j=ref_edge_list.size(); j--; )
+ {
+ RefEdge *tmp_edge = ref_edge_list.get_and_step();
+ DLIList<Body*> body_list;
+ tmp_edge->bodies( body_list );
+ bodies_to_merge += body_list;
+ }
+
+ tmp_edges.clean_out();
+ face2->ref_edges( tmp_edges );
+
+ for( j=tmp_edges.size(); j--; )
+ {
+ RefEdge *tmp_edge = tmp_edges.get_and_step();
+ DLIList<Body*> body_list;
+ tmp_edge->bodies( body_list );
+ bodies_to_merge += body_list;
+ }
+ bodies_to_merge.uniquify_unordered();
+ }
+
+ DLIList<RefEdge*> edges_to_imprint_onto_face1;
+ DLIList<RefEdge*> edges_to_imprint_onto_face2;
+
+ //sort edges...
+ //edges on face1 and not on face2 will be imprinted on face2
+ //edges on face2 and not on face1 will be imprinted on face1
+ int i;
+ for(i=ref_edge_list.size(); i--; )
+ {
+ RefEdge *tmp_edge = ref_edge_list.get_and_step();
+ DLIList<RefFace*> tmp_faces;
+ tmp_edge->ref_faces( tmp_faces );
+
+ if( tmp_faces.move_to( face1 ) && !tmp_faces.move_to( face2 ) )
+ edges_to_imprint_onto_face2.append( tmp_edge );
+ else if( tmp_faces.move_to( face2 ) && !tmp_faces.move_to( face1 ) )
+ edges_to_imprint_onto_face1.append( tmp_edge );
+ else
+ PRINT_ERROR("Will not imprint curve %d onto either surface.\n", tmp_edge->id() );
+ }
+
+ //if there are edges to impint onto both surfaces
+ if( edges_to_imprint_onto_face1.size() &&
+ edges_to_imprint_onto_face2.size() )
+ {
+ //get the modify engine
+ DLIList<Surface*> surf_list( 1 );
+ DLIList<Curve*> curve_list( edges_to_imprint_onto_face2.size() );
+ DLIList<RefFace*> ref_face_list( 1 );
+ ref_face_list.append( face2 );
+ GeometryModifyEngine* gme = common_modify_engine( ref_face_list,
+ edges_to_imprint_onto_face2,
+ surf_list,
+ curve_list );
+ if ( !gme )
+ {
+ PRINT_ERROR("Performing IMPRINT with entities containing geometry from\n"
+ "different modeling engines is not allowed.\n" );
+ return CUBIT_FAILURE;
+ }
+
+ //copy the specified boundary curves of face1 to imprint onto face2...
+ //these could be stale after we imprint face1
+ DLIList<Curve*> copied_curves;
+ for(i=curve_list.size(); i--; )
+ {
+ Curve *copied_curve = gme->make_Curve( curve_list.get_and_step() );
+ copied_curves.append( copied_curve );
+ }
+
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state_with_cubit_file( ref_faces );
+
+ //do the imprint onto face1
+ Body *new_body = NULL;
+ CubitStatus status;
+ status = tolerant_imprint( face1, edges_to_imprint_onto_face1, new_body );
+
+ //if we failed...get out
+ if( status == CUBIT_FAILURE )
+ {
+ //delete the copied curves
+ for( i=copied_curves.size(); i--; )
+ gme->get_gqe()->delete_solid_model_entities( copied_curves.get_and_step() );
+
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
+
+ return CUBIT_FAILURE;
+ }
+
+ DLIList<Body*> original_body_list;
+ face2->bodies( original_body_list );
+
+ //get the Surface* ptr
+ Surface *surface2 = face2->get_surface_ptr();
+
+ DLIList<BodySM*> body_sm_list;
+ for(i=original_body_list.size(); i--;)
+ body_sm_list.append(original_body_list.get_and_step()->get_body_sm_ptr());
+
+ int process_composites = 0;
+ if(contains_composites(original_body_list))
+ process_composites = 1;
+
+ if(process_composites)
+ {
+ // Push virtual attributes down to solid model topology before
+ // doing the imprint.
+ do_attribute_setup();
+ push_vg_attributes_before_modify(body_sm_list);
+ // This must be done after pushing the vg atts because it uses them.
+ push_imprint_attributes_before_modify(body_sm_list);
+ }
+
+ //do the imprint onto face2
+ BodySM *new_bodysm = NULL;
+ DLIList<TopologyBridge*> new_tbs, att_tbs, temporary_bridges;
+ status = gme->tolerant_imprint_surface_with_curves( surface2, copied_curves, temporary_bridges, new_bodysm,
+ &new_tbs, &att_tbs);
+ temporary_bridges.uniquify_ordered();
+ while(temporary_bridges.size())
+ delete temporary_bridges.pop();
+
+ DLIList<BodySM*> new_body_list;
+ if(new_bodysm)
+ new_body_list.append(new_bodysm);
+
+
+ //delete the copied curves
+ for( i=copied_curves.size(); i--; )
+ gme->get_gqe()->delete_solid_model_entities( copied_curves.get_and_step() );
+
+ if( status == CUBIT_FAILURE )
+ {
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
+
+ if(process_composites)
+ {
+ remove_pushed_attributes(new_body_list, original_body_list);
+ do_attribute_cleanup();
+ }
+
+ return CUBIT_FAILURE;
+ }
+ else
+ {
+ if(process_composites)
+ {
+ // Analyze the results and adjust virtual attributes as necessary.
+ DLIList<TopologyBridge*> tb_list;
+ CAST_LIST(new_body_list, tb_list, TopologyBridge);
+ GeometryQueryTool::instance()->ige_attribute_after_imprinting(new_tbs, att_tbs,
+ tb_list, original_body_list);
+
+ // Clean up attributes.
+ remove_imprint_attributes_after_modify(body_sm_list, new_body_list);
+
+ // Restore the virtual geometry.
+ restore_vg_after_modify(new_body_list, original_body_list, gme);
+ remove_pushed_attributes(new_body_list, original_body_list);
+ }
+ }
+
+ DLIList<BodySM*> new_bodies;
+ new_bodies.append( new_bodysm );
+ DLIList<Body*> result_bodies;
+ status = finish_sm_op( original_body_list, new_bodies, result_bodies );
+
+ if(process_composites)
+ do_attribute_cleanup();
+
+ if( status == CUBIT_FAILURE )
+ {
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
+ return CUBIT_FAILURE;
+ }
+ }
+ //user specified edges that will only imprint onto face1...do it anyway
+ else if( edges_to_imprint_onto_face1.size() )
+ {
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<RefFace*> tmp_faces(1);
+ tmp_faces.append( face1 );
+ CubitUndo::save_state_with_cubit_file( tmp_faces );
+ }
+
+ bool undo_enabled = CubitUndo::get_undo_enabled();
+ CubitUndo::set_undo_enabled( false );
+
+ Body *new_body = NULL;
+ CubitStatus stat = tolerant_imprint( face1, edges_to_imprint_onto_face1,
+ new_body, merge );
+
+ if( undo_enabled )
+ CubitUndo::set_undo_enabled( true );
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( stat == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+ }
+
+ return stat;
+ }
+ //user specified edges that will only imprint onto face2...do it anyway
+ else if( edges_to_imprint_onto_face2.size() )
+ {
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<RefFace*> tmp_faces(1);
+ tmp_faces.append( face2 );
+ CubitUndo::save_state_with_cubit_file( tmp_faces );
+ }
+
+ bool undo_enabled = CubitUndo::get_undo_enabled();
+ CubitUndo::set_undo_enabled( false );
+
+ Body *new_body = NULL;
+ CubitStatus stat = tolerant_imprint( face2, edges_to_imprint_onto_face2,
+ new_body, merge );
+
+ if( undo_enabled )
+ CubitUndo::set_undo_enabled( true );
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( stat == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+ }
+
+ return stat;
+ }
+
+ if( merge )
+ MergeTool::instance()->merge_bodies( bodies_to_merge );
+ }
+ else
+ {
+ DLIList<RefFace*> faces_not_to_merge;
+ Body *body1 = face1->body();
+ Body *body2 = face2->body();
+ /*
+ if(merge)
+ {
+ DLIList<RefFace*> tmp_faces;
+ body1->ref_faces(tmp_faces);
+ if(tmp_faces.move_to(face1))
+ tmp_faces.extract();
+ faces_not_to_merge = tmp_faces;
+
+ tmp_faces.clean_out();
+ body2->ref_faces(tmp_faces);
+ if(tmp_faces.move_to(face2))
+ tmp_faces.extract();
+ faces_not_to_merge += tmp_faces;
+ }
+ */
+
+ //get the modify engine
+ DLIList<Surface*> surf_list( 1 );
+ DLIList<RefFace*> ref_face_list( 2 );
+ ref_face_list.append( face1 );
+ ref_face_list.append( face2 );
+ GeometryModifyEngine* gme = common_modify_engine( ref_face_list, surf_list);
+
+ if ( !gme )
+ {
+ PRINT_ERROR("Performing IMPRINT with entities containing geometry from\n"
+ "different modeling engines is not allowed.\n" );
+ return CUBIT_FAILURE;
+ }
+
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state_with_cubit_file( ref_faces );
+
+ //do the imprint onto face1
+ DLIList<BodySM*> new_bodysm_list;
+ CubitStatus status = gme->tolerant_imprint(surf_list, new_bodysm_list);
+
+ //if we failed...get out
+ if( status == CUBIT_FAILURE )
+ {
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
+
+ return CUBIT_FAILURE;
+ }
+
+ DLIList<Body*> result_bodies;
+ DLIList<Body*> original_body_list;
+ original_body_list.append(body1);
+ original_body_list.append(body2);
+ status = finish_sm_op( original_body_list, new_bodysm_list, result_bodies );
+
+ /*
+ if( merge )
+ {
+ DLIList<RefFace*> faces_to_merge, tmp_faces;
+ body1->ref_faces(faces_to_merge);
+ body2->ref_faces(tmp_faces);
+ faces_to_merge -= faces_not_to_merge;
+ if(faces_to_merge.size() > 1)
+ {
+ MergeTool::instance()->merge_reffaces(faces_to_merge);
+ }
+ }
+ */
+ }
+
+ return CUBIT_SUCCESS;
+}
+
+
+CubitStatus GeometryModifyTool::tolerant_imprint( RefFace *ref_face,
+ DLIList<RefEdge*> &ref_edge_list,
+ Body *&new_body,
+ bool merge )
+{
+ int i;
+ DLIList<Body*> bodies_to_merge;
+ if( merge )
+ {
+ DLIList<RefEdge*> tmp_edges;
+ ref_face->ref_edges( tmp_edges );
+
+ for( i=tmp_edges.size(); i--; )
+ {
+ RefEdge *tmp_edge = tmp_edges.get_and_step();
+ DLIList<Body*> body_list;
+ tmp_edge->bodies( body_list );
+ bodies_to_merge += body_list;
+ }
+
+ for( i=ref_edge_list.size(); i--; )
+ {
+ RefEdge *tmp_edge = ref_edge_list.get_and_step();
+ DLIList<Body*> body_list;
+ tmp_edge->bodies( body_list );
+ bodies_to_merge += body_list;
+ }
+
+ bodies_to_merge.uniquify_unordered();
+ }
+
+
+ DLIList<Body*> original_body_list;
+ ref_face->bodies( original_body_list );
+
+ DLIList<Surface*> surf_list( 1 );
+ DLIList<Curve*> curve_list(ref_edge_list.size());
+ DLIList<RefFace*> ref_face_list( 1 );
+ ref_face_list.append( ref_face );
+ GeometryModifyEngine* gme = common_modify_engine( ref_face_list,
+ ref_edge_list,
+ surf_list,
+ curve_list,
+ true);
+ if ( !gme )
+ {
+ PRINT_ERROR("Performing IMPRINT with entities containing geometry from\n"
+ "different modeling engines is not allowed.\n" );
+ return CUBIT_FAILURE;
+ }
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<RefFace*> ref_faces(1);
+ ref_faces.append( ref_face );
+ CubitUndo::save_state_with_cubit_file( ref_faces );
+ }
+
+ DLIList<BodySM*> body_sm_list;
+ for(i=original_body_list.size(); i--;)
+ body_sm_list.append(original_body_list.get_and_step()->get_body_sm_ptr());
+
+ int process_composites = 0;
+ if(contains_composites(original_body_list))
+ process_composites = 1;
+
+ DLIList<TopologyBridge*> tb_list;
+ if(process_composites)
+ {
+ // Turn certain attributes on.
+ do_attribute_setup();
+ // Push virtual attributes down to solid model topology before
+ // doing the imprint.
+ push_vg_attributes_before_modify(body_sm_list);
+ DLIList<TopologyBridge*> tmp_tb_list;
+ CAST_LIST(surf_list, tmp_tb_list, TopologyBridge);
+ // Put "ORIGINAL" attributes on the bodies being imprinted and
+ // the curves as these originally existed.
+ push_named_attributes_to_curves_and_points(tmp_tb_list, "ORIGINAL");
+ CAST_LIST(curve_list, tb_list, TopologyBridge);
+ push_named_attributes_to_curves_and_points(tb_list, "ORIGINAL");
+ push_named_attributes_to_curves_and_points(tb_list, "IMPRINTER");
+ }
+
+ CubitStatus status = CUBIT_FAILURE;
+ DLIList<BodySM*> new_body_list;
+ DLIList<TopologyBridge*> new_tbs, att_tbs;
+ // The bridges doing the imprinting often get split during the process but
+ // because of the way we are making copies, the IMPRINTER attribute doesn't
+ // get propagated to them. temporary_bridges will be filled in with any
+ // additional IMPRINTER bridges we need to consider below when deciding whether to
+ // keep composite attributes.
+ DLIList<TopologyBridge*> temporary_bridges;
+ for(i=surf_list.size(); i>0; i--)
+ {
+ Surface *cur_surf = surf_list.get_and_step();
+ BodySM *new_body_sm = NULL;
+ CubitStatus tmp_status = gme->tolerant_imprint_surface_with_curves(
+ cur_surf, curve_list,
+ temporary_bridges,
+ new_body_sm,
+ &new_tbs, &att_tbs);
+ if(new_body_sm)
+ new_body_list.append(new_body_sm);
+ if(tmp_status == CUBIT_SUCCESS)
+ status = tmp_status;
+ }
+
+ temporary_bridges.uniquify_ordered();
+
+ if( status == CUBIT_FAILURE )
+ {
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
+
+ if(process_composites)
+ {
+ remove_pushed_attributes(new_body_list, original_body_list);
+ do_attribute_cleanup();
+ }
+ return CUBIT_FAILURE;
+ }
+ else
+ {
+ if(process_composites)
+ {
+ // Analyze the results and adjust virtual attributes as necessary.
+ DLIList<TopologyBridge*> tmp_tb_list;
+ CAST_LIST(new_body_list, tmp_tb_list, TopologyBridge);
+ tb_list.merge_unique(tmp_tb_list);
+ // The bridges coming back in temporary_bridges may not have IMPRINTER
+ // attributes on them becuase of the way they were generated below. Make
+ // sure they get IMPRINTER attributes.
+ push_named_attributes_to_curves_and_points(temporary_bridges, "IMPRINTER");
+ tb_list += temporary_bridges;
+ GeometryQueryTool::instance()->ige_attribute_after_imprinting(new_tbs, att_tbs,
+ tb_list, original_body_list);
+
+ while(temporary_bridges.size())
+ delete temporary_bridges.pop();
+
+ // Clean up attributes.
+ remove_imprint_attributes_after_modify(body_sm_list, new_body_list);
+
+ // Restore the virtual geometry.
+ restore_vg_after_modify(new_body_list, original_body_list, gme);
+ remove_pushed_attributes(new_body_list, original_body_list);
+ }
+ }
+
+ DLIList<Body*> result_bodies;
+ status = finish_sm_op( original_body_list, new_body_list, result_bodies );
+
+ if(process_composites)
+ do_attribute_cleanup();
+
+ if( status == CUBIT_FAILURE )
+ {
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
+ return CUBIT_FAILURE;
+ }
+
+ if( merge )
+ MergeTool::instance()->merge_bodies( bodies_to_merge );
+
+ if( result_bodies.size() == 1 )
+ new_body = result_bodies.get();
+ else
+ return CUBIT_FAILURE;
+
+ return status;
+}
+
CubitStatus GeometryModifyTool::tolerant_imprint( DLIList<Body*> &bodies,
DLIList<Body*> &new_bodies, bool merge )
{
@@ -8902,7 +16491,7 @@
//make sure that merge tolerance is not inapproiate for model
int i;
CubitBox bounding_box( CubitVector(0,0,0),
- CubitVector(CUBIT_DBL_MAX,
+ CubitVector(CUBIT_DBL_MAX,
CUBIT_DBL_MAX,
CUBIT_DBL_MAX ) );
for( i=bodies.size(); i--; )
@@ -8910,26 +16499,29 @@
CubitBox tmp_box = bodies.get_and_step()->bounding_box();
if(bounding_box.max_x() == CUBIT_DBL_MAX)
bounding_box = tmp_box;
- else if( tmp_box.diagonal().length_squared() <
+ else if( tmp_box.diagonal().length_squared() <
bounding_box.diagonal().length_squared() )
bounding_box = tmp_box;
}
-
- //get the merge tolerance
+
+ //get the merge tolerance
double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS;
-
- //if the merge tolerance is greater than 1/10th the length of the
+
+ //if the merge tolerance is greater than 1/10th the length of the
//diagonal of the bounding box of the smallest volume, fail!
- double tenth_smallest_bbox = 0.1*(bounding_box.diagonal().length());
- if( tolerance > tenth_smallest_bbox )
+ double tenth_smallest_bbox = 0.1*(bounding_box.diagonal().length());
+ if( tolerance > tenth_smallest_bbox )
{
- PRINT_ERROR("Merge tolerance is set excessively high. Must be lowner than %lf\n",
+ PRINT_ERROR("Merge tolerance is set excessively high. Must be lower than %lf\n",
tenth_smallest_bbox );
PRINT_INFO(" (Merge tolerance must be less than than 1/10th of the diagonal\n"
"of the bounding box of the smallest volume)\n");
return CUBIT_FAILURE;
}
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state_with_cubit_file( bodies );
+
body_sm_list.clean_out();
DLIList<Body*> old_body_list;
old_body_list += bodies;
@@ -8948,40 +16540,56 @@
do_attribute_setup();
push_vg_attributes_before_modify(body_sm_list);
// This must be done after pushing the vg atts because it uses them.
- push_imprint_attributes_before_modify(body_sm_list);
+ DLIList<TopologyBridge*> tb_list;
+ CAST_LIST(body_sm_list, tb_list, TopologyBridge);
+ push_named_attributes_to_curves_and_points(tb_list, "IMPRINTER");
+ push_named_attributes_to_curves_and_points(tb_list, "ORIGINAL");
}
DLIList<BodySM*> new_body_list;
DLIList<TopologyBridge*> new_tbs, att_tbs;
- CubitStatus result = gme->tolerant_imprint( body_sm_list, new_body_list, &new_tbs, &att_tbs ) ;
+ CubitStatus result = gme->tolerant_imprint( body_sm_list, new_body_list, &new_tbs, &att_tbs );
- if(process_composites)
- {
- // Analyze the results and adjust virtual attributes as necessary.
- GeometryQueryTool::instance()->ige_attribute_after_imprinting(new_tbs, att_tbs,
- new_body_list, bodies);
- // Clean up attributes.
- remove_imprint_attributes_after_modify(body_sm_list, new_body_list);
-
- // Restore the virtual geometry.
- restore_vg_after_modify(new_body_list, bodies);
- }
-
if(result == CUBIT_FAILURE)
{
if(process_composites)
+ {
+ remove_pushed_attributes(new_body_list, bodies);
do_attribute_cleanup();
+ }
return result;
}
+ else
+ {
+ if(process_composites)
+ {
+ // Analyze the results and adjust virtual attributes as necessary.
+ DLIList<TopologyBridge*> tb_list;
+ CAST_LIST(new_body_list, tb_list, TopologyBridge);
+ GeometryQueryTool::instance()->ige_attribute_after_imprinting(new_tbs, att_tbs,
+ tb_list, bodies);
+ // Clean up attributes.
+ remove_imprint_attributes_after_modify(body_sm_list, new_body_list);
+
+ // Restore the virtual geometry.
+ restore_vg_after_modify(new_body_list, bodies, gme);
+ remove_pushed_attributes(new_body_list, bodies);
+ }
+ }
+
result = finish_sm_op( bodies, body_sm_list, new_bodies );
if(process_composites)
do_attribute_cleanup();
- if(!result)
+ if(result == CUBIT_FAILURE)
+ {
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
return CUBIT_FAILURE;
+ }
if( merge )
MergeTool::instance()->merge_bodies( bodies );
@@ -9000,6 +16608,9 @@
return CUBIT_FAILURE;
}
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state_with_cubit_file( bodies );
+
CubitStatus status = CUBIT_FAILURE;
DLIList<BodySM*> modified_bodies;
int i;
@@ -9013,11 +16624,600 @@
}
}
- DLIList<Body*> dummy_list;
- if(!finish_sm_op( bodies, modified_bodies, dummy_list))
+ if( status == CUBIT_FAILURE )
+ {
+ PRINT_WARNING("Did not remove any sliver curves\n");
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
return CUBIT_FAILURE;
+ }
+ DLIList<Body*> dummy_list;
+ status = finish_sm_op( bodies, modified_bodies, dummy_list );
+ if( status == CUBIT_FAILURE )
+ {
+ PRINT_WARNING("Did not remove any sliver curves\n");
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
+ return CUBIT_SUCCESS;
+ }
+
return status;
}
+void GeometryModifyTool::split_surface_with_narrow_region(RefFace *face,
+ DLIList<CubitVector> &split_pos1_list,
+ DLIList<CubitVector> &split_pos2_list)
+{
+ int k;
+ if(split_pos1_list.size() > 0)
+ {
+ DLIList<DLIList<CubitVector*>*> vec_lists;
+ DLIList<CubitVector*> pt_list;
+ for(k=split_pos1_list.size(); k--;)
+ {
+ CubitVector split_pos1 = split_pos1_list.get_and_step();
+ CubitVector split_pos2 = split_pos2_list.get_and_step();
+ face->move_to_surface(split_pos1);
+ face->move_to_surface(split_pos2);
+ DLIList<CubitVector*> *vec_list = new DLIList<CubitVector*>;
+ vec_list->append( new CubitVector(split_pos1));
+ vec_list->append( new CubitVector(split_pos2));
+ vec_lists.append( vec_list );
+ }
+ GeometryModifyTool::instance()->split_surface(face,
+ pt_list, vec_lists );
+
+ while( vec_lists.size() )
+ {
+ DLIList<CubitVector*> *vec_list = vec_lists.pop();
+ while( vec_list->size() ) delete vec_list->pop();
+ delete vec_list;
+ }
+ /*
+ while( pt_list.size() )
+ delete( pt_list.pop() );
+ */
+ }
+}
+
+void GeometryModifyTool::fixup_merged_entities( DLIList<int> &merged_surface_ids,
+ DLIList<int> &merged_curve_ids ) const
+{
+ //use ids to find surviving merged entities
+ DLIList<RefFace*> ref_face_list;
+ DLIList<RefEdge*> ref_edge_list;
+
+ int i;
+ //see what merged survived operation
+ for( i=merged_surface_ids.size(); i--; )
+ {
+ int face_id = merged_surface_ids.get_and_step();
+ RefFace *surviving_merged_face = RefEntityFactory::instance()->get_ref_face( face_id );
+ if( surviving_merged_face )
+ ref_face_list.append( surviving_merged_face );
+ }
+
+ //see what merged survived operation
+ for( i=merged_curve_ids.size(); i--; )
+ {
+ int edge_id = merged_curve_ids.get_and_step();
+ RefEdge *surviving_merged_edge = RefEntityFactory::instance()->get_ref_edge( edge_id );
+ if( surviving_merged_edge )
+ ref_edge_list.append( surviving_merged_edge );
+ }
+
+ //fix up merged faces -- some might need to be reversed
+ for(i=ref_face_list.size(); i--; )
+ {
+ RefFace *merged_face = ref_face_list.get_and_step();
+ BasicTopologyEntity *bte = static_cast<BasicTopologyEntity*>(merged_face);
+
+ //get the first bridge of the entity
+ DLIList<TopologyBridge*> face_bridge_list;
+ bte->bridge_manager()->get_bridge_list( face_bridge_list );
+
+ //if there are 2 bridges in the list, it's still merged...do nothing
+ if( face_bridge_list.size() > 1 )
+ continue;
+
+ //get the center of the RefFace
+ CubitVector center = merged_face->center_point();
+
+ //get the normal according to the RefFace
+ CubitVector ref_face_normal = merged_face->normal_at( center );
+
+ //get the normal at the center from the underlying Surface
+ Surface *surface_ptr = CAST_TO( face_bridge_list.get(), Surface );
+ CubitVector surface_normal;
+ surface_ptr->closest_point( center, NULL, &surface_normal );
+
+ //if normals are opposite, flip sense of surface_ptr
+ if( fabs(ref_face_normal.interior_angle( surface_normal ) - 180 ) < 0.1 )
+ merged_face->reverse_normal();
+
+ //One more thing.....if surface is a composite, update the graphics
+ //on the hidden curve...could have been deleted.
+ if ( GeometryQueryTool::instance()->ige_is_composite( surface_ptr ) )
+ merged_face->notify_all_observers( TOPOLOGY_MODIFIED );
+ }
+
+ //fix up merged edges -- some might need to be reversed
+ for(i=ref_edge_list.size(); i--; )
+ {
+ RefEdge *merged_edge = ref_edge_list.get_and_step();
+ BasicTopologyEntity *bte = static_cast<BasicTopologyEntity*>(merged_edge);
+
+ //get the first bridge of the entity
+ DLIList<TopologyBridge*> edge_bridge_list;
+ bte->bridge_manager()->get_bridge_list( edge_bridge_list );
+
+ //get start/end points of the edge
+ CubitVector edge_start_point = merged_edge->start_vertex()->coordinates();
+ CubitVector edge_end_point = merged_edge->end_vertex()->coordinates();
+
+ //get start/end point of the curve
+ edge_bridge_list.reset();
+ Curve *curve_ptr = CAST_TO( edge_bridge_list.get(), Curve);
+ DLIList<Point*> tmp_points;
+ curve_ptr->points( tmp_points );
+ CubitVector curve_start_point = tmp_points.get_and_step()->coordinates();
+ CubitVector curve_end_point = tmp_points.get_and_step()->coordinates();
+
+ //check to see if curve sense needs to be reversed
+ if( edge_start_point.distance_between( curve_start_point ) < GEOMETRY_RESABS &&
+ edge_end_point.distance_between( curve_end_point ) < GEOMETRY_RESABS )
+ {
+ //do nothing...everything is fine
+ continue;
+ }
+ else
+ {
+ if( edge_start_point.distance_between( curve_end_point ) < GEOMETRY_RESABS &&
+ edge_end_point.distance_between( curve_start_point ) < GEOMETRY_RESABS )
+ {
+ //switch sense of ref entity
+ merged_edge->reverse_tangent();
+ }
+ }
+ }
+}
+
+void GeometryModifyTool::get_merged_curve_and_surface_ids(
+ DLIList<Body*> &bodies,
+ DLIList<int> &merged_surface_ids,
+ DLIList<int> &merged_curve_ids ) const
+{
+ int i;
+ for( i=bodies.size(); i--; )
+ {
+ DLIList<RefEntity*> merged_children;
+
+ MergeTool::instance()->contains_merged_children( bodies.get_and_step(),
+ merged_children );
+
+ int j;
+ for( j=merged_children.size(); j--; )
+ {
+ RefEntity *ref_ent = merged_children.get_and_step();
+
+ RefFace *ref_face = CAST_TO( ref_ent, RefFace );
+
+ if( ref_face )
+ merged_surface_ids.append( ref_face->id() );
+ else
+ {
+ RefEdge *ref_edge = CAST_TO( ref_ent, RefEdge );
+
+ if( ref_edge )
+ merged_curve_ids.append( ref_edge->id() );
+ }
+ }
+ }
+}
+
+void GeometryModifyTool::plane_preview(DLIList<Body*>& body_list,
+ const CubitVector &pt1,
+ const CubitVector &pt2,
+ const CubitVector &pt3)
+{
+ CubitPlane plane;
+ if( plane.mk_plane_with_points( pt1, pt2, pt3) == CUBIT_FAILURE)
+ {
+ PRINT_INFO( "Unable to create plane from given information.\n" );
+ return ;
+ }
+
+ CubitBox bounding_box;
+ Body* body_ptr = body_list.get_and_step();
+ bounding_box = body_ptr->bounding_box();
+
+ int i;
+ for( i=1; i<body_list.size(); i++ )
+ {
+ body_ptr = body_list.get_and_step();
+ bounding_box |= body_ptr->bounding_box();
+ }
+
+ int extension_type = 1;
+ double extension = 10; //10%
+ CubitVector p1, p2, p3, p4;
+
+ if( AnalyticGeometryTool::instance()->
+ min_pln_box_int_corners( plane, bounding_box, extension_type,
+ extension, p1, p2, p3, p4 ) == CUBIT_FAILURE )
+ {
+ PRINT_INFO( "Unable to create plane from given information.\n" );
+ return ;
+ }
+
+ GPoint gp[4];
+ gp[0].x=p1.x(); gp[0].y=p1.y(); gp[0].z=p1.z();
+ gp[1].x=p2.x(); gp[1].y=p2.y(); gp[1].z=p2.z();
+ gp[2].x=p3.x(); gp[2].y=p3.y(); gp[2].z=p3.z();
+ gp[3].x=p4.x(); gp[3].y=p4.y(); gp[3].z=p4.z();
+
+ // clear previous previews
+ GfxPreview::clear();
+
+ // Get the color to draw in
+ int color = CUBIT_BLUE;
+ GfxPreview::draw_quad(gp, color);
+ GfxPreview::flush();
+ return;
+}
+
+void GeometryModifyTool::march_path(CubitVector &start_pos,
+ RefFace *start_face,
+ CubitVector &march_dir, // should be normalized
+ double &step_size)
+{
+ double cos_45 = 0.70710678118654752440084436210485;
+ double geo_tol = GeometryQueryTool::instance()->get_sme_resabs_tolerance();
+ CubitVector point_on_surf = start_pos;
+ RefVolume *v = start_face->ref_volume();
+ RefFace *cur_face = start_face;
+ CubitVector norm = cur_face->normal_at(point_on_surf, v);
+ CubitVector sweep_dir = norm;
+
+ RefEdge *snap_edge = NULL;
+ bool snapped_to_edge_last_time = false;
+ bool turned = false;
+ CubitVector old_pos = point_on_surf;
+ while(!turned)
+ {
+ CubitVector new_pos;
+ if(snapped_to_edge_last_time)
+ {
+ // Just set the new position to the position on the
+ // edge. This will force us to jump out without doing
+ // anything and then on the next loop we will start
+ // onto the new face.
+ new_pos = old_pos;
+ snapped_to_edge_last_time = false;
+ continue;
+ }
+ else
+ {
+ // Calculate a new step along the vector.
+ new_pos = old_pos + step_size * march_dir;
+ }
+
+//GfxDebug::draw_point(new_pos, 5);
+//GfxDebug::flush();
+
+ cur_face->get_surface_ptr()->closest_point_trimmed(new_pos, point_on_surf);
+
+//GfxDebug::draw_point(point_on_surf, 6);
+//GfxDebug::flush();
+
+ norm = cur_face->normal_at(point_on_surf, v);
+ if(sweep_dir % norm < cos_45)
+ {
+ turned = true;
+ /*
+GfxDebug::draw_point(old_pos, 3);
+GfxDebug::draw_point(point_on_surf, 3);
+GfxDebug::draw_line(old_pos, point_on_surf, 3);
+GfxDebug::flush();
+*/
+ }
+ else
+ {
+ bool snapping_to_edge = true;
+ CubitVector proj_dir = point_on_surf - new_pos;
+ double proj_dist = proj_dir.length();
+ if(proj_dist < geo_tol)
+ snapping_to_edge = false;
+ else
+ {
+ proj_dir /= proj_dist;
+ double dot = proj_dir % norm;
+ if(dot > .99 || dot < -.99)
+ snapping_to_edge = false;
+ }
+ if(!snapping_to_edge)
+ {
+ snap_edge = NULL;
+GfxDebug::draw_point(old_pos, 3);
+GfxDebug::draw_point(point_on_surf, 3);
+GfxDebug::draw_line(old_pos, point_on_surf, 3);
+GfxDebug::flush();
+ // didn't snap to boundary
+ old_pos = point_on_surf;
+ }
+ else
+ {
+ // probably snapped to the boundary
+ DLIList<RefEdge*> face_edges;
+ RefEdge *best_edge = NULL;
+ cur_face->ref_edges(face_edges);
+ int i;
+ DLIList<RefEdge*> possible_edges;
+ CubitVector closest;
+ for(i=face_edges.size(); i>0; i--)
+ {
+ RefEdge *e = face_edges.get_and_step();
+//GfxDebug::draw_ref_edge(e, 8);
+//GfxDebug::flush();
+ e->closest_point_trimmed(point_on_surf, closest);
+//GfxDebug::draw_point(point_on_surf, 66);
+//GfxDebug::draw_point(closest, 77);
+//GfxDebug::flush();
+ double cur_dist = (closest - point_on_surf).length();
+ if(cur_dist < geo_tol)
+ {
+ possible_edges.append(e);
+ }
+ }
+ if(possible_edges.size() == 1)
+ best_edge = possible_edges.get();
+ else if(possible_edges.size() > 1)
+ {
+ int h;
+ double smallest_dist = CUBIT_DBL_MAX;
+ for(h=possible_edges.size(); h>0; h--)
+ {
+ RefEdge *ce = possible_edges.get_and_step();
+ ce->closest_point_trimmed(old_pos, closest);
+ double cur_dist = (old_pos-closest).length();
+ if(cur_dist < smallest_dist)
+ {
+ smallest_dist = cur_dist;
+ best_edge = ce;
+ }
+ }
+ }
+ if(best_edge)
+ {
+ if(snap_edge && snap_edge == best_edge)
+ {
+GfxDebug::draw_point(old_pos, 3);
+GfxDebug::draw_point(point_on_surf, 3);
+GfxDebug::draw_line(old_pos, point_on_surf, 3);
+GfxDebug::flush();
+ old_pos = point_on_surf;
+ snapped_to_edge_last_time = true;
+ }
+ else
+ {
+ snap_edge = best_edge;
+ cur_face = best_edge->other_face(cur_face, v);
+ CubitVector old_pos_save = old_pos;
+ old_pos = closest;
+ i = 0;
+ snapped_to_edge_last_time = true;
+
+ GeometryModifyEngine *gme = get_engine((TopologyBridge*)best_edge->get_curve_ptr());
+ if(gme)
+ {
+ Point *pt1 = gme->make_Point(old_pos_save);
+ Point *pt2 = gme->make_Point(new_pos);
+ CubitVector const* pt3 = NULL;
+ Curve *crv = gme->make_Curve(STRAIGHT_CURVE_TYPE, pt1, pt2, pt3,CUBIT_FORWARD);
+ if(crv)
+ {
+ CubitVector pos1, pos2;
+ double dist;
+ GeometryQueryTool::instance()->entity_entity_distance(crv, best_edge->get_curve_ptr(), pos1,
+ pos2, dist);
+ GfxDebug::draw_point(pos2, 9);
+ GfxDebug::flush();
+ old_pos = pos2;
+ delete crv;
+ delete pt1;
+ delete pt2;
+GfxDebug::draw_point(old_pos_save, 3);
+GfxDebug::draw_point(pos2, 3);
+GfxDebug::draw_line(old_pos_save, pos2, 3);
+GfxDebug::flush();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // GfxDebug::draw_point(point_on_surf, 4);
+ // GfxDebug::flush();
+}
+
+CubitStatus GeometryModifyTool::stitch( DLIList<Body*> &bodies_to_stitch,
+ DLIList<Body*> &result_list,
+ bool tighten_gaps,
+ double tolerance )
+{
+ if (!okay_to_modify( bodies_to_stitch, "STITCH" ))
+ return CUBIT_FAILURE;
+
+ //get all the BodySMs from 'bodies_to_stitch'
+ int i;
+ for( i=bodies_to_stitch.size(); i--; )
+ {
+ Body *tmp_body = bodies_to_stitch.get_and_step();
+ if( !tmp_body->is_sheet_body() )
+ {
+ PRINT_ERROR("Can't stitch body %d. It's a solid body\n", tmp_body->id() );
+ return CUBIT_FAILURE;
+ }
+ }
+
+ DLIList<TopologyEntity*> entity_list(bodies_to_stitch.size());
+ DLIList<TopologyBridge*> bridge_list(bodies_to_stitch.size());
+ DLIList<BodySM*> bodysm_list(bodies_to_stitch.size());
+ CAST_LIST_TO_PARENT(bodies_to_stitch, entity_list);
+ GeometryModifyEngine *gme = common_modify_engine(entity_list, bridge_list);
+
+ if( entity_list.size() != bridge_list.size() )
+ {
+ PRINT_ERROR("Cannot stitch entities of different geometry engines.\n");
+ return CUBIT_FAILURE;
+ }
+
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state_with_cubit_file( bodies_to_stitch );
+
+ CAST_LIST(bridge_list, bodysm_list, BodySM);
+ DLIList<BodySM*> new_bodies;
+ CubitStatus result = gme->stitch( bodysm_list, new_bodies, tighten_gaps, tolerance );
+
+ if( result == CUBIT_FAILURE && CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
+
+ if (!finish_sm_op(bodies_to_stitch, new_bodies, result_list))
+ {
+ result = CUBIT_FAILURE;
+ CubitUndo::remove_last_undo();
+ }
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( result == CUBIT_SUCCESS )
+ CubitUndo::note_result_bodies( result_list );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
+ return result;
+}
+
+
+
+CubitStatus GeometryModifyTool::discover_topology(RefFace *surf, CubitVector &pos,
+ double &step_size,
+ int num_subdivisions)
+{
+ CubitStatus ret = CUBIT_SUCCESS;
+
+ CubitVector point_on_surf;
+ surf->get_surface_ptr()->closest_point_trimmed(pos, point_on_surf);
+ RefVolume *v = surf->ref_volume();
+ CubitVector norm = surf->normal_at(point_on_surf, v);
+ CubitVector march_dir = norm * CubitVector(1,0,0);
+ if(march_dir.length() < .001)
+ {
+ march_dir = norm * CubitVector(0,1,0);
+ if(march_dir.length() < .001)
+ {
+ march_dir = norm * CubitVector(0,0,1);
+ if(march_dir.length() < .001)
+ {
+ PRINT_ERROR("Couldn't find a good march direction.\n");
+ ret = CUBIT_FAILURE;
+ }
+ }
+ }
+
+ if(ret == CUBIT_SUCCESS)
+ {
+ // Get initial 4 directions.
+ march_dir.normalize();
+ DLIList<CubitVector> march_directions;
+ CubitVector v1 = march_dir;
+ CubitVector v3 = -march_dir;
+ CubitVector v2 = norm*march_dir;
+ CubitVector v4 = -v2;
+ march_directions.append(v1);
+ march_directions.append(v2);
+ march_directions.append(v3);
+ march_directions.append(v4);
+
+ // Now subdivide directions further if requested.
+ int i;
+ // make sure we start at the end to process the all of the original directions correctly
+ march_directions.last();
+ for(i=march_directions.size(); i>0; i--)
+ {
+ CubitVector cur_dir = march_directions.get_and_step();
+ CubitVector next_dir = march_directions.get();
+ subdivide_pie(cur_dir, next_dir, num_subdivisions, march_directions);
+ }
+
+ for(i=march_directions.size(); i>0; i--)
+ {
+ CubitVector cur_dir = march_directions.get_and_step();
+ march_path(point_on_surf, surf, cur_dir, step_size);
+ }
+ }
+
+ return ret;
+}
+
+void GeometryModifyTool::subdivide_pie(CubitVector &dir1, CubitVector &dir2, int num_subdivisions,
+ DLIList<CubitVector> &all_directions)
+{
+ if(num_subdivisions > 0)
+ {
+ CubitVector mid = dir1 + dir2;
+ mid.normalize();
+ all_directions.append(mid);
+ if(num_subdivisions > 1)
+ {
+ subdivide_pie(dir1, mid, num_subdivisions-1, all_directions);
+ subdivide_pie(mid, dir2, num_subdivisions-1, all_directions);
+ }
+ }
+}
+
+//-------------------------------------------------------------------------
+// traverse the body object and calls premodify function on each structure
+//-------------------------------------------------------------------------
+void GeometryModifyTool::body_premodify(Body* body) const
+{
+ // skip if the mesh autodelete is disabled
+ if (!get_mesh_autodelete()) { return; }
+
+ // volumes
+ DLIList<RefVolume*> temp_vols;
+ body->ref_volumes(temp_vols);
+ for (int v = 0; v < temp_vols.size(); v++) {
+ RefVolume* volume = temp_vols.get_and_step();
+ volume->geometry_premodify();
+
+ // faces
+ DLIList<RefFace*> temp_faces;
+ volume->ref_faces(temp_faces);
+ for (int f = 0; f < temp_faces.size(); f++) {
+ RefFace* face_ptr = temp_faces.get_and_step();
+ face_ptr->geometry_premodify();
+
+ //edges
+ DLIList<RefEdge*> temp_edges;
+ face_ptr->ref_edges(temp_edges);
+ for (int e = 0; e < temp_edges.size(); e++) {
+ RefEdge* edge_ptr = temp_edges.get_and_step();
+ edge_ptr->geometry_premodify();
+
+ // vertices
+ DLIList<RefVertex*> temp_vertices;
+ edge_ptr->ref_vertices(temp_vertices);
+ for (int vertices = 0; vertices < temp_vertices.size(); vertices++) {
+ RefVertex* vertex_ptr = temp_vertices.get_and_step();
+ vertex_ptr->geometry_premodify();
+ }
+ }
+ }
+ }
+}
Modified: cgm/branches/cubit/geom/GeometryModifyTool.hpp
===================================================================
--- cgm/branches/cubit/geom/GeometryModifyTool.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/GeometryModifyTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -36,7 +36,6 @@
class RefFace;
class RefVolume;
class RefVertex;
-class RefEdge;
class RefFace;
class RefVolume;
template <class X> class DLIList;
@@ -60,12 +59,14 @@
class GeometryEntity;
+//! Interface class for modifying geometry.
class CUBIT_GEOM_EXPORT GeometryModifyTool
{
+
+ friend class MergeTool;
public :
- static GeometryModifyTool* instance( GeometryModifyEngine* GMEPtr = NULL);
- /**<
+ /*!
* \return GeometryModifyTool* - Pointer to the singleton GeometryModifyTool object
* \arg SMEPtr
* Pointer to a SolidModelingEngine object. The default value
@@ -79,92 +80,102 @@
* Hence, this instance function should specifically be called at
* startup with a valid non-NULL input SMEPtr.
*/
+ static GeometryModifyTool* instance( GeometryModifyEngine* GMEPtr = NULL);
+ static void delete_instance();
+
+ //! \brief Destructor.
~GeometryModifyTool();
- ///< Destructor.
- /**
- <HR><H3>Geometric primitive creation functions</H3>
- */
- Body* sphere( double radius );
- /**< Creates an ACIS sphere and assigns it to a Body $
+ /*! Creates an ACIS sphere and assigns it to a Body $
* {radius} input radius
* Returns the new Body or NULL
*/
-
- Body* brick( double wid, double dep, double hi );
- /**< Creates an ACIS cuboid and assigns it to a Body $
+ //! \brief Creates a sphere.
+ Body* sphere( double radius,
+ int x_shift = 0,
+ int y_shift = 0,
+ int z_shift = 0,
+ double inner_radius = 0,
+ bool delete_side = false );
+
+ /*! Creates an ACIS cuboid and assigns it to a Body $
* {wid, dep, hi} input width, depth, height
* Returns the new Body or NULL
*/
+ //! \brief Creates a brick (cube).
+ Body* brick( double wid, double dep, double hi );
- Body* brick( const CubitVector ¢er,
- const CubitVector axes[3],
- const CubitVector &extension );
- /**< Creates an ACIS cuboid and assigns it to a Body $
+ /*! Creates an ACIS cuboid and assigns it to a Body $
* {center, axes, extension} input center, xyz axes, extension
* (extension vector is 1/2 width, height, depth)
* If one of dimensions is zero a planar sheet should be created.
* Returns the new Body or NULL
*/
+ //! \brief Creates a brick (cube).
+ Body* brick( const CubitVector ¢er,
+ const CubitVector axes[3],
+ const CubitVector &extension );
- Body* prism( double height, int sides, double major, double minor );
- /**< Creates an ACIS prism and assigns it to a Body $
+ /*! Creates an ACIS prism and assigns it to a Body $
* {height, major, minor} input height, major and minor radii. $
* {sides} input number of sides. Must be >= 3.
* Returns the new Body or NULL
*/
+ //! \brief Creates a brick (cube).
+ Body* prism( double height, int sides, double major, double minor );
- Body* pyramid( double height, int sides, double major, double minor,
- double top=0.0 );
- /**< Creates an ACIS pyramid and assigns it to a Body $
+ /*! Creates an ACIS pyramid and assigns it to a Body $
* {height, major, minor} input height, major and minor radii. $
* {sides} input number of sides. Must be >= 3.
* {top} radius at top of pyramid.
* Returns the new Body or NULL
*/
+ //! \brief Creates a pyramid.
+ Body* pyramid( double height, int sides, double major, double minor,
+ double top=0.0 );
- Body* cylinder( double hi, double r1, double r2, double r3 );
- /**< Creates an ACIS frustum and assigns it to a Body $
+ /*! Creates an ACIS frustum and assigns it to a Body $
* {hi} input height $
* {r1} input radius in x-direction at base $
* {r2} input radius in y-direction at base $
* {r3} input radius in x-direction at top
* Returns the new Body or NULL
*/
+ //! \brief Creates a clyinder.
+ Body* cylinder( double hi, double r1, double r2, double r3 );
- Body* torus( double r1, double r2 );
- /**< Creates an ACIS torus and assigns it to a Body $
+ /*! Creates an ACIS torus and assigns it to a Body $
* {r1} input major_radius $
* {r2} input minor_radius
* Returns the new Body or NULL
*/
+ //! \brief Creates a torus.
+ Body* torus( double r1, double r2 );
+ /*! Creates a Body consisting of a planar sheet (no volume)
+ * p1 - 1st corner of the sheet
+ * p2 - 2nd corner of the sheet
+ * p3 - 3rd corner of the sheet
+ * p4 - 4th corner of the sheet
+ */
+ //! \brief Creates a planar surface from using four vertices.
Body* planar_sheet( const CubitVector& p1,
const CubitVector& p2,
const CubitVector& p3,
const CubitVector& p4 );
- /**< Creates a solid body consisting of a planar sheet (no volume)
- * {p1} - 1st corner of the sheet
- * {p2} - 2nd corner of the sheet
- * {p3} - 3rd corner of the sheet
- * {p4} - 4th corner of the sheet
- */
- Body* planar_sheet( const CubitVector ¢er,
- const CubitVector axes[2],
- double width, double height );
- /**< Creates an ACIS body consisting of a planar sheet (no volume)
+ /*! Creates an body consisting of a planar sheet (no volume)
* {center, axes, width, height} - input location, orientation and
* size of sheet
* Returns the new Body or NULL
*/
+ //! \brief Creates a surface from using four vertices.
+ Body* planar_sheet( const CubitVector ¢er,
+ const CubitVector axes[2],
+ double width, double height );
- Body* planar_sheet( const CubitPlane& plane,
- const CubitBox& bounding_box,
- int extension_type = 0,
- double extension = 0.0 );
- /**< Creates an ACIS body consisting of a planar sheet (no volume)
+ /*! Creates an ACIS body consisting of a planar sheet (no volume)
* {plane} - plane it will lie in
* {bounding_box} - 3D bounding box it must expand. Plane will
* have minimal area required to just cut the box.
@@ -172,13 +183,20 @@
* {extension} - distance sheet is to extend outside of bounding box
* Returns the new Body or NULL
*/
+ //! \brief Creates a surface from a plane and bounding box.
+ Body* planar_sheet( const CubitPlane& plane,
+ const CubitBox& bounding_box,
+ int extension_type = 0,
+ double extension = 0.0 );
- /// <HR><H3>Geometry transformation (move, scale, etc.)</H3>
+
+ //! \brief Scale a body non-uniformly. (x,y,z directions)
+ CubitStatus scale ( Body *&entity,
+ const CubitVector& factors,
+ bool check_to_transform = true,
+ bool preview = false);
- CubitStatus scale ( Body *&entity, const CubitVector& factors, bool check_to_transform = true );
-
- Body* copy_body ( Body* body_ptr );
- /**< \return Body*
+ /*! \return Body*
* \return - A pointer to a newly created body.
* \arg body_ptr
* A pointer to a Body which is to used to make copy.
@@ -188,15 +206,25 @@
* created Body are geometrically identical. If the copying
* operation fails for some reason, the function returns NULL.
*/
+ //! \brief Copy a Body.
+ Body* copy_body ( Body* body_ptr );
- RefEntity* copy_refentity( RefEntity *old_entity );
- /**< Takes a RefEntity (RefVertex, RefEdge, or RefFace) and creates a
+ /*! Takes a RefEntity (RefVertex, RefEdge, or RefFace) and creates a
* copy of it using the make_RefXxxxx commands.
*/
+ //! \brief Copy a RefEntity.
+ RefEntity* copy_refentity( RefEntity *old_entity );
- CubitStatus reverse( Body* body_ptr );
- /* Turn body inside-out */
+ //! \brief Turn bodies inside-out
+ CubitStatus reverse( DLIList<Body*> &body_list );
+ //! \brief Reverse the given faces using the solid modeller (flip normals)
+ CubitStatus reverse( DLIList<RefFace*> &ref_face_list );
+
+ /*! Aligns the body that contains my_face to match my_face
+ * with the target face..
+ */
+ //! \brief Align the body, which contains my_face, with the target_face.
CubitStatus align_body( Body *body_ptr,
RefFace *my_face,
RefFace *target_face,
@@ -204,9 +232,8 @@
CubitVector &axis,
CubitVector &target_center,
double &angle );
- /**< aligns the body that contains my_face to match my_face
- * with the target face..
- */
+
+ //! \brief Aligns a surface or vertex of the body with a plane defined an axis defined by 2 points.
CubitStatus align_body( Body *body_ptr,
DLIList<RefEntity*>& ref_ent_list,
CubitVector first_vector,
@@ -216,8 +243,14 @@
CubitVector &axis_of_rot,
double &angle,
double &angle_2 );
- ///< <HR><H3>Geometry modification (booleans, decomposition, etc.)</H3>
+
+ /*! This function accepts two bodies in the first list. The second body
+ in the list is subtracted from and the first and the result is put
+ into the outsideBodies list. intersectBodies list is the result of
+ intersecting the original two bodies in the first list.
+ */
+ //! \brief Intersects and subtracts the two bodies in the list.
CubitStatus chop( DLIList<Body*> &bodies,
DLIList<Body*> &intersectBodies,
DLIList<Body*> &outsideBodies,
@@ -225,38 +258,60 @@
bool keep_old = false,
bool nonreg = false );
+ //! \brief Thickens a sheet body (surface) into a solid body. Can do both directions.
CubitStatus thicken( DLIList<Body*>& bodies,
DLIList<Body*>& new_bodies,
double depth,
bool both = false );
-
+ //! \brief Boolean unite.
CubitStatus unite( DLIList<Body*> &bodies,
DLIList<Body*> &newBodies,
bool keep_old = false );
+ //! \brief Boolean unite.
CubitStatus unite( DLIList<BodySM*> &body_sm_list,
DLIList<BodySM*> &new_body_sm_list,
- bool keep_old = false );
+ bool keep_old = false);
- CubitStatus subtract( DLIList<Body*> &tool_body_list, DLIList<Body*> &from_bodies,
+ //! \brief Boolean subtract.
+ CubitStatus subtract( DLIList<Body*> &tool_body_list,
+ DLIList<Body*> &from_bodies,
DLIList<Body*> &new_bodies,
bool imprint = false,
bool keep_old = false );
- CubitStatus subtract( Body* tool_body, DLIList<Body*> &from_bodies,
+ //! \brief Boolean subtract. Subtracts the tool from all the blanks.
+ CubitStatus subtract( Body* tool_body,
+ DLIList<Body*> &from_bodies,
DLIList<Body*> &new_bodies,
bool imprint = false,
bool keep_old = false );
-
+ /*! \brief Checks for consistent normals across body. Uses surf_ref
+ as a reference surface. All other surfaces in volume should have
+ normal point in likewise direction (in or out of volume).
+ */
+ //! \brief Checks for consistent normals across body.
CubitStatus validate_normals( DLIList<Body*>& bodies,
RefFace *surf_ref,
bool reverse );
+
+ //! \brief Boolean intersect.
+ CubitStatus intersect( Body *tool_body_ptr,
+ DLIList<Body*> &from_bodies,
+ DLIList<Body*> &new_bodies,
+ bool keep_old = false );
- CubitStatus intersect( Body *tool_body_ptr, DLIList<Body*> &from_bodies,
+ //! \brief Boolean intersect.
+ CubitStatus intersect( DLIList<Body*> &from_bodies,
DLIList<Body*> &new_bodies,
bool keep_old = false );
+ /*! Cuts the given bodies with the points defining a plane.
+ * This is mainly used for vis purposes to section a body with
+ * a plane and only retain half of it.
+ */
+ //! \brief Cuts body with plane, throwing away one side.
CubitStatus section( DLIList<Body*> §ion_body_list,
const CubitVector &point_1,
const CubitVector &point_2,
@@ -264,42 +319,102 @@
DLIList<Body*> &new_body_list,
CubitBoolean keep_normal_side,
CubitBoolean keep_old = CUBIT_FALSE );
- /**< Cuts the given bodies with the points defining a plane.
- * This is mainly used for vis purposes to section a body with
- * a plane and only retain half of it.
- */
+ //! \brief Splits periodic curves and surfaces.
CubitStatus split_periodic( Body *body_ptr,
Body *&new_body_ptr );
- /**< calls solid modeling engine to split the periodic body.
- */
+
+ //! \brief Stitches sheet bodies at common edges to form larger sheet body or solid.
+ CubitStatus stitch( DLIList<Body*> &bodies_to_stitch,
+ DLIList<Body*> &result_list,
+ bool tighten_gaps,
+ double tolerance = -1.0 );
- CubitStatus split_surface( RefFace *ref_face_ptr,
- DLIList<CubitVector*> &locations,
- DLIList<DLIList<CubitVector*>*> &vec_lists,
- CubitBoolean preview_flg = CUBIT_FALSE,
- CubitBoolean create_ref_edges_flg = CUBIT_FALSE );
- /**< Split function for simple surface splitting. Temporary Curves are
+ //! \brief Beta function.
+ CubitStatus discover_topology(RefFace *ref_face_ptr,
+ CubitVector &pos,
+ double &step_size,
+ int num_subdivisions);
+
+ //! \brief Beta function.
+ void march_path(CubitVector &start_pos,
+ RefFace *start_face,
+ CubitVector &march_dir,
+ double &step_size);
+
+ //! \brief Beta function.
+ void subdivide_pie(CubitVector &dir1, CubitVector &dir2, int num_subdivisions,
+ DLIList<CubitVector> &all_directions);
+
+ /*! Split function for simple surface splitting. Temporary Curves are
* created on the RefFace and used to split the RefFace. The curves are
* created from the input vec_lists (straight lines, arcs or splines).
* The input locations are the original input locations from the user,
* which are displayed for user reference. If the preview_flg is CUBIT_TRUE,
* the curves are displayed but no splitting occurs. If the preview_flg is
* CUBIT_TRUE and the create_ref_edges_flg is CUBIT_TRUE, then RefEdges are
- * created (but no splitting occurs).
+ * created (but no splitting occurs). The clear_previous_previews flag
+ * controls whether previous previews are cleared from the graphics window
+ * (only applicable if preview_flg is CUBIT_TRUE).
*/
+ //! \brief Splits a surface with a curve defined by positions.
+ CubitStatus split_surface( RefFace *ref_face_ptr,
+ DLIList<CubitVector*> &locations,
+ DLIList<DLIList<CubitVector*>*> &vec_lists,
+ CubitBoolean preview_flg = CUBIT_FALSE,
+ CubitBoolean create_ref_edges_flg = CUBIT_FALSE,
+ CubitBoolean clear_previous_previews = CUBIT_TRUE );
- CubitStatus split_surfaces( DLIList<RefFace*> &ref_face_list,
- int num_segs,
- double fraction,
- double distance,
- RefEdge *from_curve_ptr,
- DLIList<RefVertex*> &corner_vertex_list,
- DLIList<RefVertex*> &through_vertex_list,
- RefEdge *curve_dir_ptr = NULL,
- CubitBoolean preview_flg = CUBIT_FALSE,
- CubitBoolean create_ref_edges_flg = CUBIT_FALSE );
- /**< Splits a surface or connected set of surfaces in one direction.
+
+ /*! Same behavior as other split_surface function only it handles multiple surface
+ and multiple lists of curves.
+ */
+ //! \brief Splits MULTIPLE surfaces with a curves defined by positions.
+ CubitStatus split_surface( DLIList<RefFace*> &ref_face_list,
+ DLIList<CubitVector*> &locations,
+ DLIList<DLIList<DLIList<CubitVector*>*>*> &list_of_vec_lists,
+ CubitBoolean preview_flg = CUBIT_FALSE,
+ CubitBoolean create_ref_edges_flg = CUBIT_FALSE,
+ CubitBoolean clear_previous_previews = CUBIT_TRUE );
+
+ /*! Splits surfaces by extending curves at the end of hardlines across the
+ * surface. Only works on planar surfaces and by extending linear curves.
+ * If specified vertex list is provided, only try to extend curves
+ * attached to those vertices, and error out if unable to perform the
+ * operation using any vertex. If no vertex list is provided, find
+ * appropriate vertices automatically, and limit the split to gaps less
+ * than or equal to the specified "split surface extend gap threshold".
+ * {ref_face_list} - list of connected surfaces to split
+ * {ref_vertex_list} - (OPTIONAL) - vertices to extend from. Function will
+ * error out if unable to extend from any vertex. If
+ * not supplied, function will automatically find
+ * valid vertices to extend from on the surfaces (AUTO
+ * mode), and will limit the split to gaps less than
+ * or equal to the specified extend gap threshold (see
+ * setting below).
+ * {preview_flg} - routine only displays graphics preview of splits
+ * {create_ref_edges_flg} - valid only if preview_flg=CUBIT_TRUE. If
+ * CUBIT_TRUE, create RefEdges *instead* of
+ * splitting.
+ * Note: this function uses SplitSurfaceTool. Three other settings can be
+ * specified that control this function. They are (static):
+ * SplitSurfaceTool::set_extend_gap_threshold - for AUTO mode,
+ * only split the surface if distance is less than or equal to
+ * this value.
+ * SplitSurfaceTool::set_extend_tolerance - snaps to vertices along
+ * curves within this tolerance so as to avoid creating short
+ * curves when splitting surfaces.
+ * SplitSurfaceTool:set_extend_normal - if TRUE, if a projection
+ * normal to the curve is less distance than a projection in the
+ * direction of the curve, use the normal projection instead.
+ */
+ //! \brief Splits surfaces by extending curves at the end of hardlines across the surface.
+ CubitStatus split_surfaces_extend( DLIList<RefFace*> &ref_face_list,
+ DLIList<RefVertex*> &ref_vertex_list,
+ CubitBoolean preview_flg = CUBIT_FALSE,
+ CubitBoolean create_ref_edges_flg = CUBIT_FALSE );
+
+ /*! Splits a surface or connected set of surfaces in one direction.
* Particularly useful for splitting fillets to prepare the model
* for sweeping.
* {ref_face_list} - list of connected surfaces to split
@@ -354,24 +469,26 @@
* below this becomes the triangle point (if sideAngleThreshold
* criteria is also met)
*/
+ //! \brief Splits a surface or connected set of surfaces in one direction.
+ CubitStatus split_surfaces( DLIList<RefFace*> &ref_face_list,
+ int num_segs,
+ double fraction,
+ double distance,
+ RefEdge *from_curve_ptr,
+ DLIList<RefVertex*> &corner_vertex_list,
+ DLIList<RefVertex*> &through_vertex_list,
+ RefEdge *curve_dir_ptr = NULL,
+ CubitBoolean preview_flg = CUBIT_FALSE,
+ CubitBoolean create_ref_edges_flg = CUBIT_FALSE );
- CubitStatus split_surfaces_offset(
- DLIList<RefFace*> &ref_face_list,
- DLIList<RefEdge*> &edge_list,
- int num_segs,
- double distance,
- CubitBoolean partition_flg = CUBIT_FALSE,
- CubitBoolean blunt_flg = CUBIT_FALSE,
- CubitBoolean preview_flg = CUBIT_FALSE,
- CubitBoolean create_ref_edges_flg = CUBIT_FALSE);
- /**< Splits a surface a specified distance from a curve.
+ /*! Splits surfaces a specified distance from curves.
* {ref_face_list} - list of surfaces to split
* {edge_list} - list of curves to offset from
* {num_segs} - number of segments to create (i.e, 2 segments
* means to split using two offset curves).
* {distance} - distance to offset
* {partition_flg} - (OPTIONAL) creates partitions of the offset curves. This typically provides
- * \surfaces easily map meshed
+ * surfaces easily map meshed
* {blunt_flg} - (OPTIONAL) if true the endings of the input curve graph are right angles
* instead of arcs
* {preview_flg} - (OPTIONAL) user specifies forced vertices for
@@ -380,40 +497,73 @@
* {create_ref_edges_flg} - (OPTIONAL) Create curves instead of splitting surfaces
* Requires the preview flag
*/
+ //! \brief Splits surfaces a specified distance from curves.
+ CubitStatus split_surfaces_offset(
+ DLIList<RefFace*> &ref_face_list,
+ DLIList<RefEdge*> &edge_list,
+ int num_segs,
+ double distance,
+ CubitBoolean partition_flg = CUBIT_FALSE,
+ CubitBoolean blunt_flg = CUBIT_FALSE,
+ CubitBoolean preview_flg = CUBIT_FALSE,
+ CubitBoolean create_ref_edges_flg = CUBIT_FALSE);
- CubitStatus webcut_with_cylinder( DLIList<Body*>& webcut_body_list,
- double radius,
- const CubitVector &axis,
- const CubitVector& center,
- DLIList<Body*> &results_list,
- CubitBoolean imprint = CUBIT_FALSE,
- CubitBoolean merge = CUBIT_FALSE );
- /**< Webcuts the bodies in the list with a cutting cylinder.
+ /*! Automatically create a midsurface from a volume.
+ * {body_list_in} - list of bodies to midsurface
+ * {body_list_out} - resulting midsurfaces
+ * {lower_tol} - lower tolerance for finding surface pairs
+ * {upper_tol} - upper tolerance for finding surface pairs
+ * {preview} - preview midsurfaces
+ */
+ //! \brief Create a midsurface from a volume.
+ CubitStatus auto_mid_surface(
+ DLIList<Body*> &body_list_in,
+ DLIList<Body*> &body_list_out,
+ DLIList<Body*> &old_bodies_midsurfaced,
+ DLIList<double> &thickness_list,
+ double lower_tol,
+ double upper_tol,
+ CubitBoolean delete_midsurfaced,
+ CubitBoolean preview);
+ /** Automatically create a midsurface from a volume.
+ * {body_list_in} - list of bodies to midsurface
+ * {body_list_out} - resulting midsurfaces
+ * {thickness_list} - list of matching thickness values for the body out list
+ * {lower_tol} - lower tolerance for finding surface pairs
+ * {upper_tol} - upper tolerance for finding surface pairs
+ * {preview} - preview midsurfaces
+ */
+
+ /*! Webcuts the bodies in the list with a cutting cylinder.
* The cylinder is created by the given parameters. This
* is done in the solid modeling engine to reduce the impact
* on body ids.
*/
+ //! \brief Webcuts bodies with a cylinder.
+ CubitStatus webcut_with_cylinder( DLIList<Body*>& webcut_body_list,
+ double radius,
+ const CubitVector &axis,
+ const CubitVector& center,
+ DLIList<Body*> &results_list,
+ DLIList<Body*> &neighboring_bodies,
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean merge = CUBIT_FALSE ,
+ CubitBoolean preview = CUBIT_FALSE);
#ifdef CAT
CubitStatus webcut_across_translate( DLIList<Body*>& body_list,
RefFace* plane_surf1,
RefFace* plane_surf2,
DLIList<Body*>& results_list,
- CubitBoolean imprint = CUBIT_FALSE,
- CubitBoolean merge = CUBIT_FALSE);
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean merge = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE);
/**< Webcuts with a flat plate to make a body suitable for single-single
* sweeping. Only experimental at this point.
*/
#endif
- CubitStatus webcut_with_brick( DLIList<Body*>& webcut_body_list,
- const CubitVector ¢er,
- const CubitVector axes[3],
- const CubitVector &extension,
- DLIList<Body*> &results_list,
- CubitBoolean imprint = CUBIT_FALSE,
- CubitBoolean merge = CUBIT_FALSE );
- /**< Webcuts the bodies in the list with a cutting brick.
+ /*! Webcuts the bodies in the list with a cutting brick.
* The brick is created by the given parameters - center of
* brick, xyz axes, and extension. Extension is 1/2 width,
* height and depth. If one of the brick dimensions is zero
@@ -421,29 +571,37 @@
* planar_sheet is called). Brick creation is done in the
* solid modeling engine to reduce the impact on body ids.
*/
+ //! \brief Webcuts bodies with a brick (cube).
+ CubitStatus webcut_with_brick( DLIList<Body*>& webcut_body_list,
+ const CubitVector ¢er,
+ const CubitVector axes[3],
+ const CubitVector &extension,
+ DLIList<Body*> &results_list,
+ DLIList<Body*> &neighbor_list,
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean merge = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE);
+
+ /*! Webcuts the bodies in the list with a cutting planar sheet.
+ * The sheet is created by the given parameters - center of
+ * sheet, xy axes, and width and height. Sheet creation is done
+ * in the solid modeling engine to reduce the impact on body ids.
+ */
+ //! \brief Webcuts bodies with a planar sheet.
CubitStatus webcut_with_planar_sheet( DLIList<Body*>& webcut_body_list,
const CubitVector ¢er,
const CubitVector axes[2],
double width,
double height,
DLIList<Body*> &results_list,
- CubitBoolean imprint = CUBIT_FALSE,
- CubitBoolean merge = CUBIT_FALSE );
- /**< Webcuts the bodies in the list with a cutting planar sheet.
- * The sheet is created by the given parameters - center of
- * sheet, xy axes, and width and height. Sheet creation is done
- * in the solid modeling engine to reduce the impact on body ids.
- */
+ DLIList<Body*> &neighbor_list,
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean merge = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE);
- CubitStatus webcut_with_plane( DLIList<Body*>& webcut_body_list,
- const CubitVector &vector1,
- const CubitVector &vector2,
- const CubitVector &vector3,
- DLIList<Body*> &results_list,
- CubitBoolean imprint = CUBIT_FALSE,
- CubitBoolean merge = CUBIT_FALSE ) ;
- /**< \return int
+
+ /*! \return int
* \return - Number of bodies that were webcut ( >= 0 )
* \arg webcut_body_list
* The list of bodies to be webcut
@@ -460,13 +618,18 @@
* The newly created bodies are merged and imprinted depeding on
* the respective flags.
*/
+ //! \brief Webcuts bodies with a plane.
+ CubitStatus webcut_with_plane( DLIList<Body*>& webcut_body_list,
+ const CubitVector &vector1,
+ const CubitVector &vector2,
+ const CubitVector &vector3,
+ DLIList<Body*> &results_list,
+ DLIList<Body*> &neighbor_list,
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean merge = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE) ;
- CubitStatus webcut_with_surface( DLIList<Body*>& webcut_body_list,
- RefFace* refFace,
- DLIList<Body*>& results_list,
- CubitBoolean imprint = CUBIT_FALSE,
- CubitBoolean merge = CUBIT_FALSE );
- /**< \return int
+ /*! \return int
* \return - Number of bodies that were webcut ( >= 0 )
* \arg webcut_body_list
* The list of bodies to be webcut
@@ -485,12 +648,16 @@
* merged and imprinted depeding on the respective flags.
* It returns the number of bodies that were webcut.
*/
+ //! \brief Webcuts bodies with a surface -- must be planar.
+ CubitStatus webcut_with_surface( DLIList<Body*>& webcut_body_list,
+ RefFace* refFace,
+ DLIList<Body*>& results_list,
+ DLIList<Body*> &neighbor_list,
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean merge = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE);
- CubitStatus webcut_with_curve_loop( DLIList<Body*>& webcut_body_list,
- DLIList<RefEdge*>& refedge_list,
- DLIList<Body*>& results_list,
- CubitBoolean imprint = CUBIT_FALSE );
- /**< \return int
+ /*! \return int
* \return - Number of bodies that were webcut ( >= 0 )
* \arg webcut_body_list
* The list of bodies to be webcut
@@ -509,23 +676,30 @@
* are merged and imprinted depending on the respective flags.
* It returns the number of bodies that were webcut.
*/
+ //! \brief Webcuts bodies with a surface defined by a curve loop.
+ CubitStatus webcut_with_curve_loop( DLIList<Body*>& webcut_body_list,
+ DLIList<RefEdge*>& refedge_list,
+ DLIList<Body*>& results_list,
+ DLIList<Body*> &neighbor_list,
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean merge = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE);
- CubitStatus webcut_with_sheet( DLIList<Body*>& webcut_body_list,
- Body *sheet_body,
- DLIList<Body*> &new_bodies,
- CubitBoolean imprint = CUBIT_FALSE);
- /**< calls geometric modeling engine to webcut the body using
+ /*! Webcut the bodies using
* the surface as the cutting tool.
* This is the real webcut with surface. The others are
* just for planes... The sheet body is a body with 0 volume.
*/
+ //! \brief Webcut bodies using a surface, need to be planar.
+ CubitStatus webcut_with_sheet( DLIList<Body*>& webcut_body_list,
+ Body *sheet_body,
+ DLIList<Body*> &new_bodies,
+ DLIList<Body*> &neighbor_list,
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean merge = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE);
- CubitStatus webcut_with_body( DLIList<Body*>& webcut_body_list,
- Body* body,
- DLIList<Body*>& results_list,
- CubitBoolean imprint = CUBIT_FALSE,
- CubitBoolean merge = CUBIT_FALSE );
- /**< \return int
+ /*! \return int
* \return - Number of bodies that were webcut ( >= 0 )
* \arg webcut_body_list
* The list of bodies to be webcut
@@ -542,17 +716,29 @@
* The newly created bodies are merged and imprinted depeding on
* the respective flags.
*/
+ //! \brief Webcuts bodies with a tool body.
+ CubitStatus webcut_with_body( DLIList<Body*>& webcut_body_list,
+ Body* body,
+ DLIList<Body*>& results_list,
+ DLIList<Body*> &neighbor_list,
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean merge = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE);
- CubitStatus webcut_with_extended_surf( DLIList<Body*> &webcut_body_list,
- RefFace *face_to_extend,
- DLIList<Body*> &new_bodies,
- int &num_cut,
- CubitBoolean imprint = CUBIT_FALSE);
- /**< calls geometric modeling engine to create a face extended
- * from the given refFace and then webcut the body using the
- * sheet generated.
+ /*! Create a sheet extended from the tool surfaces
+ * and then uses it to webcut the bodies.
*/
-
+ //! \brief Webcuts bodies by with an extended surface(s).
+ CubitStatus webcut_with_extended_sheet( DLIList<Body*> &webcut_body_list,
+ DLIList<RefFace*> &ref_face_list,
+ DLIList<Body*> &new_bodies,
+ DLIList<Body*> &neighbor_list,
+ int &num_cut,
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean merge = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE);
+
+ //! \brief Webcuts bodies with a tool solid created by rotating surfaces about an axis.
CubitStatus webcut_with_sweep_surfaces_rotated(
DLIList<Body*> &webcut_body_list,
DLIList<RefFace*> &tool_faces,
@@ -562,9 +748,12 @@
RefFace* stop_surf,
bool up_to_next,
DLIList<Body*> &new_bodies,
- CubitBoolean imprint = false,
- CubitBoolean merge = false );
+ DLIList<Body*> &neighbor_list,
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean merge = false,
+ CubitBoolean preview = false);
+ //! \brief Webcuts bodies with a tool surface created by rotating curves about an axis.
CubitStatus webcut_with_sweep_curves_rotated(
DLIList<Body*> &webcut_body_list,
DLIList<RefEdge*> &tool_curves,
@@ -573,9 +762,12 @@
double angle,
RefFace* stop_surf,
DLIList<Body*> &new_bodies,
- CubitBoolean imprint = false,
- CubitBoolean merge = false );
+ DLIList<Body*> &neighbor_list,
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean merge = false,
+ CubitBoolean preview = false);
+ //! \brief Webcuts bodies with a tool solid created by sweeping surfaces along a vector.
CubitStatus webcut_with_sweep_surfaces(
DLIList<Body*> &webcut_body_list,
DLIList<RefFace*> &tool_faces,
@@ -587,9 +779,12 @@
RefFace *stop_surf,
RefEdge* edge_to_sweep_along,
DLIList<Body*> &new_bodies,
- CubitBoolean imprint = false,
- CubitBoolean merge = false );
+ DLIList<Body*> &neighbor_list,
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean merge = false,
+ CubitBoolean preview = false);
+ //! \brief Webcuts bodies with a tool surface created by sweeping curves along a vector.
CubitStatus webcut_with_sweep_curves(
DLIList<Body*> &webcut_body_list,
DLIList<RefEdge*> &tool_curves,
@@ -598,49 +793,57 @@
RefFace *stop_surf,
RefEdge* edge_to_sweep_along,
DLIList<Body*> &new_bodies,
- CubitBoolean imprint = false,
- CubitBoolean merge = false );
+ DLIList<Body*> &neighbor_list,
+ ImprintType imprint_type = NO_IMPRINT,
+ CubitBoolean merge = false,
+ CubitBoolean preview = false);
+
+ //! \brief Removes small topology; i.e, curves and surfaces.
+ CubitStatus remove_topology( DLIList<RefEdge*> &ref_edge_list,
+ DLIList<RefFace*> &ref_face_list, double backoff_distance,
+ double small_curve_size, DLIList<Body*> &new_body_list,
+ CubitBoolean propagate,
+ CubitBoolean preview);
+ /*! Creates curves offset from a chain of curves. The offset direction is
+ * only used if there is one linear curve. Otherwise, the offset direction
+ * 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.
+ */
+ //! \brief Creates curves offset from a chain of curves. The offset direction is
CubitStatus offset_curves( DLIList<RefEdge*>& ref_edge_list,
double offset_distance,
const CubitVector& offset_direction,
int gap_type = 1 );
- /**< Creates curves offset from a chain of curves. The offset direction is
- * only used if there is one linear curve. Otherwise, the offset direction
- * 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 trim_curve( RefEdge* trim_curve,
- const CubitVector& trim_vector,
- const CubitVector& keep_vector );
- /**< Trims or extends a curve, up to the trim_vector. If trimming, the
+ /*! Trims or extends a curve, up to the trim_vector. If trimming, the
* keep_vector determines which side of the curve to keep. If the curve
* is not free, the curve is automatically copied before trimming (so
* a new curve results).
*/
+ //! \brief Trims or extends a curve, up to the trim_vector. If trimming, the
+ CubitStatus trim_curve( RefEdge* trim_curve,
+ const CubitVector& trim_vector,
+ const CubitVector& keep_vector );
- ///< <HR><H3>Topology modification (imprint, regularize, etc.)</H3>
-
+ //! \brief Imprints a group of bodies with one another.
CubitStatus imprint( DLIList<Body*> &from_body_list,
DLIList<Body*> &new_body_list,
CubitBoolean keep_old = CUBIT_FALSE );
+
+ /*! Imprints a list of Bodies with a list of RefEdges. Useful for
+ * splitting surfaces. If edge pierces a surface a hardpoint will
+ * result at the pierce location. Interface is free of ACIS but
+ * currently only works if all entities are ACIS entities.
+ */
+ //! \brief Imprints a list of Bodies with a list of RefEdges. Useful for
CubitStatus imprint( DLIList<Body*> &body_list,
DLIList<RefEdge*> &ref_edge_list,
DLIList<Body*>& new_body_list,
CubitBoolean keep_old_body = CUBIT_FALSE,
CubitBoolean show_messages = CUBIT_TRUE );
- /**< Imprints a list of Bodies with a list of RefEdges. Useful for
- * splitting surfaces. If edge pierces a surface a hardpoint will
- * result at the pierce location. Interface is free of ACIS but
- * currently only works if all entities are ACIS entities.
- */
- CubitStatus imprint( DLIList<RefFace*> &ref_face_list,
- DLIList<RefEdge*> &ref_edge_list,
- DLIList<Body*>& new_body_list,
- CubitBoolean keep_old_body = CUBIT_FALSE );
- /**< Imprints a list of RefFaces with a list of RefEdges. This is
+ /*! Imprints a list of RefFaces with a list of RefEdges. This is
* useful if the user has a curve which spans several surfaces on
* a body and only wants to imprint to selected surfaces. Algorithm
* does not support imprinting to free surfaces. This method
@@ -648,11 +851,12 @@
* body. Interface is free of ACIS but currently only works if all
* entities are ACIS entities.
*/
+ //! Imprints a list of RefFaces with a list of RefEdges. This is
+ CubitStatus imprint( DLIList<RefFace*> &ref_face_list,
+ DLIList<RefEdge*> &ref_edge_list,
+ DLIList<Body*>& new_body_list,
+ CubitBoolean keep_old_body = CUBIT_FALSE );
- CubitStatus imprint( DLIList<Surface*> &surface_list,
- DLIList<DLIList<Curve*>*> &curve_lists_list,
- Body*& new_body,
- CubitBoolean keep_old_body = CUBIT_FALSE );
/**< 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
@@ -660,15 +864,23 @@
* Also, the Curves need not be RefEntities.
* All input surfaces must be from the same body however.
*/
+ //! \brief Imprints a list of Surfaces with list of Curves, sorted per
+ CubitStatus imprint( DLIList<Surface*> &surface_list,
+ DLIList<DLIList<Curve*>*> &curve_lists_list,
+ Body*& new_body,
+ CubitBoolean keep_old_body = CUBIT_FALSE,
+ CubitBoolean expand = CUBIT_TRUE);
+ /*! Imprints a list of bodies to a list of locations. Useful for
+ * splitting curves and creating hardpoints on surfaces. Interface
+ * is free of ACIS but currently only works if bodies are ACIS bodies.
+ */
+ //! \brief Imprints a list of bodies to a list of locations.
CubitStatus imprint( DLIList<Body*> &body_list,
DLIList<CubitVector*> &vector_list,
DLIList<Body*>& new_body_list,
- CubitBoolean keep_old_body = CUBIT_FALSE );
- /**< Imprints a list of bodies to a list of locations. Useful for
- * splitting curves and creating hardpoints on surfaces. Interface
- * is free of ACIS but currently only works if bodies are ACIS bodies.
- */
+ CubitBoolean keep_old_body = CUBIT_FALSE,
+ CubitBoolean merge = CUBIT_FALSE );
//HEADER- Sweep-related functions. All of these are implemented
//HEADER- only for RefEntities whose underlying geometry is
@@ -676,91 +888,153 @@
//HEADER- itself is free of ACIS.
+ //! \brief Imprints a list of RefFaces with a list of projected RefEdges.
CubitStatus imprint_projected_edges( DLIList<RefFace*> &ref_face_list,
DLIList<RefEdge*> &ref_edge_list,
DLIList<Body*>& new_body_list,
CubitBoolean keep_old_body,
CubitBoolean keep_free_edges );
- //- Imprints a list of RefFaces with a list of projected RefEdges.
+ //! \brief Imprints a list of Bodies with a list of RefEdges which are projected
+ //! to a list of RefFaces
CubitStatus imprint_projected_edges( DLIList<RefFace*> &ref_face_list,
DLIList<Body*> &body_list,
DLIList<RefEdge*> &ref_edge_list,
DLIList<Body*>& new_body_list,
CubitBoolean keep_old_body,
CubitBoolean keep_free_edges );
- //- Imprints a list of Bodies with a list of RefEdges which are projected
- //- to a list of RefFaces
+ //! \brief Tolerantly imprintings a list of curves on a list of surfaces.
+ //! Should be used when you have sloppy/out-of-tolerance geometry.
+ CubitStatus tolerant_imprint( DLIList<RefFace*> &ref_faces,
+ DLIList<RefEdge*> &ref_edge_list,
+ DLIList<Body*> &new_bodies,
+ bool merge = false );
+
+ //! \brief Tolerantly imprintings a list of curves onto a single surface.
+ //! Should be used when you have sloppy/out-of-tolerance geometry.
+ CubitStatus tolerant_imprint( RefFace *ref_face,
+ DLIList<RefEdge*> &ref_edge_list,
+ Body *&new_body, bool merge = false );
+
+ //! \brief Imprints bodies onto one another. Should be used when you have sloppy/out-
+ //! of-tolerance geometry.
CubitStatus tolerant_imprint( DLIList<Body*> &bodies, DLIList<Body*> &new_bodies,
bool merge = false );
- //imprints bodies onto one another. Should be used when you have sloppy/out-
- //of-tolerance geometry.
+ //! \brief Projects list RefEdges onto a list of RefFaces.
CubitStatus project_edges( DLIList<RefFace*> &ref_face_list,
DLIList<RefEdge*> &ref_edge_list_in,
- DLIList<RefEdge*> &ref_edge_list_new );
- //- Projects list RefEdges to a list of RefFaces
+ DLIList<RefEdge*> &ref_edge_list_new,
+ CubitBoolean trim_projected = CUBIT_FALSE);
+ //! \brief Removes all unnessesary faces, curves, vertices from a body.
CubitStatus regularize_body( Body *body_ptr, Body *&new_body );
- /**< Removes all unnessesary faces, curves, vertices and associated
- * data from a body.
- */
+ //! \brief Removes all unnessesary faces, curves, vertices and associated
+ //! data from a refentity.
CubitStatus regularize_refentity( RefEntity *old_entity_ptr,
Body *&new_body_ptr);
- //- Removes all unnessesary faces, curves, vertices and associated
- // data from a refentity.
+
+ //! \brief Tests if a RefEntity can have any unncessary child entities removed,
+ //! or simplified away.
+ CubitStatus test_regularize_refentity( RefEntity *old_entity_ptr);
+ CubitStatus split_free_curve( RefEdge *ref_edge,
+ CubitVector &split_location );
+
+ //! \brief Separates multi-volume bodies into single-volume bodies.
CubitStatus split_body( Body *body_ptr,
DLIList<Body*> &new_bodies ) const;
- /**< calls solid modeling engine to split the body.
+
+ /*! Separates surfaces from sheet bodies into separate bodies. Connected
+ * surfaces will remain connected but be placed in a new body.
*/
+ //! \brief Separates surfaces from sheet bodies into separate bodies. Connected
+ CubitStatus separate_surfaces( DLIList<RefFace*> &ref_face_list,
+ DLIList<Body*> &new_bodies );
+
///< <HR><H3>GeometryModifyTool options and settings</H3>
-
+
+ //! \brief Sets group imprint flag.
static void set_group_imprint(CubitBoolean flag) {groupImprint = flag;}
+ //! \brief Gets group imprint flag.
static CubitBoolean get_group_imprint() {return groupImprint;}
- ///< get/set minIds flag
+ //! \brief Sets all edges imprint flag.
static void set_all_edges_imprint( CubitBoolean flag );
+ //! \brief Gets all edges imprint flag.
static CubitBoolean get_all_edges_imprint();
- /**< sets/gets the allEdgesImprint flag.
- */
+ //! \brief Gets boolean regularize flag.
static void boolean_regularize( CubitBoolean flag );
+ //! \brief Sets boolean regularize flag.
static CubitBoolean boolean_regularize();
- /**< sets/gets the booleanRegularize flag.
- */
+ //! \brief Gets unite mixed models flag.
+ static CubitBoolean unite_mixed_models();
+ //! \brief Sets unite mixed models flag.
+ static void unite_mixed_models( CubitBoolean flag );
+ //! \brief Gets new ids flag.
+ static CubitBoolean get_new_ids() {return newIds;}
+ //! \brief Sets new ids flag.
static void set_new_ids(CubitBoolean flag) {newIds = flag;}
- static CubitBoolean get_new_ids() {return newIds;}
- /// get/set minIds flag
- static void set_old_names(CubitBoolean flag)
- { oldNames = flag; }
- static CubitBoolean get_old_names()
- { return oldNames; }
+ //! \brief Gets old names flag.
+ static CubitBoolean get_old_names() { return oldNames; }
+ //! \brief Sets old names flag.
+ static void set_old_names(CubitBoolean flag) { oldNames = flag; }
+ //! \brief Gets mesh autodelete flag.
+ static CubitBoolean get_mesh_autodelete() {return meshAutodelete;}
+ //! \brief Sets mesh autodelete flag.
+ static void set_mesh_autodelete(CubitBoolean flag) {meshAutodelete = flag;}
+
+ //! \brief Gets mesh autodelete-remesh flag.
+ static CubitBoolean is_mesh_autodelete_remesh() {return meshAutodeleteRemesh;}
+ //! \brief Sets mesh autodelete-remesh flag.
+ static void set_mesh_autodelete_remesh(CubitBoolean flag) {meshAutodeleteRemesh = flag;}
+
+ //! \brief Initializes all the settings in GeometryModifyTool to defaults
static void initialize_settings();
- static CubitStatus prepare_for_copy( RefEntity *ref_ents,
- TopologyBridge *&top_bridge );
+ #ifdef PROE
+ CubitStatus prepare_for_topology_update( BodySM* old_bodysm );
- static CubitStatus finish_copy( TopologyBridge *&new_bridge,
- TopologyBridge *old_bridge );
+ CubitStatus finish_topology_update( BodySM* new_bodysm,
+ Body* old_body );
+ #endif
- static CubitStatus clean_up_from_copy_failure( TopologyBridge *old_bridge );
+ //! \brief Gets the entity being copied, if any.
+ static RefEntity* get_copy_entity() { return copyingEntity; }
- static RefEntity* get_copy_entity() { return copyingEntity; }
+ //! \brief Sets the entity being copied.
static void set_copy_entity( RefEntity *ent) { copyingEntity = ent; }
+
+ double get_resultant_angle_score(RefFace *narrow_face,
+ RefFace *other_face,
+ RefEdge *common_edge);
+ double get_neighbor_type_score(RefEdge *common_edge,
+ RefFace *other_face,
+ double small_curve_size,
+ int &neighbor_is_narrow_or_small);
+
+ double get_dihedral_angle_score(RefFace *f1, RefFace *f2,
+ RefEdge *common_edge);
+
+ double get_edge_type_score(RefEdge *common_edge, double small_curve_size);
+ double get_diff_from_multiple_of_90(double angle);
+ void split_surface_with_narrow_region(RefFace *face,
+ DLIList<CubitVector> &split_pos1_list,
+ DLIList<CubitVector> &split_pos2_list);
+
///< <HR><H3>Topology/geometry creation functions</H3>
- RefVertex* make_RefVertex(CubitVector const& point, int color = -1) const ;
- /**< \return RefVertex*
+ /*! \return RefVertex*
* \return - A pointer to a newly created RefVertex
* \arg ref_vertex_type
* The type of the RefVertex
@@ -773,15 +1047,14 @@
* Allows the color to define during creation
* defaults to -1 or CUBIT_DEFAULT_COLOR
*/
+ //! \brief Creates a point from an x,y,z location
+ RefVertex* make_RefVertex(CubitVector const& point, int color = -1) const;
+ RefVertex* make_RefVertex( RefVertex *vertex ) const;
+ //! \brief Creates a sheet body from a surface.
Body *make_Body(Surface *surface) const;
- RefEdge* make_RefEdge( GeometryType ref_edge_type,
- RefVertex *ref_vertex_1,
- RefVertex *ref_vertex_2,
- DLIList<CubitVector*>& vector_list,
- RefFace* reffaca_ptr = NULL ) const ;
- /**< \return RefEdge*
+ /*! \return RefEdge*
* \return - A pointer to a newly created RefEdge
* \arg ref_edge_type
* The type of the RefEdge
@@ -800,12 +1073,14 @@
* is created. If the input refface_ptr is not NULL, the points are
* first moved to the surface before interpolation.
*/
+ //! \brief Creates a curve from two or more points.
+ RefEdge* make_RefEdge( GeometryType ref_edge_type,
+ RefVertex *ref_vertex_1,
+ RefVertex *ref_vertex_2,
+ DLIList<CubitVector*>& vector_list,
+ RefFace* reffaca_ptr = NULL ) const ;
- RefEdge* make_RefEdge( RefVertex *ref_vertex_1,
- RefVertex *ref_vertex_2,
- RefFace* ref_face_ptr,
- RefVertex const* ref_vertex_3 = NULL ) const ;
- /**< \return RefEdge*
+ /*! \return RefEdge*
* \return - A pointer to a newly created RefEdge
* \arg ref_edge_type
* The type of the RefEdge
@@ -819,21 +1094,22 @@
* line along the surface. In periodic surfaces, a third point may
* be used to create the give the correct direction.
*/
-
- RefEdge* make_RefEdge(RefEdge *ref_edge, bool copy_attribs = true) const;
- /**< Give a certain ref edge, create a new one.
+ //! \brief Creates a curve from two or more points, on a surface.
+ RefEdge* make_RefEdge( RefVertex *ref_vertex_1,
+ RefVertex *ref_vertex_2,
+ RefFace* ref_face_ptr,
+ RefVertex const* ref_vertex_3 = NULL ) const ;
+
+ /*! Give a certain ref edge, create a new one.
* This is useful when you are creating surfaces from curves already
* in the model. If you use curves existing in the model (attached
* to other surfaces) then acis will mess up. So we basically
* need a copy. This will also create new vertices...
*/
-
- RefEdge* make_RefEdge(GeometryType ref_edge_type,
- RefVertex *ref_vertex_1,
- RefVertex *ref_vertex_2,
- CubitVector const* intermediate_point = NULL,
- CubitSense sense = CUBIT_FORWARD) const ;
- /**< \return RefEdge*
+ //! \brief Create a curve from an existing curve.
+ RefEdge* make_RefEdge(RefEdge *ref_edge, bool copy_attribs = true) const;
+
+ /*! \return RefEdge*
* \return - A pointer to a newly created RefEdge
* \arg ref_edge_type
* The type of the RefEdge
@@ -878,17 +1154,36 @@
* 3 points must form an isosceles triangle. This definition
* limits the user to generation of the tip of parabolic shapes only.
*/
+ //! \brief Create a curve, i.e. ellipse, parabola, straight, or arc curves.
+ RefEdge* make_RefEdge(GeometryType ref_edge_type,
+ RefVertex *ref_vertex_1,
+ RefVertex *ref_vertex_2,
+ CubitVector const* intermediate_point = NULL,
+ CubitSense sense = CUBIT_FORWARD) const ;
+ //! \brief Create a surface from an existing one.
RefFace* make_RefFace(RefFace *from_ref_face,
CubitBoolean extended_from = CUBIT_FALSE) const;
- /**< create a refface from an existing one, creates underlying entities.
+
+ /*! \return Body*
+ * \return - Pointer to a newly created Body object.
+ * \arg ref_face_list
+ * The RefFace list from which we want to create an extended sheet.
+ * \arg clip_box
+ * An optional bounding box to clip the resultant sheet body by.
+ * \arg preview
+ * If true just draw the extended 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.
*/
+ //! \brief This function creates a sheet body by extending the input surfaces.
+ Body* make_extended_sheet( DLIList<RefFace*> &ref_face_list,
+ CubitBox *clip_box_ptr = NULL,
+ bool preview = false) const;
- RefFace* make_RefFace(GeometryType ref_face_type,
- DLIList<RefEdge*>& ref_edge_list,
- RefFace *ref_face_ptr = NULL,
- bool check_edges = true ) const ;
- /**< \return RefFace*
+ /*! \return RefFace*
* \return - A pointer to a newly created RefFace
* \arg ref_face_type
* The type of the RefFace
@@ -911,26 +1206,14 @@
* value can be a NULL pointer, if the RefFace cannot be succesfully
* made for some reason.
*/
+ //! \brief Creates a surface from bounding curves.
+ RefFace* make_RefFace(GeometryType ref_face_type,
+ DLIList<RefEdge*>& ref_edge_list,
+ bool is_free_face,
+ RefFace *ref_face_ptr = NULL,
+ bool check_edges = true ) const ;
-// RefVolume* make_RefVolume(DLIList<RefFace*>& ref_face_list) const ;
- /**< \return RefVlume*
- * \return - A pointer to a newly created RefVlume
- * \arg ref_volume_type
- * The type of the RefVolume
- * \arg ref_face_list
- * The RefFaces to use to create the RefVolume.
- *
- * This function takes a type information and a list of
- * RefFaces to create a RefVolume. The underlying representation
- * of the RefVolume is determined by the GeometryQueryEngine of
- * the RefFaces. All the RefFaces in the list must be
- * associated with the same GeometryQueryEngine. The return
- * value can be a NULL pointer, if the RefVolume cannot be succesfully
- * made for some reason.
- */
-
- Body* make_Body(DLIList<RefVolume*>& ref_volume_list) const ;
- /**< \return Body*
+ /*! \return Body*
* \return - A pointer to a newly created Body
* \arg ref_volume_list
* The RefVolumes to use to create the Body
@@ -943,19 +1226,17 @@
* pointer, if the RefFace cannot be succesfully made for some
* reason.
*/
+ //! \brief Creates a body from a list of volumes.
+ Body* make_Body(DLIList<RefVolume*>& ref_volume_list) const ;
+ /*! Creates a body from a ref_face. This will always be a
+ * sheet body, with no volume, consisting of a single face.
+ */
+ //! \brief Creates a body from a surface.
Body* make_Body(RefFace *from_ref_face,
CubitBoolean extended_from = CUBIT_FALSE) const;
- /**< Creates a body from a ref_face. This will always be a
- * sheet body, with no volume, consisting of a single face.
- */
- Body* make_Body(GeometryType ref_face_type,
- DLIList<RefEdge*>& ref_edge_list,
- RefFace *ref_face_ptr = NULL) const ;
- // Each RefEdge in ref_edge_list MUST be a free edge, i.e., not
- // attached to a RefFace, for this function to succeed!
- /**< \return Body*
+ /*! \return Body*
* \return - A pointer to a newly created Body that has just one RefFace
* \arg ref_face_type
* The type of the RefFace
@@ -972,8 +1253,16 @@
* GeometryQueryEngine. The return value can be a NULL
* pointer, if the Body cannot be succesfully made for some
* reason.
+ *
+ * Each RefEdge in ref_edge_list MUST be a free edge, i.e., not
+ * attached to a RefFace, for this function to succeed!
*/
+ //! \brief Creates a body from a surface created from a list of curves.
+ Body* make_Body(GeometryType ref_face_type,
+ DLIList<RefEdge*>& ref_edge_list,
+ RefFace *ref_face_ptr = NULL) const ;
+ //! \brief Create bodies by sweeping curves or surfaces along a vector.
CubitStatus sweep_translational(DLIList<RefEntity*>& ref_ent_list,
const CubitVector& sweep_vector,
double draft_angle,
@@ -981,8 +1270,22 @@
CubitBoolean switchside,
CubitBoolean rigid);
- CubitStatus sweep_target(CubitPlane ref_plane,
+ CubitStatus sweep_curve_target(CubitPlane ref_plane,
DLIList<RefEntity*>& ref_ent_list);
+
+ CubitStatus sweep_curve_target(DLIList<RefEdge*>& curve_list,
+ Body *target_body,
+ DLIList<Body*> &out_bodies,
+ CubitVector direction,
+ CubitPlane stop_plane,
+ bool unite);
+
+ CubitStatus sweep_surface_target(RefFace *face,
+ Body *target_body,
+ CubitVector distance,
+ CubitPlane stop_plane,
+ double magnitude = 0.0);
+
CubitStatus sweep_surface_target(CubitPlane ref_plane,
DLIList<RefEntity*>& ref_ent_list);
@@ -993,6 +1296,7 @@
CubitBoolean switchside,
CubitBoolean rigid);
+ //! \brief Creates bodies by sweeping surfaces or curves about an axis.
CubitStatus sweep_rotational(DLIList<RefEntity*>& ref_ent_list,
const CubitVector& point,
const CubitVector& direction,
@@ -1004,24 +1308,47 @@
CubitBoolean make_solid = CUBIT_FALSE,
CubitBoolean rigid = CUBIT_FALSE);
+ //! \brief Creates bodies by sweeping surfaces or curves along a curve.
CubitStatus sweep_along_curve(DLIList<RefEntity*>& ref_ent_list,
DLIList<RefEdge*>& ref_edge_list,
double draft_angle = 0.0,
int draft_type = 0,
CubitBoolean rigid = CUBIT_FALSE);
+ //! \brief Currently unsupported.
+ CubitStatus tweak_bend( DLIList<Body*> &bend_bodies,
+ DLIList<Body*> &new_body_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 );
+
+ /*! Chamfer curves on solid and 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.
+ */
+ //! \brief Chamfer curves on solid and sheet bodies.
CubitStatus tweak_chamfer( DLIList<RefEdge*> &ref_edge_list,
double left_offset,
DLIList<Body*> &new_body_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 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.
*/
-
+ //! \brief Chamfer vertices on solid or sheet bodies.
CubitStatus tweak_chamfer( DLIList<RefVertex*> &ref_vertex_list,
double offset1,
DLIList<Body*> &new_body_list,
@@ -1032,170 +1359,255 @@
RefEdge *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
- * supplied, only one offset value is allowed and the edges are not used.
- */
+ //! \brief Creates a round fillet (or blend) at the given curves on solid or
+ //! sheet bodies.
CubitStatus tweak_fillet( DLIList<RefEdge*> &ref_edge_list,
double radius,
DLIList<Body*> &new_body_list,
CubitBoolean keep_old_body = CUBIT_FALSE,
CubitBoolean preview = CUBIT_FALSE );
- /**< Create a round fillet (or blend) at the given curves on solid bodies.
+
+ /*! Creates 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.
*/
-
+ //! \brief Creates a round fillet (or blend) at the given curve.
CubitStatus tweak_fillet( RefEdge *ref_edge_ptr,
double start_radius,
double end_radius,
Body *&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.
- */
+ //! \brief Create a round fillet (or blend) at the given vertices on sheet bodies.
CubitStatus tweak_fillet( DLIList<RefVertex*> &ref_vertex_list,
double radius,
DLIList<Body*> &new_body_list,
CubitBoolean keep_old_body = CUBIT_FALSE,
CubitBoolean preview = CUBIT_FALSE );
- /**< Create a round fillet (or blend) at the given vertices on sheet bodies.
- */
+ //! \brief Tweak specified faces of a volume or volumes along a vector.
CubitStatus tweak_move( DLIList<RefFace*> &ref_face_list,
const CubitVector &delta,
DLIList<Body*> &new_body_list,
CubitBoolean keep_old_body = CUBIT_FALSE,
CubitBoolean preview = CUBIT_FALSE );
- /**< Tweak specified faces of a volume or volumes along a vector.
- */
+ //! \brief Tweak specified curves of a sheet body along a vector.
CubitStatus tweak_move( DLIList<RefEdge*> &ref_edge_list,
const CubitVector &delta,
DLIList<Body*> &new_body_list,
CubitBoolean keep_old_body = CUBIT_FALSE,
CubitBoolean preview = CUBIT_FALSE );
- /**< Tweak specified curves of a sheet body along a vector.
+
+ /*! Tweak specified faces of a volume or volumes by offsetting those faces
+ * by the offset distance. Optionally supply additional faces with
+ * different offset distances.
*/
-
+ //! \brief Offsets a surface(s) on a volume(s).
CubitStatus tweak_offset( DLIList<RefFace*> &ref_face_list,
double offset_distance,
+ DLIList<RefFace*> *add_ref_face_list_ptr,
+ DLIList<double> *add_offset_list_ptr,
DLIList<Body*> &new_body_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.
+
+ /*! Tweak specified curves of a sheet body or bodies by offsetting those
+ * curves by the offset distance. Optionally supply additional curves with
+ * different offset distances.
*/
-
+ //! \brief Offset curves on sheet bodies.
CubitStatus tweak_offset( DLIList<RefEdge*> &ref_edge_list,
double offset_distance,
+ DLIList<RefEdge*> *add_ref_face_list_ptr,
+ DLIList<double> *add_offset_list_ptr,
DLIList<Body*> &new_body_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.
- */
- CubitStatus tweak_remove( DLIList<RefFace*> &ref_face_list,
- DLIList<Body*> &new_body_list,
- CubitBoolean extend_adjoining = CUBIT_TRUE,
- CubitBoolean keep_surface = CUBIT_FALSE,
- CubitBoolean keep_old_body = CUBIT_FALSE,
- CubitBoolean individual = CUBIT_FALSE,
- CubitBoolean preview = CUBIT_FALSE);
- /**< Remove surfaces from a body or bodies and then extend the adjoining
- * surfaces to fill the gap or remove the hole.
- */
+ //! \brief Performs tweak_remove operation on surfaces individually.
+ CubitStatus tweak_remove_individually( DLIList<RefFace*> &ref_face_list,
+ DLIList<Body*> &new_body_list,
+ CubitBoolean keep_surface = CUBIT_FALSE,
+ CubitBoolean keep_old_body = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE );
+ //! \brief Performs tweak_remove operation on surfaces collectively.
+ CubitStatus tweak_remove_together( DLIList<RefFace*> &ref_face_list,
+ DLIList<Body*> &new_body_list,
+ CubitBoolean extend_adjoining = CUBIT_TRUE,
+ CubitBoolean keep_surface = CUBIT_FALSE,
+ 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.
+ */
+ //! \brief Removes a surface from a volume, extending neighboring surfaces.
CubitStatus tweak_remove( DLIList<RefEdge*> &ref_edge_list,
DLIList<Body*> &new_body_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.
+
+ /*! Tweak specified faces of a volume or volumes up to target surface.
+ * 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.
*/
-
+ //! \brief Extends (tweaks) surfaces up to a target surface.
CubitStatus tweak_target( DLIList<RefFace*> &ref_face_list,
DLIList<RefFace*> &target_face_list,
DLIList<Body*> &new_body_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 target plane.
+ * 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.
+ */
+
+ //! \brief Extends (tweaks) surfaces up to a target plane.
CubitStatus tweak_target( DLIList<RefFace*> &ref_face_list,
CubitPlane &plane,
DLIList<Body*> &new_body_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 target surface
- * or plane.
+
+ /*! Tweak specified edges of a surface or set of surfaces (in sheet
+ * bodies) up to target surfaces or plane. This essentially extends
+ * or 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.
*/
-
+ //! \brief Extends (tweaks) curves up to a target surface.
CubitStatus tweak_target( DLIList<RefEdge*> &ref_edge_list,
DLIList<RefFace*> &target_face_list,
DLIList<Body*> &new_body_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 );
+ CubitBoolean preview = CUBIT_FALSE,
+ double max_area_increase = 0 );
CubitStatus tweak_target( DLIList<RefEdge*> &ref_edge_list,
CubitPlane &plane,
DLIList<Body*> &new_body_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 target surfaces or plane. This essentially extends
- * or trims the attached surfaces of the sheet body.
+
+ /*! Tweak specified edges of a surface or set of surfaces (in sheet
+ * bodies) up to target plane. This essentially extends
+ * or 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.
*/
-
+ //! \brief Extends (tweaks) curves up to a target plane.
CubitStatus tweak_target( DLIList<RefEdge*> &ref_edge_list,
DLIList<RefEdge*> &target_edge_list,
DLIList<Body*> &new_body_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 );
+ CubitBoolean preview = CUBIT_FALSE,
+ double max_area_increase = 0 );
/**< Tweak specified edges of a sheet body or bodies up to target curves
* that are part of a sheet body. The target is a surface or surfaces
* created by thickening the owning surface of the target curve(s).
+ * 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.
*/
+ //! \brief Tweak specified vertex of a sheet body to a given location.
+ CubitStatus tweak_target( RefVertex *ref_vertex_ptr,
+ DLIList<RefFace*> &modify_ref_face_list,
+ CubitVector &target_loc,
+ Body *&new_Body_ptr,
+ CubitBoolean keep_old_body = CUBIT_FALSE,
+ CubitBoolean preview = CUBIT_FALSE );
-
+ //! \brief Converts edges smaller than 'lengthlimit' into tolerant (or fat) vertices.
+ //! ACIS only.
CubitStatus remove_curve_slivers( DLIList<Body*> &bodies, double lengthlimit );
- //ACIS-specific function only. Converts edges smaller than 'lengthlimit' into
- //tolerant (or fat) vertices.
+ //! \brief Create a surface using arrays of points in u and v directions.
CubitStatus create_net_surface( DLIList<Surface*>& ref_face_list, BodySM *& new_body,
DLIList<DLIList<CubitVector*>*> &vec_lists_u,
DLIList<DLIList<CubitVector*>*> &vec_lists_v,
double net_tol = 1e-3,
CubitBoolean heal = CUBIT_TRUE );
- CubitStatus create_net_surface( DLIList<RefEdge*>& u_curves, DLIList<RefEdge*>& v_curves,
+ //! \brief Create a surface using curves in u and v directions.
+ CubitStatus create_net_surface( DLIList<RefEdge*>& u_curves,
+ DLIList<RefEdge*>& v_curves,
double net_tol = 1e-3,
CubitBoolean heal = CUBIT_TRUE );
+ //! \brief Creates an offset surface some distance from a surface.
CubitStatus create_offset_surface( RefFace* ref_face_ptr,
double offset_distance );
+ /*! 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.
+ */
+ //! \brief Create a body(s) by offsetting the given surfaces.
+ CubitStatus create_offset_sheet( DLIList<RefFace*> &ref_face_list,
+ double offset_distance,
+ DLIList<RefFace*> *add_ref_face_list_ptr,
+ DLIList<double> *add_offset_list_ptr,
+ DLIList<Body*> &new_body_list,
+ CubitBoolean preview = CUBIT_FALSE );
+
+ //! \brief Create a body by offsetting all the surface of the body.
CubitStatus create_offset_body( Body *body_ptr, Body *&new_body,
double offset_distance );
- CubitStatus create_skin_surface( DLIList<RefEdge*>& ref_edges, Body*& new_body );
-
-#ifdef BOYD14
- CubitStatus loft_surfaces( RefFace *face1, const double &takeoff1,
- RefFace *face2, const double &takeoff2,
- Body*& new_body,
- CubitBoolean arc_length_option = CUBIT_FALSE,
- CubitBoolean twist_option = CUBIT_FALSE,
- CubitBoolean align_direction = CUBIT_TRUE,
- CubitBoolean perpendicular = CUBIT_TRUE,
- CubitBoolean simplify_option = CUBIT_FALSE);
-#endif
-
+ //! \brief Create a sheet body skinning (lofting) a series of curves.
+ CubitStatus create_skin_surface( DLIList<RefEdge*>& ref_edges,
+ Body*& new_body,
+ DLIList<RefEdge*>& guides);
+
+ //! \brief Create a solid body by lofting between two surfaces.
CubitStatus loft_surfaces_to_body( RefFace *face1, const double &takeoff1,
RefFace *face2, const double &takeoff2,
Body*& new_body,
@@ -1205,11 +1617,50 @@
CubitBoolean perpendicular,
CubitBoolean simplify_option);
+ CubitStatus create_surface_curve(DLIList<RefEntity*> curve_entity,
+ DLIList<RefEntity*> target_entity,
+ CubitVector sweep_direction = CubitVector (0,0,0),
+ CubitBoolean distance_flag = CUBIT_FALSE);
+
+ CubitStatus idealize_hole_slot_geometry(DLIList<RefEntity*> idealize_entity,
+ DLIList<RefEntity*> exclude_entity,
+ double arc_radius,
+ double slot_arc_radius,
+ double slot_length,
+ CubitBoolean preview = CUBIT_FALSE);
+
+ CubitStatus idealize_fillet_geometry(DLIList<RefEntity*> idealize_entity,
+ DLIList<RefEntity*> exclude_entity,
+ double fillet_rad,
+ CubitBoolean internal_flg,
+ CubitBoolean external_flg,
+ CubitBoolean preview = CUBIT_FALSE);
+
+ CubitStatus create_surface_doubler(DLIList<RefEntity*> doubler_entity,
+ DLIList<RefEntity*> target_entity,
+ DLIList<Body*> &body_list_out,
+ CubitBoolean internal_flg = CUBIT_FALSE,
+ CubitBoolean extend_flg = CUBIT_TRUE,
+ CubitPlane *limit_plane = NULL,
+ CubitVector sweep_direction = CubitVector(0,0,0),
+ CubitBoolean preview = CUBIT_FALSE);
+
+ /*! Fits an analytic spline surface through positions. If a surface is specified,
+ positions are forced to lie on the surface and restrains the resultant surface
+ geometry to match the surface's geometry. The project parameter will project
+ the nodes or vertices to the specified surface.
+ */
+ //! \brief Fits an analytic spline surface through positions.
CubitStatus create_surface( DLIList<CubitVector*>& vec_list,
Body *&new_body,
RefFace *ref_face_ptr,
CubitBoolean project_points );
+ CubitStatus create_surface( DLIList<RefVertex*> &vert_list,
+ Body *&new_body );
+
+
+ //! \brief Creates a simple triangular weld surface.
CubitStatus create_weld_surface( CubitVector &root,
RefFace *ref_face1,
double leg1,
@@ -1217,139 +1668,103 @@
double leg2,
Body *&new_body );
- CubitStatus create_body_from_surfs( DLIList<RefFace*> &ref_face_list,
- Body *&new_body,
- CubitBoolean keep_old = CUBIT_FALSE,
- CubitBoolean heal = CUBIT_TRUE ) const;
- /**< Creates a body out of the surfaces in the ref_face_list. The surfaces
+ /*! Creates a body out of the surfaces in the ref_face_list. The surfaces
* can be either free surfaces or sheet bodies or both.
- * The body should be healed.
+ * The body should be healed. The bounding curves and vertices between
+ * the surfaces must be within tolerance.
*/
+ //! \brief Creates a body out of the specified surfaces.
+ CubitStatus create_solid_bodies_from_surfs( DLIList<RefFace*> &ref_face_list,
+ DLIList<Body*> &new_bodies,
+ CubitBoolean keep_old = CUBIT_FALSE,
+ CubitBoolean heal = CUBIT_TRUE,
+ CubitBoolean sheet = CUBIT_FALSE ) const;
+ //! \brief Create curves from the intersection of two surfaces.
CubitStatus surface_intersection( RefFace *ref_face1,
RefFace *ref_face2,
DLIList<RefEdge*> &ref_edge_list );
- /**< Create curves from the intersection of two surfaces */
+ //! \brief Create an arc curve from three points.
RefEdge* create_arc_three( RefVertex* ref_vertex1,
RefVertex* ref_vertex2,
RefVertex* ref_vertex3,
CubitBoolean full = CUBIT_FALSE );
+
+ //! \brief Create an arc curve tangent to three curves.
RefEdge* create_arc_three( RefEdge* ref_edge1,
RefEdge* ref_edge2,
RefEdge* ref_edge3,
CubitBoolean full = CUBIT_FALSE );
+
+ /*! \brief Create an arc curve from two points and a center point.
+ If full option is specified, a full circle is created.*/
+ //! \brief Create an arc curve from two points and a center point.
RefEdge* create_arc_center_edge( RefVertex* ref_vertex1,
RefVertex* ref_vertex2,
RefVertex* ref_vertex3,
const CubitVector &normal,
double radius = CUBIT_DBL_MAX,
CubitBoolean full = CUBIT_FALSE );
- /**< Methods to create arcs. First uses 3 points on arc, next creates arc
- * tangent to 3 curves, last creates arc using center and two points on arc.
- * If full option is specified, a full circle is created.
- */
+ //! \brief Create a curve that is a combination of the specified curves.
CubitStatus create_curve_combine( DLIList<RefEdge*>& ref_edge_list,
RefEdge *&new_ref_edge_ptr );
- /*< Uses the solid modeller to create a new RefEdge that is a combination
- * of the input chain of edges.
- */
- static void set_sep_after_webcut_setting(CubitBoolean val)
- {sepAfterWebcut = val;}
- static CubitBoolean get_sep_after_webcut_setting()
- {return sepAfterWebcut;}
- /**< Gets/Sets the separate after webcut static flag.
- */
+ //! \brief Sets sepAfterWebcut variable.
+ static void set_sep_after_webcut_setting(CubitBoolean val) {sepAfterWebcut = val;}
+ //! \brief Gets sepAfterWebcut variable.
+ static CubitBoolean get_sep_after_webcut_setting() {return sepAfterWebcut;}
+
+ /*! Returns CUBIT_TRUE if all the entities have the same geometric query engine and
+ * if that is the same one as the default. */
+ //! \brief Check to determine if all entities are of the same geometry engine.
CubitBoolean same_modify_engine(DLIList<TopologyEntity*> &topo_list) const;
- /**< Returns CUBIT_TRUE if all the entities have the same geometric query engine and
- * if that is the same one as the default.
- */
- CubitBoolean same_modify_engine(DLIList<RefEntity*> &ref_entity_list,
- CubitBoolean check_children = CUBIT_FALSE) const;
- /**< Returns CUBIT_TRUE if all the entities have the same geometric query engine and
+ /*! Returns CUBIT_TRUE if all the entities have the same geometric query engine and
* if that is the same one as the default. If the check_children parameter is
* CUBIT_TRUE, all the child entities will also be checked.
*/
+ //! \brief Check to determine if all entities are of the same geometry engine as
+ //! active geometry engine.
+ CubitBoolean same_modify_engine(DLIList<RefEntity*> &ref_entity_list,
+ CubitBoolean check_children = CUBIT_FALSE) const;
- GeometryModifyEngine* common_modify_engine( DLIList<Body*>& bodies,
- DLIList<BodySM*>& bodysms ) const;
+
+ //! \brief Determines if specified RefFaces and RefEdges are of the same geometry engine.
+ //! Returns common engine, if any, and underlying surfaces and curves.
GeometryModifyEngine* common_modify_engine( DLIList<RefFace*>& faces,
DLIList<RefEdge*>& edges,
DLIList<Surface*>& surfaces,
- DLIList<Curve*>& curves ) const;
- GeometryModifyEngine* common_modify_engine( DLIList<RefFace*>& faces,
- DLIList<Surface*>& surfaces ) const;
- GeometryModifyEngine* common_modify_engine( DLIList<RefEdge*>& edges,
- DLIList<Curve*>& curves ) const;
- GeometryModifyEngine* common_modify_engine( DLIList<RefVertex*>& vertices,
- DLIList<Point*>& points ) const;
+ DLIList<Curve*>& curves,
+ CubitBoolean allow_composites = CUBIT_FALSE) const;
- GeometryModifyEngine* common_modify_engine( DLIList<TopologyEntity*>& topology_list,
- DLIList<TopologyBridge*>& engine_bridges,
- CubitBoolean allow_virtual_engine
- = CUBIT_FALSE ) const;
- /**< \return GeometryModifyEngine*
- * A GeometryModifyEngine common at least one
- * TopologyBridge of each of the passed TopologyEntities, or
- * NULL if no common geometry engine is found.
- * \arg topology_list
- * The input list of TopologyEntities
- * \arg engine_bridges
- * Pass back the list of TopolgyBridges associated with each
- * of the passed TopologyEntities (topology_list) and owned
- * by the returned geometry engine.
- * \arg allow_virtual_engine
- * Return VirtualGeometryEngine::instance() if no common
- * geometry enginge can be found.
- *
- * Look for a common geometry engine other than the
- * VirtualGeometryEngine. If no common geometry engine other
- * than VGE can be found and allow_virtual_engine is FALSE,
- * NULL is returned. If allow_virtual_engine is TRUE, and no
- * common geometry engine is found, VGE will be returned, and
- * engine_bridges will be populated with any virtual geometry
- * if possible, otherwise with the first topology bridge attached
- * to each of the passed TopologyEntities.
- */
+
+ //! \brief Add a geometry modify engine to the list.
void add_gme(GeometryModifyEngine *gme_ptr);
- /**< add a geometry modify engine to the list
- */
+ //! \brief < remove a geometry modify engine from the list; returns CUBIT_FAILURE
+ //! if it wasn't in the list.
CubitStatus remove_gme(GeometryModifyEngine *gme_ptr);
- /**< remove a geometry modify engine from the list; returns CUBIT_FAILURE
- * if it wasn't on the list
- */
+ //! \brief Returns a list of GeometryModifyEngines.
void get_gme_list(DLIList<GeometryModifyEngine*> &gme_list);
- /**< return the list of gme's
- */
+ //! \brief Gets the current active GeometryModifyEngine.
GeometryModifyEngine *get_gme() const;
- /**< return the first gme on the list
- */
-// GeometryModifyEngine *get_gme(const EntityType gme_type);
- /**< return the gme of the specified type
- */
+ //! \brief Gets the GeometryModifyEngine of this entity.
GeometryModifyEngine *get_engine(TopologyBridge *tb_ptr) const;
- /**< get the geometry modify engine associated with this entity
- */
+ //! \brief Gets the GeometryModifyEngine of this entity.
GeometryModifyEngine *get_engine(TopologyEntity *te_ptr,
TopologyBridge** bridge = 0) const;
- /**< get the geometry modify engine associated with this entity
- */
- CubitStatus get_offset_intersections( RefEdge* ref_edge1, RefEdge* ref_edge2,
- DLIList<CubitVector*>& intersection_list,
- double offset, CubitBoolean ext_first = CUBIT_TRUE );
- /***< Finds the intersections of a certain distance (offset) between two
+
+ /*! Finds the intersections of a certain distance (offset) between two
* curves. The two curves must lie in a plane. The first curve is offset
* the offset distance in both directions, and the bounded intersections with
* the second curve are found. The first curve can optionally be extended
@@ -1359,36 +1774,49 @@
* diameter on an arc in an engineering drawing. The function allocates the
* CubitVectors in the returned list, so be sure to free them.
*/
+ //! \brief Finds the intersections of a certain distance (offset) between two curves.
+ CubitStatus get_offset_intersections( RefEdge* ref_edge1, RefEdge* ref_edge2,
+ DLIList<CubitVector*>& intersection_list,
+ double offset, CubitBoolean ext_first = CUBIT_TRUE );
- CubitStatus get_offset_intersections( RefEdge* ref_edge_ptr, RefFace* ref_face_ptr,
- DLIList<CubitVector*> &intersection_list,
- double offset = 0.0,
- CubitBoolean ext_surf = CUBIT_TRUE );
- /**< Finds intersections (points) of the curve and surface. The surface can
+ /*! Finds intersections (points) of the curve and surface. The surface can
* be offset - it is offset to each side and intersections are found. By
* default the surface is extended to infinity (if possible) and the
* intersections are found. The function allocates the CubitVectors in
* the returned list, so be sure to free them.
*/
+ //! \brief Finds intersections (points) of the curve and surface.
+ CubitStatus get_offset_intersections( RefEdge* ref_edge_ptr, RefFace* ref_face_ptr,
+ DLIList<CubitVector*> &intersection_list,
+ double offset = 0.0,
+ CubitBoolean ext_surf = CUBIT_TRUE );
+ //! \brief From two surface, create a midplane, then trim it with a body.
CubitStatus get_mid_plane( RefFace *ref_face_1,
RefFace *ref_face_2,
Body *body_to_trim_to,
DLIList<RefFace*> &mid_plane_surfs ) const;
- /**< Given 2 surfaces, this function returns trimmed surfaces of
- * the mid plane.
- */
+ //! \brief Given 2 surfaces, this returns trimmed surfaces of
+ //! the midsurface (this is an ALPHA feature).
CubitStatus get_mid_surface( RefFace *ref_face_1,
RefFace *ref_face_2,
Body *body_to_trim_to,
DLIList<RefFace*> &mid_plane_surfs ) const;
- /**< Given 2 surfaces, this function returns trimmed surfaces of
- * the midsurface (this is an ALPHA feature).
- */
-CubitStatus set_default_gme(GeometryModifyEngine* GMEPtr);
+ //! \brief Sets the active geometry engine.
+ CubitStatus set_default_gme(GeometryModifyEngine* GMEPtr);
+ //! Get a subset of bodies from 'remaining_bodies' that share
+ //! a common GeometryModifyEngine. Remove them from
+ //! 'remaining_bodies', put the Bodies and corresponding BodySMs in
+ //! 'engine_bodies' and 'engine_body_sms', and return the engine.
+ //! Returns NULL if all bodies remaining in the list have no
+ //! modify engine.
+ //! \brief Groups Bodies with the same underlying geometry engine into a list.
+ GeometryModifyEngine* group_bodies_by_engine( DLIList<Body*>& remaining_bodies,
+ DLIList<Body*>& engine_bodies,
+ DLIList<BodySM*>& engine_body_sms ) const;
protected :
GeometryModifyTool(GeometryModifyEngine* GMEPtr);
@@ -1414,32 +1842,50 @@
CubitStatus okay_to_modify( DLIList<Body*>& bodies, const char* op ) const;
-public: /* needed by OffsetSplitTool*/
- CubitStatus finish_webcut( DLIList<Body*>& input_bodies,
- DLIList<BodySM*>& webcut_results,
- CubitBoolean merge,
- CubitStatus webcut_status,
- DLIList<Body*>& new_bodies,
- CubitBoolean print_info = CUBIT_TRUE ) const;
- //- Helper function for all webcut functions.
- //- Finish up DAG update, merging, etc. after GME does webcut.
- //I input_bodies
- //I- The list of bodies that were webcut
- //I webcut_results
- //I- The new bodies returned by the GME webcut.
- //I merge
- //I- Merge after webcut
- //I webcut_status
- //I- The return value from the GME webcut function
- //O new_bodies
- //O- The new Bodies constructed from the passed BodySMs.
- //R CubitStatus
- //R- CUBIT_FAILURE on error, webcut_status on success.
- //- Does separate_body_after_webcut for all bodies if
- //- webcut_status == CUBIT_SUCCESS
- //- Merges bodies if webcut_status == CUBIT_SUCCESS AND merge == CUBIT_TRUE
+ GeometryModifyEngine* common_modify_engine( DLIList<Body*>& bodies,
+ DLIList<BodySM*>& bodysms ) const;
- /* needed by AcisEdgeTool */
+ GeometryModifyEngine* common_modify_engine( DLIList<RefFace*>& faces,
+ DLIList<Surface*>& surfaces,
+ CubitBoolean allow_composites = CUBIT_FALSE ) const;
+ GeometryModifyEngine* common_modify_engine( DLIList<RefEdge*>& edges,
+ DLIList<Curve*>& curves,
+ CubitBoolean allow_composites = CUBIT_FALSE ) const;
+ GeometryModifyEngine* common_modify_engine( DLIList<RefVertex*>& vertices,
+ DLIList<Point*>& points,
+ CubitBoolean allow_composites = CUBIT_FALSE ) const;
+
+ GeometryModifyEngine* common_modify_engine( DLIList<TopologyEntity*>& topology_list,
+ DLIList<TopologyBridge*>& engine_bridges,
+ CubitBoolean allow_composites
+ = CUBIT_FALSE ) const;
+ /**< \return GeometryModifyEngine*
+ * A GeometryModifyEngine common at least one
+ * TopologyBridge of each of the passed TopologyEntities, or
+ * NULL if no common geometry engine is found.
+ * \arg topology_list
+ * The input list of TopologyEntities
+ * \arg engine_bridges
+ * Pass back the list of TopolgyBridges associated with each
+ * of the passed TopologyEntities (topology_list) and owned
+ * by the returned geometry engine.
+ * \arg allow_virtual_engine
+ * Return VirtualGeometryEngine::instance() if no common
+ * geometry enginge can be found.
+ *
+ * Look for a common geometry engine other than the
+ * VirtualGeometryEngine. If no common geometry engine other
+ * than VGE can be found and allow_virtual_engine is FALSE,
+ * NULL is returned. If allow_virtual_engine is TRUE, and no
+ * common geometry engine is found, VGE will be returned, and
+ * engine_bridges will be populated with any virtual geometry
+ * if possible, otherwise with the first topology bridge attached
+ * to each of the passed TopologyEntities.
+ */
+
+public:
+
+ //! \brief Internal use only.
CubitStatus finish_sm_op( DLIList<Body*>& input_bodies,
DLIList<BodySM*>& new_bodies,
DLIList<Body*>& result_bodies,
@@ -1466,7 +1912,8 @@
GeometryModifyEngine* tweak_setup( DLIList<RefFace*>& input_faces,
const char* tweak_function_name,
DLIList<Body*>& old_bodies_out,
- DLIList<Surface*>& surfaces_out );
+ DLIList<Surface*>& surfaces_out,
+ CubitBoolean allow_composites = CUBIT_FALSE);
GeometryModifyEngine* tweak_setup( DLIList<RefEdge*>& input_edges,
const char* tweak_function_name,
@@ -1505,20 +1952,6 @@
//O curve_list
//O- Curves corresponding to edges in edge_list.
- CubitStatus sweep_finish( const char* const sweep_function_name,
- DLIList<Body*>& input_body_list,
- DLIList<BodySM*>& new_body_list,
- CubitBoolean restore_newids );
- //- Common cleanup code for sweep functions
- //I sweep_function_name
- //I- Name to use in error messages.
- //I input_body_list
- //I- Bodies that may need to be updated.
- //I new_body_list
- //I- bodies returned by GeometryModifyEngine
- //I restore_newids
- //I- Passed back from sweep_setup -- restore setting state.
-
CubitStatus imprint_singly( DLIList<Body*>& body_list,
DLIList<Body*>& new_bodies,
CubitBoolean keep_old );
@@ -1531,57 +1964,61 @@
Body* update_body( Body* body ) const;
//- Destroy or update modified body, as appropriate.
+ void body_premodify(Body* body) const;
+ //- traverse the body object and calls premodify function on each structure
+
+
private :
+ //! \brief Static pointer to the unique instance of this class.
static GeometryModifyTool* instance_;
- /**< static pointer to the unique instance of this class.
- */
+ //! \brief Use group imprinting, which is much faster. Default: true.
static CubitBoolean groupImprint;
- /**< if true, the new group imprint function is called, which is much faster;
- */
+ //! \brief An object will be unmeshed if modified or deleted. Default: true.
+ static CubitBoolean meshAutodelete;
+
+ //! \brief An object will be cached if the mesh is autodeleted
+ //! and can be remeshed later. Default: false.
+ static CubitBoolean meshAutodeleteRemesh;
+
+ //! \brief Causes code to reuse old ids, which are more persistent. Default: false.
static CubitBoolean newIds;
- /**< if true, causes code to reuse old ids, which are more persistent
- */
+ //! \brief Attempt entity naming backwards compatible with v8/pre-bool-on-merged. Default:
+ //! false.
static CubitBoolean oldNames;
- /**< Attempt entity naming backwards compatible with v8/pre-bool-on-merged
- */
+ //! \brief Separate the result bodies of webcutting into single-body volumes.
+ //! Default: true.
static CubitBoolean sepAfterWebcut;
- /**< Will separate after webcutting the bodies into multiple bodies that
- * only contain 1 volume each.
- */
- static CubitBoolean allEdgesImprint;
- /**< Option for acis to know if we should imprint all of the edges
+ /*! Option for acis to know if we should imprint all of the edges
* or only relevant ones. For now, default is false, but check
* the .cc file. The user can control this by a "set" nonregimprint
- * command.
+ * command. Default: true.
*/
+ static CubitBoolean allEdgesImprint;
+ //! \brief Regularized booleans are performed. Default: true.
static CubitBoolean booleanRegularize;
- /**< If true, regularized booleans are performed;
- * Otherwise, nonregularized booleans are performed.
- */
+ //! \brief Unite operations can mix sheet bodies with solid bodies. Default: true.
+ static CubitBoolean uniteMixedModels;
+
+ /*! Pointer to the entity being copied. When copying an entity, used to
+ prevent to copying of unique id and saved-merged-ids attributes.
+ */
+ //! \brief This pointer points to the entity that is being copied.
static RefEntity *copyingEntity;
- //- This pointer points to the entity that is being copied.
+ //! \brief The list of geometry modify engines.
DLIList<GeometryModifyEngine*> gmeList;
- /**< The list of geometry modify engines
- */
- GeometryModifyEngine* group_bodies_by_engine( DLIList<Body*>& remaining_bodies,
- DLIList<Body*>& engine_bodies,
- DLIList<BodySM*>& engine_body_sms ) const;
- //- Get a subset of bodies from 'remaining_bodies' that share
- //- a common GeometryModifyEngine. Remove them from
- //- 'remaining_bodies', put the Bodies and corresponding BodySMs in
- //- 'engine_bodies' and 'engine_body_sms', and return the engine.
- //- Returns NULL if all bodies remaining in the list have no
- //- modify engine.
+ void get_merged_curve_and_surface_ids( DLIList<Body*> &bodies,
+ DLIList<int> &merged_surface_ids,
+ DLIList<int> &merged_curve_ids ) const;
CubitStatus separate_body_after_webcut (DLIList<Body*> &input_list,
DLIList<Body*> &output_list) const;
@@ -1590,6 +2027,9 @@
* only be called after webcutting. (Checks sepAfterWebcut flag.)
*/
+ void fixup_merged_entities( DLIList<int> &merged_surface_ids,
+ DLIList<int> &merged_curve_ids ) const;
+
bool contains_intermediate_geom(DLIList<Body*>& list) const;
bool contains_intermediate_geom(DLIList<TopologyBridge*>& list) const;
bool contains_composites(DLIList<TopologyBridge*>& bridge_list ) const;
@@ -1602,15 +2042,136 @@
* are virtual.
*/
#endif
-
+
void do_attribute_setup(void);
void do_attribute_cleanup(void);
void push_vg_attributes_before_modify(DLIList<BodySM*> &old_sms);
CubitStatus restore_vg_after_modify(DLIList<BodySM*> &new_sms,
+ DLIList<Body*> &old_bodies,
+ GeometryModifyEngine *gme);
+ void remove_pushed_attributes(DLIList<BodySM*> &new_sms,
DLIList<Body*> &old_bodies);
void push_imprint_attributes_before_modify(DLIList<BodySM*> &old_sms);
+ void push_named_attributes_to_curves_and_points(DLIList<TopologyBridge*> &tb_list, const char *name_in);
void remove_imprint_attributes_after_modify(DLIList<BodySM*> &body_sms,
DLIList<BodySM*> &new_sms);
+
+ //! draw a preview of a plane for webcut previews
+ static void plane_preview(DLIList<Body*> &body_list,
+ const CubitVector &pt1,
+ const CubitVector &pt2,
+ const CubitVector &pt3);
+
+ void propagate_from_small_edge( RefEdge *edge,
+ DLIList<RefEdge*> &small_edges,
+ DLIList<RefFace*> &narrow_faces,
+ DLIList<RefFace*> &processed_faces,
+ double small_edge_length);
+ void propagate_over_narrow_face( RefFace *narrow_face,
+ RefEdge *edge,
+ DLIList<RefFace*> &processed_faces,
+ DLIList<RefEdge*> &small_edges,
+ DLIList<RefFace*> &narrow_faces,
+ double small_edge_length);
+
+ static CubitStatus prepare_for_copy( RefEntity *ref_ents,
+ TopologyBridge *&top_bridge );
+
+ static CubitStatus finish_copy( TopologyBridge *&new_bridge,
+ TopologyBridge *old_bridge );
+
+ CubitStatus sweep_finish( const char* const sweep_function_name,
+ DLIList<Body*>& input_body_list,
+ DLIList<BodySM*>& new_body_list,
+ DLIList<Body*>& output_body_list,
+ CubitBoolean restore_newids );
+ //- Common cleanup code for sweep functions
+ //I sweep_function_name
+ //I- Name to use in error messages.
+ //I input_body_list
+ //I- Bodies that may need to be updated.
+ //I new_body_list
+ //I- SMbodies returned by GeometryModifyEngine
+ //I output_body_list
+ //I- ref_bodies returned by GeometryModifyEngine
+ //I restore_newids
+ //I- Passed back from sweep_setup -- restore setting state.
+
+ CubitStatus finish_webcut( DLIList<Body*>& input_bodies,
+ DLIList<BodySM*>& webcut_results,
+ CubitBoolean merge,
+ CubitStatus webcut_status,
+ DLIList<Body*>& new_bodies,
+ DLIList<int> *merged_surface_ids = NULL,
+ DLIList<int> *merged_curve_ids = NULL,
+ CubitBoolean print_info = CUBIT_TRUE ) const;
+ //- Helper function for all webcut functions.
+ //- Finish up DAG update, merging, etc. after GME does webcut.
+ //I input_bodies
+ //I- The list of bodies that were webcut
+ //I webcut_results
+ //I- The new bodies returned by the GME webcut.
+ //I merge
+ //I- Merge after webcut
+ //I webcut_status
+ //I- The return value from the GME webcut function
+ //O new_bodies
+ //O- The new Bodies constructed from the passed BodySMs.
+ //R CubitStatus
+ //R- CUBIT_FAILURE on error, webcut_status on success.
+ //- Does separate_body_after_webcut for all bodies if
+ //- webcut_status == CUBIT_SUCCESS
+ //- Merges bodies if webcut_status == CUBIT_SUCCESS AND merge == CUBIT_TRUE
+
+ CubitStatus tweak_remove( DLIList<RefFace*> &ref_face_list,
+ DLIList<Body*> &new_body_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 extend the adjoining
+ * surfaces to fill the gap or remove the hole. Only called by
+ * tweak_remove_individually, tweak_remove_together.
+ */
+
+ void get_neighboring_bodies( DLIList<Body*> &input_bodies,
+ DLIList<Body*> &neighboring_bodies );
+
+
+ CubitStatus unite_separately( GeometryModifyEngine *gme_ptr,
+ DLIList<Body*> &body_list,
+ DLIList<Body*> &new_body_list,
+ bool keep_old );
+ CubitStatus unite_all( GeometryModifyEngine *gme_ptr,
+ DLIList<Body*> &body_list,
+ DLIList<Body*> &new_body_list,
+ bool keep_old );
+ /**< Private functions called to unite bodies. First form separates the
+ * body list into sheets & solids and unites each group together
+ * separately. Second one unites all bodies together (including sheets
+ * & solids.
+ */
+
+ CubitStatus unite_private( GeometryModifyEngine *gme_ptr,
+ DLIList<Body*> &body_list,
+ DLIList<Body*> &new_body_list,
+ bool keep_old );
+ /**< Private lower level function called to unite bodies
+ */
+
+
+ static CubitStatus clean_up_from_copy_failure( TopologyBridge *old_bridge );
+
+ GeometryModifyEngine * pull_common_surfs( DLIList<RefFace*> &ref_face_list,
+ DLIList<RefFace*> &common_face_list,
+ DLIList<Surface*> &common_surf_list );
+ /**< Pull RefFaces with a common GeometryModifyEngine out of the input
+ * ref_face_list. Place their surfaces in the output RefFace and Surface
+ * lists, and return the common modify engine. Note the function returns
+ * a NULL pointer if a RefFace without a modify engine is found in the
+ * input list.
+ */
+
};
inline void GeometryModifyTool::set_all_edges_imprint( CubitBoolean flag )
@@ -1618,13 +2179,15 @@
inline CubitBoolean GeometryModifyTool::get_all_edges_imprint()
{return allEdgesImprint;}
-// added by Lingyun Pan, Cat
inline CubitBoolean GeometryModifyTool::boolean_regularize()
{return booleanRegularize;}
-
inline void GeometryModifyTool::boolean_regularize(CubitBoolean flag)
-{booleanRegularize= flag;}
+{booleanRegularize = flag;}
+inline CubitBoolean GeometryModifyTool::unite_mixed_models()
+{return uniteMixedModels;}
+inline void GeometryModifyTool::unite_mixed_models(CubitBoolean flag)
+{uniteMixedModels = flag;}
inline void GeometryModifyTool::add_gme(GeometryModifyEngine *gme_ptr)
{
Modified: cgm/branches/cubit/geom/GeometryQueryEngine.cpp
===================================================================
--- cgm/branches/cubit/geom/GeometryQueryEngine.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/GeometryQueryEngine.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -39,3 +39,7 @@
CubitStatus GeometryQueryEngine::get_underlying_surfaces(Surface * surf_ptr,
DLIList<TopologyBridge*>& surf_list)
{ return CUBIT_SUCCESS; }
+
+CubitStatus GeometryQueryEngine::get_underlying_bridges(TopologyBridge* bridge_ptr,
+ DLIList<TopologyBridge*>& bridge_list)
+{ return CUBIT_SUCCESS; }
Modified: cgm/branches/cubit/geom/GeometryQueryEngine.hpp
===================================================================
--- cgm/branches/cubit/geom/GeometryQueryEngine.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/GeometryQueryEngine.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -28,8 +28,10 @@
class GMem;
class TopologyBridge;
+class TopologyEntity;
class GeometryEntity;
class BodySM;
+class Lump;
class Surface;
class Curve;
class Point;
@@ -39,41 +41,43 @@
public:
+ //!- virtual destructor
virtual ~GeometryQueryEngine() {}
- //- virtual destructor
+ //!R CubitStatus
+ //!R- CUBIT_SUCCESS/CUBIT_FAILURE
+ //!I ref_entity_list
+ //!I- A list of RefEntities to be exported or saved to a file.
+ //!I file_name
+ //!I- The name of the file to write to.
+ //!I file_type
+ //!I- An optional type of file.
+ //!- Export the current CUBIT geometry (everything in the Model) to a
+ //!- solid model format. Valid file types are:
+ //!- "ACIS_SAT" -- ACIS ASCII (SAT) file format
+ //!- "ACIS_SAB" -- ACIS BINARY (SAB) file format
+ //!- "ACIS_DEBUG" -- ACIS ASCII debug format
+ //!- "IGES" -- IGES file
+ //!- "STEP" -- STEP file
+ //!I logfile_name
+ //!I- Optional - name of logfile.
+ //!- No logfile gets created for SAB/SAT files, but for IGES and
+ //!- STEP file a logfile always gets created. Default filenames
+ //!- are assigned if one is not given (iges_export.log, step_export.log).
+ //!-
+ //!- The function returns CUBIT_FAILURE if anything goes wrong with
+ //!- export - improper file type, inaccessible file, mismatch between
+ //!- the underlying representation and file type. It returns
+ //!- CUBIT_SUCCESS if everything goes well.
virtual CubitStatus export_solid_model(
DLIList<TopologyBridge*>& bridge_list,
const char* file_name,
const char* file_type,
const CubitString &cubit_version,
const char* logfile_name = NULL ) = 0;
- //R CubitStatus
- //R- CUBIT_SUCCESS/CUBIT_FAILURE
- //I ref_entity_list
- //I- A list of RefEntities to be exported or saved to a file.
- //I file_name
- //I- The name of the file to write to.
- //I file_type
- //I- An optional type of file.
- //- Export the current CUBIT geometry (everything in the Model) to a
- //- solid model format. Valid file types are:
- //- "ACIS_SAT" -- ACIS ASCII (SAT) file format
- //- "ACIS_SAB" -- ACIS BINARY (SAB) file format
- //- "ACIS_DEBUG" -- ACIS ASCII debug format
- //- "IGES" -- IGES file
- //- "STEP" -- STEP file
- //I logfile_name
- //I- Optional - name of logfile.
- //- No logfile gets created for SAB/SAT files, but for IGES and
- //- STEP file a logfile always gets created. Default filenames
- //- are assigned if one is not given (iges_export.log, step_export.log).
- //-
- //- The function returns CUBIT_FAILURE if anything goes wrong with
- //- export - improper file type, inaccessible file, mismatch between
- //- the underlying representation and file type. It returns
- //- CUBIT_SUCCESS if everything goes well.
-
+
+ //! Saves out a temporary geometry file. Entities in list must all be
+ //! of same modeling engine.
virtual CubitStatus save_temp_geom_file(
DLIList<TopologyBridge*> &ref_entity_list,
const char *filename,
@@ -81,12 +85,40 @@
CubitString &created_file,
CubitString &created_file_type ) = 0;
+ //! Imports entities into CGM from file that was embedded in a cub file.
+ //! This file is could an ACIS, granite, catia, or another supported
+ //! solid modeling engine file.
virtual CubitStatus import_temp_geom_file(
FILE* file_ptr,
const char* file_name,
const char* file_type,
DLIList<TopologyBridge*> &bridge_list ) = 0;
+ //!R CubitStatus
+ //!R- CUBIT_SUCCESS/CUBIT_FAILURE
+ //!I file_ptr
+ //!I- A pointer to the file to read (can be NULL for IGES and STEP files).
+ //!I file_type
+ //!I- Type of file.
+ //!- Reads in geometry and creates the necessary Reference entities
+ //!- associated with the input geometry.
+ //!- Valid file types are:
+ //!- "ACIS_SAT" -- ACIS ASCII (SAT) file format
+ //!- "ACIS_SAB" -- ACIS BINARY (SAB) file format
+ //!- "IGES" -- IGES file
+ //!- "STEP" -- STEP file
+ //!I heal_step - auto-healing of step bodies on import. This is recommended
+ //! because they always need it.
+ //!I import_bodies (etc...)
+ //!I- Should bodies be import.
+ //!- Function can selectively import solid bodies, free surfaces, free
+ //!- curves, or free vertices. For example, the user may not want
+ //!- to import any free entities.
+ //!-
+ //!- The function returns CUBIT_FAILURE if anything goes wrong with
+ //!- import - improper file type, inaccessible file, mismatch between
+ //!- the underlying representation and file type. It returns
+ //!- CUBIT_SUCCESS if everything goes well.
virtual CubitStatus import_solid_model(
const char* file_name,
const char* file_type,
@@ -100,31 +132,6 @@
bool import_vertices = true,
bool free_surfaces = true
) = 0;
- //R CubitStatus
- //R- CUBIT_SUCCESS/CUBIT_FAILURE
- //I file_ptr
- //I- A pointer to the file to read (can be NULL for IGES and STEP files).
- //I file_type
- //I- Type of file.
- //- Reads in geometry and creates the necessary Reference entities
- //- associated with the input geometry.
- //- Valid file types are:
- //- "ACIS_SAT" -- ACIS ASCII (SAT) file format
- //- "ACIS_SAB" -- ACIS BINARY (SAB) file format
- //- "IGES" -- IGES file
- //- "STEP" -- STEP file
- //I heal_step - auto-healing of step bodies on import. This is recommended
- // because they always need it.
- //I import_bodies (etc...)
- //I- Should bodies be import.
- //- Function can selectively import solid bodies, free surfaces, free
- //- curves, or free vertices. For example, the user may not want
- //- to import any free entities.
- //-
- //- The function returns CUBIT_FAILURE if anything goes wrong with
- //- import - improper file type, inaccessible file, mismatch between
- //- the underlying representation and file type. It returns
- //- CUBIT_SUCCESS if everything goes well.
virtual CubitStatus get_underlying_curves(Curve * curve_ptr,
DLIList<TopologyBridge*>& curve_list) ;
@@ -132,6 +139,8 @@
// - curves from virtual curves.
virtual CubitStatus get_underlying_surfaces(Surface * surf_ptr,
DLIList<TopologyBridge*>& surf_list) ;
+ virtual CubitStatus get_underlying_bridges(TopologyBridge* bridge_ptr,
+ DLIList<TopologyBridge*>& bridge_list);
virtual CubitStatus get_intersections(
Curve* ref_edge1, CubitVector& point1,
@@ -185,24 +194,29 @@
//- on those entities. Supports vertices, curves, surfaces, volumes and bodies.
virtual void delete_solid_model_entities(DLIList<BodySM*>& body_list) const = 0;
- virtual CubitStatus delete_solid_model_entities( BodySM* body_ptr ) const = 0;
- virtual CubitStatus delete_solid_model_entities(Surface* surf_ptr ) const = 0;
- virtual CubitStatus delete_solid_model_entities( Curve* curve_ptr ) const = 0;
- virtual CubitStatus delete_solid_model_entities( Point* point_ptr ) const = 0;
+ virtual CubitStatus delete_solid_model_entities( BodySM* body_ptr ) const = 0;
+ virtual CubitStatus delete_solid_model_entities(Surface* surf_ptr ) const = 0;
+ virtual CubitStatus delete_solid_model_entities( Curve* curve_ptr ) const = 0;
+ virtual CubitStatus delete_solid_model_entities( Point* point_ptr ) const = 0;
//- Deletes the solid model entities associcated with the input
//- free-floating RefEntity. If the input RefEntity is not free-floating,
//- then its underlying ACIS ENTITYs are not deleted and CUBIT_FAILURE
//- is returned.
//- Returns CUBIT_SUCCESS if all went well, otherwise, CUBIT_FAILURE.
- virtual CubitStatus fire_ray(BodySM *body,
- const CubitVector &ray_start_point,
- const CubitVector &unit_direction,
- DLIList<double> &ray_params,
- DLIList<GeometryEntity*> *entity_list = NULL
- ) const = 0;
- //- fire a ray at the specified body, returning the entities hit and
- //- the parameters along the ray; return CUBIT_FAILURE 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 = 0;
+ //- 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. 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 get_isoparametric_points(Surface* ref_face_ptr,
int &nu, int &nv,
@@ -226,6 +240,9 @@
//O vector showning transform.
//O-Computes the transform from the transformed body.
+ virtual int curve_is_on_ignored_surface(Curve *curve,
+ Surface *surf) { return 0; }
+
virtual const char* modeler_type() = 0;
virtual int get_major_version() = 0;
virtual int get_minor_version() = 0;
@@ -251,9 +268,6 @@
//- Set solid modeler options
virtual CubitStatus get_graphics( Surface* surface_ptr,
- int& number_of_triangles,
- int& number_of_points,
- int& number_of_facets,
GMem* gMem,
unsigned short normal_tolerance=15,
double distance_tolerance=0,
@@ -263,19 +277,13 @@
//I ref_face_ptr
//I- The RefFAce for which hoops facetting information will be
//I- gathered.
- //O- The number of polygons (triangles) needed for facetting.
- //O number_points
- //O- The number of points needed for facetting
- //O number_Facets
- //O- The number of facets needed for facetting.
//O gMem
//O- The sturage place for facets (and points).
- //= This function gathersw and outputs ACIS facet (and point)
+ //= This function gathers and outputs ACIS facet (and point)
//- information for hoops involved in facetting an RefFace. If
//- all goes well, CUBIT_Success is retuned.
virtual CubitStatus get_graphics( Curve* curve_ptr,
- int& num_points,
GMem* gMem = NULL,
double tolerance = 0.0 ) const = 0;
//R CubitStatus
@@ -310,6 +318,10 @@
virtual CubitBoolean bodies_overlap (BodySM *body_ptr_1,
BodySM *body_ptr_2 ) const = 0;
+ virtual CubitBoolean volumes_overlap (Lump *lump1, Lump *lump2 ) const = 0;
+
+ virtual TopologyBridge* get_visible_entity_at_point(TopologyBridge* hidden_tb, CubitVector* point){return NULL;};
+
protected:
private:
Modified: cgm/branches/cubit/geom/GeometryQueryTool.cpp
===================================================================
--- cgm/branches/cubit/geom/GeometryQueryTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/GeometryQueryTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -9,14 +9,15 @@
#include "ProgressTool.hpp"
#include "GeometryDefines.h"
#include "GeometryEntity.hpp"
+#include "GeomMeasureTool.hpp"
#include "GeometryQueryTool.hpp"
+#include "GeometryModifyTool.hpp"
#include "AnalyticGeometryTool.hpp"
#include "MergeTool.hpp"
#include "GeometryQueryEngine.hpp"
#include "DAG.hpp"
#include "TBOwnerSet.hpp"
-
#include "RefEntity.hpp"
#include "RefEntityFactory.hpp"
#include "BasicTopologyEntity.hpp"
@@ -73,10 +74,19 @@
#include "ModelQueryEngine.hpp"
#include "CubitTransformMatrix.hpp"
+#include "CubitUndo.hpp"
+#include "GMem.hpp"
+#include "IntersectionTool.hpp"
-double GeometryQueryTool::geometryToleranceFactor = 500.0;
+#include "GfxPreview.hpp" //DJQ
+#include "GfxDebug.hpp" //DJQ
+
+double GeometryQueryTool::geometryToleranceFactor = DEFAULT_GEOM_FACTOR;
GeometryQueryTool* GeometryQueryTool::instance_ = 0;
CubitBoolean GeometryQueryTool::useFacetBBox = CUBIT_FALSE;
+CubitBoolean GeometryQueryTool::trackMergedAwayEnts = CUBIT_FALSE;
+DLIList<int> GeometryQueryTool::uidsOfImportingEnts;
+int GeometryQueryTool::entitiesMergedAway = 0;
const int GeometryQueryTool::CGM_MAJOR_VERSION = 10;
const int GeometryQueryTool::CGM_MINOR_VERSION = 0;
@@ -86,12 +96,13 @@
CubitBoolean GeometryQueryTool::bboxMergeTest = CUBIT_TRUE;
int GeometryQueryTool::internalSurfaceMergeTest = 2; // 0=off, 1=all, 2=splines only
#else
+//test
// Cat prefers to avoid internal checks altogether as they cause problems with splines
CubitBoolean GeometryQueryTool::bboxMergeTest = CUBIT_FALSE;
int GeometryQueryTool::internalSurfaceMergeTest = 0; // 0=off, 1=all, 2=splines only
#endif // ndef CAT
-double GeometryQueryTool::curveSliverCleanUpTolerance = geometryToleranceFactor*GEOMETRY_RESABS ;
+double GeometryQueryTool::curveSliverCleanUpTolerance = geometryToleranceFactor*GEOMETRY_RESABS ;
double GeometryQueryTool::surfaceSliverCleanUpTolerance = -1.0;
// static CubitStatus import_actuate(DLIList<RefEntity*> &entity_list);
@@ -158,7 +169,6 @@
GeometryQueryTool::~GeometryQueryTool ()
{
-
//Kill the geometry query engine(s).
int i;
for (i = gqeList.size(); i > 0; i--)
@@ -168,59 +178,24 @@
gqeList.clean_out();
instance_ = NULL;
-
}
//-------------------------------------------------------------------------
-// Purpose : Reads a geometry file (named fileName). If the file
-// cannot be found in the current directory, and if includePath
-// is not NULL, the include path specified by includePath is
-// added to the file name, and it is searched in the given
-// order. The file type specified in the "type" argument
-// determines what type of geometry file it is -- the default
-// is an ACIS SAT file.
+// Purpose : Function to delete instance variable
//
// Special Notes :
//
-// Creator : Xuechen Liu
+// Creator : Corey Ernst
//
-// Creation Date : 07/11/96
+// Creation Date : 12/31/07
//-------------------------------------------------------------------------
-CubitStatus GeometryQueryTool::read_geometry_file(char const* fileName,
- const char* includePath,
- const char* type)
+void GeometryQueryTool::delete_instance()
{
- CubitStatus result = CUBIT_SUCCESS;
-
- FILE* file = fopen(fileName, "r");
-
- // If the file is not in the current directory, add a path to it.
- CubitString file_and_path;
- if (!file && includePath)
- {
- file_and_path = includePath;
- file_and_path += CubitString("/");
- file_and_path += CubitString(fileName);
- file = fopen(file_and_path.c_str(), "r");
- }
- else
- file_and_path = fileName;
-
- // If the file is opened successfully.
- if (file)
- {
- fclose(file);
- result = import_solid_model(file_and_path.c_str(), type);
- if (result != CUBIT_SUCCESS)
- PRINT_ERROR("The specified file type is not supported!\n");
- }
- else
- {
- PRINT_ERROR("Cannot open geometry file: %s .\n", fileName);
- result = CUBIT_FAILURE;
- }
-
- return result;
+ if( NULL != instance_ )
+ {
+ delete instance_;
+ instance_ = NULL;
+ }
}
//-------------------------------------------------------------------------
@@ -240,7 +215,7 @@
std::list<CubitString> &types_written)
{
int i;
-
+// clear all attributes
if (ref_entity_list.size() == 0) {
// All bodies are to be exported
@@ -508,97 +483,320 @@
}
//-------------------------------------------------------------------------
-// Purpose : Fire a ray and see which entities it hits
+// Purpose : Fire a ray at a list of entities and return the
+// parameters along the ray (distance from origin of ray)
+// where it hits the entities; optionally find the
+// corresponding entities it hit.
//
// Special Notes :
//
-// Creator : Tim Tautges (this wrapper function added by
-// Brett Clark)
+// Creator : Steve Storm
//
-// Creation Date : 3/18/97
+// Creation Date : 3/29/2007
//-------------------------------------------------------------------------
+CubitStatus GeometryQueryTool::fire_ray( CubitVector &origin,
+ CubitVector &direction,
+ DLIList<RefEntity*> &at_entity_list,
+ DLIList<double> &ray_params,
+ int max_hits,
+ double ray_radius,
+ DLIList<RefEntity*> *hit_entity_list_ptr )
+{
+ int i;
-int GeometryQueryTool::fire_ray(Body* body,
- const CubitVector ray_point,
- const CubitVector unit,
- DLIList<double>& ray_params,
- DLIList<RefEntity*> *entity_list)
-{
- BodySM* bodysm = body->get_body_sm_ptr();
- if (bodysm == NULL)
+ // Do this in a way to account for the case if they happen to be from
+ // different geometry engines (could easily occur with virtual geometry)
+
+ DLIList<TopologyEntity*> te_fire_at_list;
+ DLIList<TopologyEntity*> te_hit_entity_list;
+ DLIList<TopologyEntity*> *te_hit_entity_list_ptr = 0;
+ if( hit_entity_list_ptr )
+ te_hit_entity_list_ptr = &te_hit_entity_list;
+
+ GeometryQueryEngine *gqe = 0;
+ GeometryQueryEngine *gqe_last = 0;
+ RefEntity *ref_entity_ptr;
+ TopologyEntity *topo_ptr;
+
+ int loc_max_hits = max_hits;
+ CubitBoolean hits_limited = CUBIT_FALSE;
+ if( max_hits > 0 )
+ hits_limited = CUBIT_TRUE;
+
+ // Note we care about order
+ at_entity_list.reset();
+ for( i=at_entity_list.size(); i--; )
{
- PRINT_ERROR("Body %d is invalid -- no attached BodySM.\n", body->id());
- return 0;
+ ref_entity_ptr = at_entity_list.get_and_step();
+
+ topo_ptr = CAST_TO( ref_entity_ptr, TopologyEntity );
+ if( !topo_ptr )
+ {
+ PRINT_ERROR( "Couldnt get topo_ptr\n" );
+ continue;
+ }
+
+ gqe = topo_ptr->get_geometry_query_engine();
+ if( !gqe )
+ {
+ PRINT_ERROR( "Unable to find geometry engine associated with an entity!\n" );
+ return CUBIT_FAILURE;
+ }
+
+ if( !gqe_last ) gqe_last = gqe;
+ if( gqe != gqe_last )
+ {
+ if( hits_limited == CUBIT_TRUE )
+ {
+ loc_max_hits = max_hits - ray_params.size();
+ if( loc_max_hits <= 0 )
+ break;
+ }
+
+ if( fire_ray( origin, direction, te_fire_at_list, ray_params,
+ loc_max_hits, ray_radius, te_hit_entity_list_ptr ) == CUBIT_FAILURE )
+ return CUBIT_FAILURE;
+
+ // Reset
+ gqe_last = gqe;
+ te_fire_at_list.clean_out();
+ }
+
+ te_fire_at_list.append( topo_ptr );
}
- DLIList<GeometryEntity*>* geom_list = NULL;
- if (entity_list)
- geom_list = new DLIList<GeometryEntity*>;
+ // Do the last ray fire, if necessary
+ if( hits_limited == CUBIT_TRUE )
+ loc_max_hits = max_hits - ray_params.size();
+ if( hits_limited==CUBIT_FALSE || loc_max_hits>0 )
+ if( fire_ray( origin, direction, te_fire_at_list, ray_params,
+ loc_max_hits, ray_radius, te_hit_entity_list_ptr ) == CUBIT_FAILURE )
+ return CUBIT_FAILURE;
- int rval = bodysm->get_geometry_query_engine()->
- fire_ray(bodysm, ray_point, unit, ray_params, geom_list );
+ if( hit_entity_list_ptr )
+ {
+ // Find RefEntities from TopologyEntities
+ te_hit_entity_list.reset();
+ for( i=te_hit_entity_list.size(); i--; )
+ {
+ topo_ptr = te_hit_entity_list.get_and_step();
+ if( !topo_ptr )
+ {
+ hit_entity_list_ptr->append( 0 );
+ continue;
+ }
- if (geom_list)
+ ref_entity_ptr = CAST_TO( topo_ptr, RefEntity );
+ hit_entity_list_ptr->append( ref_entity_ptr );
+ }
+ }
+
+ // Now, make sure we don't have more hits than asked for
+ if( hits_limited == CUBIT_TRUE )
{
- geom_list->reset();
- for (int i = geom_list->size(); i--; )
+ if( ray_params.size() <= max_hits )
+ return CUBIT_SUCCESS;
+
+ for( i=ray_params.size()-max_hits; i--; )
{
- TopologyEntity* topo_ent = entity_from_bridge(geom_list->get_and_step());
- RefEntity* ref_ent = dynamic_cast<RefEntity*>(topo_ent);
- if (ref_ent)
- entity_list->append(ref_ent);
+ ray_params.last();
+ ray_params.remove();
+ if( hit_entity_list_ptr )
+ {
+ hit_entity_list_ptr->last();
+ hit_entity_list_ptr->remove();
+ }
}
- delete geom_list;
}
- return rval ;
+ return CUBIT_SUCCESS;
}
-CubitStatus GeometryQueryTool::import_temp_geom_file(FILE* file_ptr,
- const char* file_type )
+//-------------------------------------------------------------------------
+// Purpose : Fire a ray at a list of entities and return the
+// parameters along the ray (distance from origin of ray)
+// where it hits the entities; optionally find the
+// corresponding entities it hit.
+//
+// Special Notes : All entities must be from the same geometry engine.
+//
+// Creator : Steve Storm
+//
+// Creation Date : 5/19/2007
+//-------------------------------------------------------------------------
+CubitStatus GeometryQueryTool::fire_ray( CubitVector &origin,
+ CubitVector &direction,
+ DLIList<TopologyEntity*> &at_entity_list,
+ DLIList<double> &ray_params,
+ int max_hits,
+ double ray_radius,
+ DLIList<TopologyEntity*> *hit_entity_list_ptr )
{
- // reset the attribImporteds flags to facilitate attribute reporting
-// CubitAttrib::clear_attrib_importeds();
+ if( !at_entity_list.size() )
+ return CUBIT_SUCCESS;
- // Use the default MQE to import a list of ToplogyBridges from the file.
- gqeList.reset();
- DLIList<TopologyBridge*> bridge_list;
- GeometryQueryEngine *gqe;
+ TopologyEntity *topo_ptr = at_entity_list.get();
+
+ GeometryQueryEngine *gqe = topo_ptr->get_geometry_query_engine();
+ if( !gqe )
+ {
+ PRINT_ERROR( "Unable to find geometry engine associated with an entity!\n" );
+ return CUBIT_FAILURE;
+ }
+
+
+ DLIList<TopologyBridge*> tb_list;
int i;
- CubitStatus status = CUBIT_FAILURE;
- for(i=gqeList.size(); i--; )
+ at_entity_list.reset();
+ for( i=at_entity_list.size(); i--; )
{
- gqe = gqeList.get_and_step();
- status = gqe->import_temp_geom_file( file_ptr, "dummy",file_type, bridge_list );
- if( status == CUBIT_SUCCESS ) //done...get out
- break;
+ topo_ptr = at_entity_list.get_and_step();
+ DLIList<TopologyBridge*> bridge_list;
+ topo_ptr->bridge_manager()->get_bridge_list( bridge_list );
+ bridge_list.reset();
+ tb_list.append( bridge_list.get() );
}
- if( bridge_list.size() == 0 )
- return status;
+ // Setup temporary variables to pass
+ DLIList<double> tmp_ray_params;
+ DLIList<TopologyBridge*> tb_hit_list;
+ DLIList<TopologyBridge*> *tb_hit_list_ptr = NULL;
+ if( hit_entity_list_ptr )
+ tb_hit_list_ptr = &tb_hit_list;
- for (IGESet::iterator itor = igeSet.begin(); itor != igeSet.end(); ++itor)
- (*itor)->import_geometry(bridge_list);
+ // Do the ray fire. Note we will sort the hits by distance and append to the output lists.
+ if( gqe->fire_ray( origin, direction, tb_list, tmp_ray_params,
+ max_hits, ray_radius, tb_hit_list_ptr ) == CUBIT_FAILURE )
+ return CUBIT_FAILURE;
- DLIList<RefEntity*> dummy_list;
- status = construct_refentities(bridge_list, &dummy_list);
+ tmp_ray_params.reset();
+ if( tb_hit_list_ptr) tb_hit_list_ptr->reset();
- // report attribs imported
-// CubitAttrib::report_attrib_importeds();
+ // Append to output lists
+ ray_params += tmp_ray_params;
- // now return
- return status;
+ // Get the TE's from the TopologyBridges
+ if( hit_entity_list_ptr )
+ {
+ // First need to make sure that the entities hit are visible...entities hit
+ // may be hidden under virtual entities....we need to get the visible
+ // entities.
+ DLIList<TopologyBridge*> vis_tb_hit_list;
+ DLIList<CubitVector*> cv_list;
+
+ CubitVector *loc_ptr;
+ double param;
+ tmp_ray_params.reset();
+ for( i=tmp_ray_params.size(); i--; )
+ {
+ param = tmp_ray_params.get_and_step();
+
+ loc_ptr = new CubitVector;
+ origin.next_point( direction, param, *loc_ptr );
+ cv_list.append( loc_ptr );
+ }
+
+
+ TopologyBridge *bridge_ptr;
+ TopologyBridge *tb_owner = 0;
+ for( i=0; i<tb_hit_list_ptr->size(); i++ )
+ {
+ bool added_entity = false;
+ bridge_ptr = tb_hit_list_ptr->get_and_step();
+
+ TopologyBridge *visible_tb = NULL;
+ TBOwner* o2 = bridge_ptr->owner();
+
+ bool broke_early = false;
+ BridgeManager* bridge_manager2;
+ while (!(bridge_manager2 = dynamic_cast<BridgeManager*>(o2)))
+ {
+ if (TopologyBridge* bridge2 = dynamic_cast<TopologyBridge*>(o2))
+ {
+ GeometryQueryEngine* gqe2 = bridge2->get_geometry_query_engine();
+
+ //Let the VQE handle the work
+ visible_tb = gqe2->get_visible_entity_at_point(bridge_ptr, cv_list[i]);
+ if (visible_tb)
+ o2 = visible_tb->owner();
+ else
+ o2 = bridge2->owner();
+ }
+
+ else if(TBOwnerSet* set = dynamic_cast<TBOwnerSet*>(o2))
+ {
+ DLIList<TopologyBridge*> list2;
+ set->get_owners(list2);
+ list2.reset();
+
+ // This had better be the Virtual QE.
+ GeometryQueryEngine* gqe2 = list2.get()->get_geometry_query_engine();
+
+ //Let the VQE handle the work
+ visible_tb = gqe2->get_visible_entity_at_point(bridge_ptr, cv_list[i]);
+ if (visible_tb)
+ o2 = visible_tb->owner();
+ else
+ {
+ broke_early = true;
+ break;
+ }
+ }
+ else
+ {
+ broke_early = true;
+ break;
+ }
+ }
+
+ if (!broke_early)
+ visible_tb = bridge_manager2->topology_bridge();
+
+
+ if( visible_tb )
+ {
+ topo_ptr = visible_tb->topology_entity();
+ hit_entity_list_ptr->append( topo_ptr );
+ }
+ else
+ hit_entity_list_ptr->append( 0 );
+ }
+
+
+ // Free memory
+ while( cv_list.size() ) delete cv_list.pop();
+ }
+
+ // Sort ray_params (low to high) and sort hit_entity_list_ptr 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)
+ std::map<double, TopologyEntity*> temp_map;
+ for (i=0; i<ray_params.size(); i++)
+ temp_map.insert(std::map<double,
+ TopologyEntity*>::value_type( ray_params.get_and_step(),
+ hit_entity_list_ptr ? hit_entity_list_ptr->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_ptr) hit_entity_list_ptr->clean_out();
+
+ std::map<double, TopologyEntity*>::iterator iter;
+ for (iter=temp_map.begin(); iter != temp_map.end(); iter++)
+ {
+ ray_params.append(iter->first);
+ if( hit_entity_list_ptr) hit_entity_list_ptr->append(iter->second);
+ }
+
+ return CUBIT_SUCCESS;
}
-
//-------------------------------------------------------------------------
-// Purpose : Reads in geometry in geometry and creates
-// the necessary Reference entities associated with the
-// input geometry. Has ability to read selectively read
-// in either bodies, free surfaces, free curves or free
-// vertices from the file.
+// Purpose : Reads in geometry and creates the necessary Reference
+// entities associated with the input geometry. Has ability
+// to read selectively read in either bodies, free surfaces,
+// free curves or free vertices from the file.
//
// Valid file types are:
// "ACIS_SAT" -- ACIS ASCII (SAT) file format
@@ -630,6 +828,9 @@
return CUBIT_FAILURE;
}
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state();
+
// reset the attribImporteds flags to facilitate attribute reporting
// CubitAttrib::clear_attrib_importeds();
@@ -648,8 +849,26 @@
(*itor)->import_geometry(bridge_list);
bridge_list.reset();
- status = construct_refentities(bridge_list, imported_entities);
+ DLIList<RefEntity*> tmp_ent_list;
+ status = construct_refentities(bridge_list, &tmp_ent_list);
+ if( imported_entities )
+ (*imported_entities) += tmp_ent_list;
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ if( tmp_ent_list.size() && status == CUBIT_SUCCESS )
+ CubitUndo::note_result_entities( tmp_ent_list );
+ else
+ CubitUndo::remove_last_undo();
+ }
+
+ //clear out all attributes that were set to actuate
+ DLIList<RefEntity*> all_ents;
+ RefEntity::get_all_child_ref_entities( tmp_ent_list, all_ents );
+ all_ents += tmp_ent_list;
+ CubitAttribUser::clear_all_simple_attrib_set_to_actuate( all_ents );
+
// report attribs imported
// CubitAttrib::report_attrib_importeds();
@@ -707,7 +926,8 @@
}
else if( (surface_ptr = dynamic_cast<Surface*>(bridge_ptr) ) != NULL )
{
- RefFace* face_ptr = make_free_RefFace( surface_ptr );
+ bool is_free_face = true;
+ RefFace* face_ptr = make_free_RefFace( surface_ptr, is_free_face );
if( face_ptr )
{
face_list.append( face_ptr );
@@ -975,11 +1195,23 @@
body->id(), timer.cpu_secs() );
if( body_created )
+ {
CubitObserver::notify_static_observers( body, VGI_BODY_CONSTRUCTED );
+ CGMHistory::Event evt(CGMHistory::TOP_LEVEL_ENTITY_CREATED, body);
+ const_cast<CGMHistory&>(mHistory).add_event(evt);
+ }
else if( body_modified )
+ {
body->notify_all_observers( TOPOLOGY_MODIFIED );
+ CGMHistory::Event evt(CGMHistory::TOPOLOGY_CHANGED, body);
+ const_cast<CGMHistory&>(mHistory).add_event(evt);
+ }
else if( vol_modified )
+ {
body->notify_all_observers( GEOMETRY_MODIFIED );
+ CGMHistory::Event evt(CGMHistory::GEOMETRY_CHANGED, body);
+ const_cast<CGMHistory&>(mHistory).add_event(evt);
+ }
PRINT_DEBUG_3("Updated graphics for Body %d in %f seconds.\n",
body->id(), timer.cpu_secs() );
@@ -1072,7 +1304,11 @@
if (volume->deactivated())
volume_modified = false;
else if(!volume_created && volume_modified )
+ {
volume->notify_all_observers( TOPOLOGY_MODIFIED );
+ CGMHistory::Event evt(CGMHistory::TOPOLOGY_CHANGED, volume);
+ const_cast<CGMHistory&>(mHistory).add_event(evt);
+ }
return volume;
}
@@ -1295,9 +1531,19 @@
// Get/construct RefFace for surface.
bool face_created = false;
bool face_modified = false;
+ bool face_modified2 = false;
RefFace* face = CAST_TO( surface_ptr->topology_entity(), RefFace );
if( !face )
+ {
face = dynamic_cast<RefFace*>(check_mergeable_refentity(surface_ptr));
+
+ //Including this call in here in case the surface a composite and
+ //hidden curves need to be removed in the graphics.
+ if( face )
+ {
+ face_modified2 = true;
+ }
+ }
if( !face )
{
face = RefEntityFactory::instance()->construct_RefFace(surface_ptr);
@@ -1527,7 +1773,19 @@
}
if( !face_created && face_modified && !face->deactivated() )
+ {
face->notify_all_observers( GEOMETRY_TOPOLOGY_MODIFIED );
+ CGMHistory::Event evt2(CGMHistory::TOPOLOGY_CHANGED, face);
+ const_cast<CGMHistory&>(mHistory).add_event(evt2);
+ CGMHistory::Event evt(CGMHistory::GEOMETRY_CHANGED, face);
+ const_cast<CGMHistory&>(mHistory).add_event(evt);
+ }
+ else if(face_modified2)
+ {
+ face->notify_all_observers(TOPOLOGY_MODIFIED);
+ CGMHistory::Event evt(CGMHistory::TOPOLOGY_CHANGED, face);
+ const_cast<CGMHistory&>(mHistory).add_event(evt);
+ }
if (merged)
MergeTool::instance()->set_merge_occurance(CUBIT_TRUE);
@@ -1557,8 +1815,8 @@
if (num_bridges < 2) // isn't merged
return CUBIT_FAILURE;
- // Get some other Surface in merged RefFace to compare
- // topology with.
+ // Get some other Surface in merged RefFace to compare
+ // topology with.
DLIList<TopologyBridge*> bridge_list(num_bridges);
face->bridge_manager()->get_bridge_list(bridge_list);
bridge_list.reset();
@@ -1694,6 +1952,8 @@
assert(curves.size() == 1);
if (curves.get()->owner() != curve->owner())
{
+ merge->bridge_manager()->remove_bridge(merged_coedge);
+ assert(merge->get_parents());
merge = 0;
}
}
@@ -1783,6 +2043,7 @@
bool reversed = (CUBIT_REVERSED == curve_ptr->bridge_sense());
bool merged = edge->bridge_manager()->number_of_bridges() > 1;
+
// Construct RefVertices
DLIList<Point*> points(2);
curve_ptr->points( points );
@@ -1833,8 +2094,22 @@
points.last();
if( points.get()->topology_entity() != end_vertex )
merged = false;
+
+ //perhaps the bridge sense just needs to be swapped
+ if( merged == false )
+ {
+ points.reverse();
+ points.reset();
+ Point *point1 = points.get_and_step();
+ Point *point2 = points.get_and_step();
+ if( point1->topology_entity() == start_vertex &&
+ point2->topology_entity() == end_vertex )
+ {
+ merged = true;
+ curve_ptr->reverse_bridge_sense();
+ }
+ }
}
-
// Unmerge the curve, if necessary.
if( !merged && edge->bridge_manager()->number_of_bridges() > 1 )
{
@@ -1859,6 +2134,7 @@
// Create new RefEdge for un-merged curve
edge = RefEntityFactory::instance()->construct_RefEdge( curve_ptr );
+ PRINT_WARNING("Creating edge %d that was supposed to be merged\n", edge->id() );
edge_created = true;
// If we had swapped the vertex order because the curve
@@ -1943,7 +2219,13 @@
}
if( !edge_created && edge_modified && !edge->deactivated() )
+ {
edge->notify_all_observers( GEOMETRY_TOPOLOGY_MODIFIED );
+ CGMHistory::Event evt2(CGMHistory::TOPOLOGY_CHANGED, edge);
+ const_cast<CGMHistory&>(mHistory).add_event(evt2);
+ CGMHistory::Event evt(CGMHistory::GEOMETRY_CHANGED, edge);
+ const_cast<CGMHistory&>(mHistory).add_event(evt);
+ }
if (merged)
MergeTool::instance()->set_merge_occurance(CUBIT_TRUE);
@@ -1972,19 +2254,29 @@
RefEntity *re_ptr = NULL;
- if (csa_ptr != NULL) {
-
+ if (csa_ptr != NULL)
+ {
// from the csa, call CAMP to get the partner, if one exists
// (and return it)
csa_ptr->int_data_list()->reset();
int merge_id = *(csa_ptr->int_data_list()->get());
+
+ bool unique_append = false;
+ if( GeometryQueryTool::trackMergedAwayEnts )
+ unique_append = GeometryQueryTool::uidsOfImportingEnts.append_unique( merge_id );
+
ToolDataUser *tdu = TDUniqueId::find_td_unique_id(merge_id);
TopologyEntity *te = dynamic_cast<TopologyEntity*>(tdu);
CubitSense sense = CAMergePartner::get_bridge_sense( csa_ptr );
//We found the merge partner.....
- if (te != NULL) {
+ if (te != NULL)
+ {
+ //it's the first time you found this uid and you found an entity
+ //
+ if(GeometryQueryTool::trackMergedAwayEnts && unique_append )
+ GeometryQueryTool::entitiesMergedAway++;
// assume this merge attrib will be actuated, so remove the csa
bridge->remove_simple_attribute_virt(csa_ptr);
@@ -2135,7 +2427,6 @@
// Create a RefVertex from this Point.
vertex = RefEntityFactory::instance()->construct_RefVertex(point);
}
-
assert(vertex != NULL);
return vertex;
@@ -2153,7 +2444,8 @@
//
// Creation Date : 3/27/99
//-------------------------------------------------------------------------
-RefFace* GeometryQueryTool::make_free_RefFace(Surface *surface_ptr ) const
+RefFace* GeometryQueryTool::make_free_RefFace(Surface *surface_ptr,
+ bool is_free_face ) const
{
RefFace* ref_face_ptr = make_RefFace( surface_ptr );
if( !ref_face_ptr )
@@ -2163,9 +2455,14 @@
return 0;
}
-
// Add the new ref_face to the graphics
- ref_face_ptr->notify_all_observers( FREE_REF_ENTITY_GENERATED );
+ if( is_free_face )
+ {
+ ref_face_ptr->notify_all_observers( FREE_REF_ENTITY_GENERATED );
+
+ CGMHistory::Event evt(CGMHistory::TOP_LEVEL_ENTITY_CREATED, ref_face_ptr);
+ const_cast<CGMHistory&>(mHistory).add_event(evt);
+ }
return ref_face_ptr;
}
@@ -2191,6 +2488,9 @@
}
ref_edge_ptr->notify_all_observers( FREE_REF_ENTITY_GENERATED );
+
+ CGMHistory::Event evt(CGMHistory::TOP_LEVEL_ENTITY_CREATED, ref_edge_ptr);
+ const_cast<CGMHistory&>(mHistory).add_event(evt);
return ref_edge_ptr;
}
@@ -2217,6 +2517,9 @@
// Add the new ref_vertex to the graphics
ref_vertex_ptr->notify_all_observers( FREE_REF_ENTITY_GENERATED );
+
+ CGMHistory::Event evt(CGMHistory::TOP_LEVEL_ENTITY_CREATED, ref_vertex_ptr);
+ const_cast<CGMHistory&>(mHistory).add_event(evt);
return ref_vertex_ptr;
}
@@ -2275,6 +2578,8 @@
{
BodySM* bodysm = body_ptr->get_body_sm_ptr();
DLIList<RefEntity*> merged_children;
+ DLIList<RefFace*> faces_to_reverse;
+ DLIList<RefEdge*> edges_to_reverse;
if (!bodysm)
{
PRINT_ERROR("Body %d is invalid -- no attached BodySM.\n",body_ptr->id());
@@ -2304,6 +2609,49 @@
}
}
+// if( tmp_merged_children.size() )
+// MergeTool::instance()->unmerge( body_ptr );
+
+ //fix up merged children -- some might need to be reversed
+ for(i=merged_children.size(); i--; )
+ {
+ RefEntity *merged_child = merged_children.get_and_step();
+ BasicTopologyEntity *bte = static_cast<BasicTopologyEntity*>(merged_child);
+
+ //get the first bridge of the entity
+ DLIList<TopologyBridge*> child_bridge_list;
+ bte->bridge_manager()->get_bridge_list( child_bridge_list );
+ child_bridge_list.reset();
+ TopologyBridge *first_bridge = child_bridge_list.get_and_step();
+
+ //if it is not the body we're deleting just continue
+ BodySM *owning_body = first_bridge->bodysm();
+ if( owning_body != bodysm )
+ continue;
+
+ RefFace *ref_face = CAST_TO( merged_child, RefFace );
+ if( ref_face )
+ {
+ faces_to_reverse.append( ref_face );
+ continue;
+ }
+ RefEdge *ref_edge = CAST_TO( merged_child, RefEdge );
+ if( ref_edge )
+ {
+ //get merged_child's first topology bridge
+ TopologyBridge *second_bridge = child_bridge_list.get_and_step();
+
+ Curve *first_curve = CAST_TO( first_bridge, Curve );
+ Curve *second_curve = CAST_TO( second_bridge, Curve );
+
+ CubitSense relative_sense = first_curve->relative_sense( second_curve );
+
+ if( relative_sense == CUBIT_REVERSED )
+ edges_to_reverse.append( ref_edge );
+ continue;
+ }
+ }
+
// Ask owning model engine to delete the TopologyBridges
GeometryQueryEngine* gqe = bodysm->get_geometry_query_engine();
gqe->delete_solid_model_entities(bodysm);
@@ -2314,11 +2662,24 @@
(*itor)->clean_out_deactivated_geometry();
}
+ int i;
+ for( i=faces_to_reverse.size(); i--; )
+ faces_to_reverse.get_and_step()->reverse_normal();
+ for( i=edges_to_reverse.size(); i--; )
+ edges_to_reverse.get_and_step()->reverse_tangent();
+
//regenerate graphics of merged entities
- int i;
for( i=merged_children.size(); i--; )
- merged_children.get_and_step()->notify_all_observers( GEOMETRY_MODIFIED );
+ {
+ RefEntity* child = merged_children.get_and_step();
+ child->notify_all_observers( GEOMETRY_TOPOLOGY_MODIFIED );
+ CGMHistory::Event evt2(CGMHistory::TOPOLOGY_CHANGED, child);
+ const_cast<CGMHistory&>(mHistory).add_event(evt2);
+ CGMHistory::Event evt(CGMHistory::GEOMETRY_CHANGED, child);
+ const_cast<CGMHistory&>(mHistory).add_event(evt);
+ }
+
// Check if body actually got deleted.
return destroy_dead_entity( body_ptr );
}
@@ -2685,7 +3046,12 @@
const CubitVector &vector2,
double tolerance_factor)
{
- return (vector1.within_tolerance( vector2, GEOMETRY_RESABS * tolerance_factor ));
+ double tol = GEOMETRY_RESABS * tolerance_factor;
+ tol *= tol;
+ double dist_sq = vector1.distance_between_squared(vector2);
+ return !(dist_sq > tol);
+ // within_tolerance() just checks coordinate aligned distances, not the actual distance.
+// return (vector1.within_tolerance( vector2, GEOMETRY_RESABS * tolerance_factor ));
}
double GeometryQueryTool::geometric_angle(RefEdge* ref_edge_1,
@@ -2856,6 +3222,8 @@
TopologyEntity* GeometryQueryTool::entity_from_bridge( TopologyBridge* bridge_ptr ) const
{
+ if( !bridge_ptr )
+ return NULL;
TBOwner* owner = bridge_ptr->owner();
BridgeManager* bridge_manager;
while (!(bridge_manager = dynamic_cast<BridgeManager*>(owner)))
@@ -3543,6 +3911,7 @@
" to\n this unsuccessful deletion.\n",
bodyPtr->id() );
assert( status != CUBIT_FAILURE) ;
+ break;
}
}
@@ -3572,6 +3941,7 @@
"due to\n this unsuccessful deletion.\n",
refFacePtr->id());
assert( status != CUBIT_FAILURE) ;
+ break;
}
}
@@ -3601,6 +3971,7 @@
"due to\n this unsuccessful deletion.\n",
refEdgePtr->id());
assert( status != CUBIT_FAILURE) ;
+ break;
}
}
@@ -3630,6 +4001,7 @@
"due to\n this unsuccessful deletion.\n",
refVertexPtr->id());
assert( status != CUBIT_FAILURE) ;
+ break;
}
}
@@ -3649,16 +4021,36 @@
CubitBox GeometryQueryTool::model_bounding_box()
{
+ int i;
+ CubitBox result;
DLIList<Body*> bodies;
this->bodies(bodies);
- if (!bodies.size())
- return CubitBox();
+ DLIList<RefEntity*> free_entity_list;
+ this->get_free_ref_entities(free_entity_list);
+
+ if (!(bodies.size() + free_entity_list.size()))
+ return result;
+
bodies.reset();
- CubitBox result = bodies.get()->bounding_box();
- for (int i = bodies.size() - 1; i--; )
- result |= bodies.step_and_get()->bounding_box();
+ free_entity_list.reset();
+
+ if( bodies.size() )
+ {
+ result = bodies.get_and_step()->bounding_box();
+ for ( i = bodies.size()-1; i--; )
+ result |= bodies.get_and_step()->bounding_box();
+ i = free_entity_list.size();
+ }
+ else
+ {
+ result = free_entity_list.get_and_step()->bounding_box();
+ i = free_entity_list.size()-1;
+ }
+ for ( i; i--; )
+ result |= free_entity_list.get_and_step()->bounding_box();
+
return result;
}
@@ -3692,6 +4084,18 @@
RefEntityFactory::instance()->ref_vertices(ref_vertices);
}
+#ifdef PROE
+void GeometryQueryTool::ref_parts (DLIList<RefPart*> &ref_parts)
+{
+ RefEntityFactory::instance()->ref_parts(ref_parts);
+}
+
+void GeometryQueryTool::ref_assemblies (DLIList<RefAssembly*> &ref_assemblies)
+{
+ RefEntityFactory::instance()->ref_assemblies(ref_assemblies);
+}
+#endif
+
int GeometryQueryTool::num_bodies() const
{
return RefEntityFactory::instance()->num_bodies();
@@ -4534,6 +4938,12 @@
return (CubitStatus)igeSet.insert(engine_ptr).second;
}
+void GeometryQueryTool::unregister_intermediate_engine(
+ IntermediateGeomEngine* engine_ptr )
+{
+ (CubitStatus)igeSet.erase(engine_ptr);
+}
+
void GeometryQueryTool::ige_export_geom( DLIList<TopologyBridge*> &geom_list )
{
for (IGESet::reverse_iterator itor = igeSet.rbegin(); itor != igeSet.rend(); ++itor)
@@ -4547,6 +4957,13 @@
(*itor)->push_imprint_attributes_before_modify(geom_list);
}
+void GeometryQueryTool::ige_push_named_attributes_to_curves_and_points
+ ( DLIList<TopologyBridge*> &tb_list, const char *name_in )
+{
+ for (IGESet::reverse_iterator itor = igeSet.rbegin(); itor != igeSet.rend(); ++itor)
+ (*itor)->push_named_attributes_to_curves_and_points(tb_list, name_in);
+}
+
void GeometryQueryTool::ige_remove_imprint_attributes_after_modify
( DLIList<BodySM*> &old_sms,
DLIList<BodySM*> &new_sms )
@@ -4567,6 +4984,21 @@
}
return ret;
}
+
+bool GeometryQueryTool::ige_is_composite(TopologyBridge *bridge)
+{
+ bool ret = false;
+ for (IGESet::iterator itor = igeSet.begin(); itor != igeSet.end() && ret != true; ++itor)
+ {
+ if((*itor)->is_composite(bridge))
+ {
+ ret = true;
+ }
+ }
+ return ret;
+}
+
+
bool GeometryQueryTool::ige_is_partition(TBOwner *bridge_owner)
{
bool ret = false;
@@ -4586,13 +5018,20 @@
(*itor)->import_geometry(geom_list);
}
+void GeometryQueryTool::get_tbs_with_bridge_manager_as_owner( TopologyBridge *source_bridge,
+ DLIList<TopologyBridge*> &tbs )
+{
+ for (IGESet::iterator itor = igeSet.begin(); itor != igeSet.end(); ++itor)
+ (*itor)->get_tbs_with_bridge_manager_as_owner( source_bridge, tbs );
+}
+
void GeometryQueryTool::ige_attribute_after_imprinting( DLIList<TopologyBridge*> &new_tbs,
DLIList<TopologyBridge*> &att_tbs,
- DLIList<BodySM*> &new_sms,
+ DLIList<TopologyBridge*> &tb_list,
DLIList<Body*> &old_bodies)
{
for (IGESet::iterator itor = igeSet.begin(); itor != igeSet.end(); ++itor)
- (*itor)->attribute_after_imprinting(new_tbs, att_tbs, new_sms, old_bodies);
+ (*itor)->attribute_after_imprinting(new_tbs, att_tbs, tb_list, old_bodies);
}
void GeometryQueryTool::ige_remove_attributes( DLIList<TopologyBridge*> &geom_list )
@@ -4707,7 +5146,11 @@
// parent sense entity which this function will be called on and
// that call will be the top-most one.
if (top)
+ {
CubitObserver::notify_static_observers( ob, TOP_LEVEL_ENTITY_DESTRUCTED );
+ CGMHistory::Event evt(CGMHistory::TOP_LEVEL_ENTITY_DELETED, static_cast<RefEntity*>(ob));
+ const_cast<CGMHistory&>(mHistory).add_event(evt);
+ }
ob->notify_all_observers( MODEL_ENTITY_DESTRUCTED );
}
else
@@ -4740,7 +5183,11 @@
has_parents = true;
}
if (!has_parents)
+ {
ob->notify_all_observers( FREE_REF_ENTITY_GENERATED );
+ CGMHistory::Event evt(CGMHistory::TOP_LEVEL_ENTITY_CREATED, static_cast<RefEntity*>(ob));
+ const_cast<CGMHistory&>(mHistory).add_event(evt);
+ }
}
}
}
@@ -4879,14 +5326,118 @@
return CUBIT_TRUE;
}
+void GeometryQueryTool::translate( DLIList<RefEntity*> &entities_to_transform,
+ double x, double y, double z, bool check_before_transforming,
+ DLIList<RefEntity*> &entities_transformed,
+ bool preview /*= false*/)
+{
+ CubitVector delta(x,y,z);
+
+ //translate free, merged-away entities first
+ DLIList<TopologyBridge*> free_ents;
+ get_merged_away_free_entities( entities_to_transform, free_ents );
+
+ int i;
+ if (!preview)
+ {
+ for( i=free_ents.size(); i--; )
+ {
+ TopologyBridge *bridge = free_ents.get_and_step();
+ Curve *curve= CAST_TO( bridge, Curve );
+ Point *point = CAST_TO( bridge, Point );
+
+ if( curve || point )
+ {
+ GeometryEntity *geom = CAST_TO( bridge, GeometryEntity );
+ GeometryQueryEngine* engine = geom->get_geometry_query_engine();
+ CubitStatus result = engine->translate( geom, delta );
+ }
+ }
+ }
+
+ Body *tmp_body;
+ RefFace *tmp_face;
+ RefEdge *tmp_curve;
+ RefVertex *tmp_vertex;
+ CubitStatus result;
+
+ for(i = entities_to_transform.size(); i > 0; i--)
+ {
+ RefEntity *tmp_ent = entities_to_transform.get_and_step();
+
+ if( ( tmp_body = CAST_TO( tmp_ent, Body ) ) != NULL )
+ {
+ result = translate( tmp_body, CubitVector(x, y, z),
+ check_before_transforming, preview );
+ }
+ else if( ( tmp_face = CAST_TO( tmp_ent, RefFace ) ) != NULL )
+ {
+ // only allow translating RefFaces if preview is on
+ if (!preview)
+ continue;
+
+ result = translate(tmp_face, CubitVector( x, y, z ),
+ check_before_transforming, preview );
+ }
+ else if( ( tmp_curve = CAST_TO( tmp_ent, RefEdge ) ) != NULL )
+ {
+ result = translate(tmp_curve, CubitVector( x, y, z ),
+ check_before_transforming, preview );
+ }
+ else if( ( tmp_vertex = CAST_TO( tmp_ent, RefVertex ) ) != NULL )
+ {
+ CubitVector vec(x, y, z);
+ result = translate( tmp_vertex, vec, check_before_transforming, preview);
+ if( result )
+ {
+ PRINT_INFO("Vertex %d moved %g %g %g\n", tmp_vertex->id(), x, y, z);
+ }
+ else
+ PRINT_ERROR("Unable to move Vertex %d\n", tmp_vertex->id());
+ }
+
+ if(result)
+ entities_transformed.append( tmp_ent );
+ }
+}
+
+
+
CubitStatus GeometryQueryTool::translate( Body* body,
const CubitVector& delta,
- bool check_to_transform )
+ bool check_to_transform,
+ bool preview )
{
if( check_to_transform )
if (!okay_to_transform( body ))
return CUBIT_FAILURE;
+ if (preview)
+ {
+ DLIList<RefEdge*> edges;
+ body->ref_edges(edges);
+ for (int i = 0; i < edges.size(); i++)
+ {
+ GMem poly, prev;
+ edges[i]->get_graphics(poly);
+ GPoint *prev_points = NULL;
+ prev_points = new GPoint[poly.point_list_size()];
+ for (int j = 0; j < poly.point_list_size(); j++)
+ {
+ CubitVector tempV(poly.point_list()[j].x, poly.point_list()[j].y, poly.point_list()[j].z);
+ tempV += delta;
+ prev_points[j].x = tempV.x();
+ prev_points[j].y = tempV.y();
+ prev_points[j].z = tempV.z();
+ }
+ GfxPreview::draw_polyline(prev_points, poly.point_list_size(), CUBIT_BLUE);
+ delete [] prev_points;
+ prev_points = NULL;
+ }
+ GfxPreview::flush();
+ return CUBIT_SUCCESS;
+ }
+
BodySM* bodysm = body->get_body_sm_ptr();
GeometryQueryEngine* engine = bodysm->get_geometry_query_engine();
CubitStatus result = engine->translate( bodysm, delta );
@@ -4903,15 +5454,126 @@
return result;
}
+CubitStatus GeometryQueryTool::rotate( DLIList<RefEntity*> &entities_to_transform,
+ const CubitVector& point,
+ const CubitVector& direction,
+ double angle,
+ bool check_before_transforming,
+ DLIList<RefEntity*> &entities_transformed,
+ bool preview /*= false*/)
+{
+ //rotate free, merged-away entities first
+ DLIList<TopologyBridge*> free_ents;
+ get_merged_away_free_entities( entities_to_transform, free_ents );
+
+ int i;
+ if (!preview)
+ {
+ for( i=free_ents.size(); i--; )
+ {
+ TopologyBridge *bridge = free_ents.get_and_step();
+ Curve *curve= CAST_TO( bridge, Curve );
+ Point *tmp_point = CAST_TO( bridge, Point );
+
+ if( curve || tmp_point )
+ {
+ GeometryEntity *geom = CAST_TO( bridge, GeometryEntity );
+ GeometryQueryEngine* engine = geom->get_geometry_query_engine();
+ CubitStatus result = engine->translate( geom, -point );
+ result = engine->rotate( geom, direction, angle );
+ result = engine->translate( geom, point );
+
+ }
+ }
+ }
+
+ Body *tmp_body;
+ RefFace *tmp_face;
+ RefEdge *tmp_curve;
+ RefEntity *tmp_ent;
+ CubitStatus result;
+ for(i=entities_to_transform.size(); i > 0; i--)
+ {
+ tmp_ent = entities_to_transform.get_and_step();
+
+ //body
+ if( ( tmp_body = CAST_TO( tmp_ent, Body ) ) != NULL )
+ result = rotate( tmp_body, point, direction, angle,
+ check_before_transforming, preview);
+ else if( (tmp_face = CAST_TO( tmp_ent, RefFace ) ) != NULL )
+ {
+ // only allow rotation of RefFaces if preview is on
+ if (!preview)
+ continue;
+
+ result = rotate( tmp_face, direction, angle,
+ check_before_transforming, preview);
+ }
+ //curve
+ else if( (tmp_curve = CAST_TO( tmp_ent, RefEdge ) ) != NULL )
+ result = rotate( tmp_curve, direction, angle,
+ check_before_transforming, preview);
+
+ if( result == CUBIT_SUCCESS )
+ entities_transformed.append( tmp_ent );
+ }
+
+ return result;
+}
+
CubitStatus GeometryQueryTool::rotate( Body* body,
const CubitVector& axis,
double angle,
- bool check_to_transform )
+ bool check_to_transform,
+ bool preview )
{
if( check_to_transform )
if (!okay_to_transform( body ))
return CUBIT_FAILURE;
+ if (preview)
+ {
+ DLIList<RefEdge*> edges;
+ body->ref_edges(edges);
+ for (int j = 0; j < edges.size(); j++)
+ {
+ GMem poly, prev;
+ edges[j]->get_graphics(poly);
+ GPoint *prev_points = NULL;
+ prev_points = new GPoint[poly.point_list_size()];
+ for (int k = 0; k < poly.point_list_size(); k++)
+ {
+ CubitVector q;
+ CubitVector tempAxis = axis;
+ CubitVector p(poly.point_list()[k].x, poly.point_list()[k].y, poly.point_list()[k].z);
+ double costheta = cos(angle*3.14159265358979323846/180);
+ double sintheta = sin(angle*3.14159265358979323846/180);
+ tempAxis.normalize();
+
+ q.x() += (costheta + (1 - costheta) * tempAxis.x() * tempAxis.x()) * p.x();
+ q.x() += ((1 - costheta) * tempAxis.x() * tempAxis.y() - tempAxis.z() * sintheta) * p.y();
+ q.x() += ((1 - costheta) * tempAxis.x() * tempAxis.z() + tempAxis.y() * sintheta) * p.z();
+
+ q.y() += ((1 - costheta) * tempAxis.x() * tempAxis.y() + tempAxis.z() * sintheta) * p.x();
+ q.y() += (costheta + (1 - costheta) * tempAxis.y() * tempAxis.y()) * p.y();
+ q.y() += ((1 - costheta) * tempAxis.y() * tempAxis.z() - tempAxis.x() * sintheta) * p.z();
+
+ q.z() += ((1 - costheta) * tempAxis.x() * tempAxis.z() - tempAxis.y() * sintheta) * p.x();
+ q.z() += ((1 - costheta) * tempAxis.y() * tempAxis.z() + tempAxis.x() * sintheta) * p.y();
+ q.z() += (costheta + (1 - costheta) * tempAxis.z() * tempAxis.z()) * p.z();
+
+ prev_points[k].x = q.x();
+ prev_points[k].y = q.y();
+ prev_points[k].z = q.z();
+ }
+ GfxPreview::draw_polyline(prev_points, poly.point_list_size(), CUBIT_BLUE);
+ delete [] prev_points;
+ prev_points = NULL;
+ }
+ GfxPreview::flush();
+ return CUBIT_SUCCESS;
+ }
+
BodySM* bodysm = body->get_body_sm_ptr();
GeometryQueryEngine* engine = bodysm->get_geometry_query_engine();
CubitStatus result = engine->rotate( bodysm, axis, angle );
@@ -4934,12 +5596,66 @@
const CubitVector& point,
const CubitVector& direction,
double degrees,
- bool check_to_transform )
+ bool check_to_transform,
+ bool preview /*=false*/)
{
if( check_to_transform )
if (!okay_to_transform( body ))
return CUBIT_FAILURE;
+ if (preview)
+ {
+ // define the axis
+ CubitVector axis(direction);
+
+ DLIList<RefEdge*> edges;
+ body->ref_edges(edges);
+ for (int j = 0; j < edges.size(); j++)
+ {
+ GMem poly, prev;
+ edges[j]->get_graphics(poly);
+ GPoint *prev_points = NULL;
+ prev_points = new GPoint[poly.point_list_size()];
+ for (int k = 0; k < poly.point_list_size(); k++)
+ {
+ CubitVector q;
+
+ // first translate to the rotation axis
+ CubitVector p(poly.point_list()[k].x, poly.point_list()[k].y, poly.point_list()[k].z);
+ p -= point;
+
+ CubitVector tempAxis = axis;
+ double costheta = cos(degrees*3.14159265358979323846/180);
+ double sintheta = sin(degrees*3.14159265358979323846/180);
+ tempAxis.normalize();
+
+ q.x() += (costheta + (1 - costheta) * tempAxis.x() * tempAxis.x()) * p.x();
+ q.x() += ((1 - costheta) * tempAxis.x() * tempAxis.y() - tempAxis.z() * sintheta) * p.y();
+ q.x() += ((1 - costheta) * tempAxis.x() * tempAxis.z() + tempAxis.y() * sintheta) * p.z();
+
+ q.y() += ((1 - costheta) * tempAxis.x() * tempAxis.y() + tempAxis.z() * sintheta) * p.x();
+ q.y() += (costheta + (1 - costheta) * tempAxis.y() * tempAxis.y()) * p.y();
+ q.y() += ((1 - costheta) * tempAxis.y() * tempAxis.z() - tempAxis.x() * sintheta) * p.z();
+
+ q.z() += ((1 - costheta) * tempAxis.x() * tempAxis.z() - tempAxis.y() * sintheta) * p.x();
+ q.z() += ((1 - costheta) * tempAxis.y() * tempAxis.z() + tempAxis.x() * sintheta) * p.y();
+ q.z() += (costheta + (1 - costheta) * tempAxis.z() * tempAxis.z()) * p.z();
+
+ // move back into position
+ q += point;
+
+ prev_points[k].x = q.x();
+ prev_points[k].y = q.y();
+ prev_points[k].z = q.z();
+ }
+ GfxPreview::draw_polyline(prev_points, poly.point_list_size(), CUBIT_BLUE);
+ delete [] prev_points;
+ prev_points = NULL;
+ }
+ GfxPreview::flush();
+ return CUBIT_SUCCESS;
+ }
+
BodySM* bodysm = body->get_body_sm_ptr();
GeometryQueryEngine* engine = bodysm->get_geometry_query_engine();
CubitTransformMatrix xform;
@@ -4983,12 +5699,110 @@
return result;
}
-CubitStatus GeometryQueryTool::scale( Body* body, double factor, bool check_to_transform )
+void GeometryQueryTool::scale( DLIList<RefEntity*> &entities_to_transform,
+ double scale_x, double scale_y, double scale_z,
+ bool check_before_transforming,
+ DLIList<RefEntity*> &entities_scaled,
+ bool preview /*= false*/)
{
+ CubitVector factors(scale_x, scale_y, scale_z);
+
+ //scale free, merged-away entities first
+ DLIList<TopologyBridge*> free_ents;
+ get_merged_away_free_entities( entities_to_transform, free_ents );
+ int i;
+ if (!preview)
+ {
+ for( i=free_ents.size(); i--; )
+ {
+ TopologyBridge *bridge = free_ents.get_and_step();
+ Curve *curve= CAST_TO( bridge, Curve );
+ Point *point = CAST_TO( bridge, Point );
+
+ if( curve || point )
+ {
+ GeometryEntity *geom = CAST_TO( bridge, GeometryEntity );
+ GeometryQueryEngine* engine = geom->get_geometry_query_engine();
+ CubitStatus result = engine->scale( geom, factors );
+ }
+ }
+ }
+
+ CubitStatus result;
+ for(i=entities_to_transform.size(); i--; )
+ {
+ RefEntity *tmp_ent = entities_to_transform.get_and_step();
+ Body *tmp_body;
+ RefFace* tmp_face;
+ RefEdge *tmp_curve;
+ if( ( tmp_body = CAST_TO( tmp_ent, Body ) ) != NULL )
+ {
+ //non-uniform scaling
+ if( scale_x != scale_y ||
+ scale_x != scale_z ||
+ scale_y != scale_z )
+ {
+ // use GMT version for non-uniform scaling b/c it updates topology if it changes
+ result = GeometryModifyTool::instance()->scale(tmp_body, factors,
+ check_before_transforming, preview);
+ tmp_ent = tmp_body;
+ }
+ else
+ result = scale( tmp_body, CubitVector(scale_x, scale_y, scale_z),
+ check_before_transforming, preview);
+ }
+ else if( ( tmp_face = CAST_TO( tmp_ent, RefFace ) ) != NULL )
+ {
+ // only allow scaling of RefFaces if preview is on
+ if (!preview)
+ continue;
+ result = scale( tmp_face, CubitVector(scale_x, scale_y, scale_z),
+ check_before_transforming, preview);
+ }
+ else if( ( tmp_curve = CAST_TO( tmp_ent, RefEdge ) ) != NULL )
+ {
+ result = scale( tmp_curve, CubitVector(scale_x, scale_y, scale_z),
+ check_before_transforming, preview);
+ }
+ if(result)
+ entities_scaled.append( tmp_ent );
+ }
+
+}
+
+
+CubitStatus GeometryQueryTool::scale( Body* body, double factor, bool check_to_transform, bool preview )
+{
if( check_to_transform )
if (!okay_to_transform( body ))
return CUBIT_FAILURE;
+ if (preview)
+ {
+ DLIList<RefEdge*> edges;
+ body->ref_edges(edges);
+ for (int i = 0; i < edges.size(); i++)
+ {
+ GMem poly, prev;
+ edges[i]->get_graphics(poly);
+ GPoint *prev_points = NULL;
+ prev_points = new GPoint[poly.point_list_size()];
+ for (int j = 0; j < poly.point_list_size(); j++)
+ {
+ CubitVector tempV(poly.point_list()[j].x, poly.point_list()[j].y, poly.point_list()[j].z);
+ tempV *= factor;
+ prev_points[j].x = tempV.x();
+ prev_points[j].y = tempV.y();
+ prev_points[j].z = tempV.z();
+ }
+ GfxPreview::draw_polyline(prev_points, poly.point_list_size(), CUBIT_BLUE);
+ delete [] prev_points;
+ prev_points = NULL;
+ }
+ GfxPreview::flush();
+ return CUBIT_SUCCESS;
+ }
+
BodySM* bodysm = body->get_body_sm_ptr();
GeometryQueryEngine* engine = bodysm->get_geometry_query_engine();
CubitStatus result = engine->scale( bodysm, factor );
@@ -5007,12 +5821,41 @@
CubitStatus GeometryQueryTool::scale( Body *body,
const CubitVector& factors,
- bool check_to_transform )
+ bool check_to_transform,
+ bool preview )
{
if( check_to_transform )
if (!okay_to_transform( body ))
return CUBIT_FAILURE;
+ if (preview)
+ {
+ DLIList<RefEdge*> edges;
+ body->ref_edges(edges);
+ for (int i = 0; i < edges.size(); i++)
+ {
+ GMem poly, prev;
+ edges[i]->get_graphics(poly);
+ GPoint *prev_points = NULL;
+ prev_points = new GPoint[poly.point_list_size()];
+ for (int j = 0; j < poly.point_list_size(); j++)
+ {
+ CubitVector tempV(poly.point_list()[j].x, poly.point_list()[j].y, poly.point_list()[j].z);
+ tempV.x(tempV.x()*factors.x());
+ tempV.y(tempV.y()*factors.y());
+ tempV.z(tempV.z()*factors.z());
+ prev_points[j].x = tempV.x();
+ prev_points[j].y = tempV.y();
+ prev_points[j].z = tempV.z();
+ }
+ GfxPreview::draw_polyline(prev_points, poly.point_list_size(), CUBIT_BLUE);
+ delete [] prev_points;
+ prev_points = NULL;
+ }
+ GfxPreview::flush();
+ return CUBIT_SUCCESS;
+ }
+
BodySM* bodysm = body->get_body_sm_ptr();
GeometryQueryEngine* engine = bodysm->get_geometry_query_engine();
CubitStatus result = engine->scale( bodysm, factors );
@@ -5030,11 +5873,129 @@
return result;
}
+void GeometryQueryTool::reflect( DLIList<RefEntity*> &entities_to_transform,
+ double x, double y, double z,
+ bool check_before_transforming,
+ DLIList<RefEntity*> &entities_transformed,
+ bool preview /*= false*/)
+{
+ CubitVector axis( x,y,z);
+
+ //reflect free, merged-away entities
+ DLIList<TopologyBridge*> free_ents;
+ get_merged_away_free_entities( entities_to_transform, free_ents );
+
+ int i;
+ if (!preview)
+ {
+ for( i=free_ents.size(); i--; )
+ {
+ TopologyBridge *bridge = free_ents.get_and_step();
+ Curve *curve= CAST_TO( bridge, Curve );
+ Point *tmp_point = CAST_TO( bridge, Point );
+
+ if( curve || tmp_point )
+ {
+ GeometryEntity *geom = CAST_TO( bridge, GeometryEntity );
+ GeometryQueryEngine* engine = geom->get_geometry_query_engine();
+ CubitStatus result = engine->reflect( geom, axis );
+ }
+ }
+ }
+
+ DLIList<Body*> body_list;
+ DLIList<RefEdge*> curve_list;
+ DLIList<RefFace*> face_list;
+ CubitStatus result;
+ CAST_LIST(entities_to_transform, body_list, Body);
+ if( body_list.size() != entities_to_transform.size() )
+ {
+ CAST_LIST(entities_to_transform, curve_list, RefEdge);
+ CAST_LIST(entities_to_transform, face_list, RefFace);
+ }
+
+ if( body_list.size() )
+ {
+ result = GeometryQueryTool::instance()->reflect( body_list, CubitVector( x, y, z ), preview );
+ if ( result )
+ {
+ while(body_list.size())
+ entities_transformed.append(body_list.pop());
+ }
+ }
+ if( face_list.size() )
+ {
+ int i;
+ for(i = face_list.size(); i > 0; i--)
+ {
+ // only allow reflection of RefFaces if preview is on
+ if (!preview)
+ continue;
+
+ RefFace *tmp_face = face_list.get_and_step();
+ result = reflect( tmp_face, axis,
+ check_before_transforming, preview );
+ if ( result )
+ entities_transformed.append( tmp_face );
+ }
+ }
+ if( curve_list.size() )
+ {
+ int i;
+ for(i = curve_list.size(); i > 0; i--)
+ {
+ RefEdge *tmp_edge = curve_list.get_and_step();
+ result = reflect( tmp_edge, axis,
+ check_before_transforming, preview );
+ if ( result )
+ entities_transformed.append( tmp_edge );
+ }
+ }
+
+}
+
+
+
CubitStatus GeometryQueryTool::reflect( DLIList<Body*> bodies,
- const CubitVector& axis )
+ const CubitVector& axis,
+ bool preview)
{
Body *tmp_body;
CubitStatus result = CUBIT_FAILURE;
+
+ if (preview)
+ {
+ for (int i = 0; i < bodies.size(); i++)
+ {
+ DLIList<RefEdge*> edges;
+ bodies[i]->ref_edges(edges);
+ for (int j = 0; j < edges.size(); j++)
+ {
+ GMem poly, prev;
+ edges[j]->get_graphics(poly);
+ GPoint *prev_points = NULL;
+ prev_points = new GPoint[poly.point_list_size()];
+ for (int k = 0; k < poly.point_list_size(); k++)
+ {
+ CubitVector tempAxis = axis;
+ CubitVector tempV(poly.point_list()[k].x, poly.point_list()[k].y, poly.point_list()[k].z);
+ CubitVector b = tempV - CubitVector(0,0,0);
+ double dist = (tempAxis % b) / tempAxis.length();
+ tempAxis.length(dist);
+ CubitVector refl = tempV - tempAxis;
+ refl = refl - tempV + refl;
+ prev_points[k].x = refl.x();
+ prev_points[k].y = refl.y();
+ prev_points[k].z = refl.z();
+ }
+ GfxPreview::draw_polyline(prev_points, poly.point_list_size(), CUBIT_BLUE);
+ delete [] prev_points;
+ prev_points = NULL;
+ }
+ GfxPreview::flush();
+ }
+ return CUBIT_SUCCESS;
+ }
//first, reflect the underlying geometry
int i;
for( i=bodies.size(); i--;)
@@ -5058,6 +6019,11 @@
CubitTransformMatrix xform;
xform.reflect( axis );
notify_intermediate_of_transform( tmp_body, xform );
+ }
+
+ for( i=bodies.size(); i--;)
+ {
+ tmp_body = bodies.get_and_step();
make_Body( tmp_body->get_body_sm_ptr() );
notify_observers_of_transform( tmp_body );
}
@@ -5078,6 +6044,10 @@
RefEntity* ref_entity ) const
{
ref_entity->notify_sub_all_observers( GEOMETRY_MODIFIED );
+
+ CGMHistory::Event evt(CGMHistory::GEOMETRY_TRANSFORMED, ref_entity);
+ const_cast<CGMHistory&>(mHistory).add_event(evt);
+
return CUBIT_SUCCESS;
}
@@ -5105,12 +6075,50 @@
CubitStatus GeometryQueryTool::translate( BasicTopologyEntity* bte,
const CubitVector& delta,
- bool check_to_transform )
+ bool check_to_transform,
+ bool preview )
{
if( check_to_transform )
if (!okay_to_transform( bte ))
return CUBIT_FAILURE;
+ if (preview)
+ {
+ DLIList<RefEdge*> edges;
+ bte->ref_edges(edges);
+ for (int i = 0; i < edges.size(); i++)
+ {
+ GMem poly, prev;
+ edges[i]->get_graphics(poly);
+ GPoint *prev_points = NULL;
+ prev_points = new GPoint[poly.point_list_size()];
+ for (int j = 0; j < poly.point_list_size(); j++)
+ {
+ CubitVector tempV(poly.point_list()[j].x, poly.point_list()[j].y, poly.point_list()[j].z);
+ tempV += delta;
+ prev_points[j].x = tempV.x();
+ prev_points[j].y = tempV.y();
+ prev_points[j].z = tempV.z();
+ }
+ GfxPreview::draw_polyline(prev_points, poly.point_list_size(), CUBIT_BLUE);
+ delete [] prev_points;
+ prev_points = NULL;
+ }
+ if (edges.size() == 0)
+ {
+ DLIList<RefVertex*> points;
+ bte->ref_vertices(points);
+ for (int i = 0; i < points.size(); i++)
+ {
+ CubitVector temp(points[i]->center_point());
+ temp += delta;
+ GfxPreview::draw_point(temp, CUBIT_BLUE);
+ }
+ }
+ GfxPreview::flush();
+ return CUBIT_SUCCESS;
+ }
+
GeometryEntity* geom = bte->get_geometry_entity_ptr();
GeometryQueryEngine* engine = geom->get_geometry_query_engine();
CubitStatus result = engine->translate( geom, delta );
@@ -5130,12 +6138,87 @@
CubitStatus GeometryQueryTool::rotate( BasicTopologyEntity* bte,
const CubitVector& axis,
double angle,
- bool check_to_transform )
+ bool check_to_transform,
+ bool preview )
{
if( check_to_transform )
if (!okay_to_transform( bte ))
return CUBIT_FAILURE;
+ if (preview)
+ {
+ DLIList<RefEdge*> edges;
+ bte->ref_edges(edges);
+
+ for (int j = 0; j < edges.size(); j++)
+ {
+ GMem poly, prev;
+ edges[j]->get_graphics(poly);
+ GPoint *prev_points = NULL;
+ prev_points = new GPoint[poly.point_list_size()];
+ for (int k = 0; k < poly.point_list_size(); k++)
+ {
+ CubitVector q;
+ CubitVector tempAxis = axis;
+ CubitVector p(poly.point_list()[k].x, poly.point_list()[k].y, poly.point_list()[k].z);
+ double costheta = cos(angle*3.14159265358979323846/180);
+ double sintheta = sin(angle*3.14159265358979323846/180);
+ tempAxis.normalize();
+
+ q.x() += (costheta + (1 - costheta) * tempAxis.x() * tempAxis.x()) * p.x();
+ q.x() += ((1 - costheta) * tempAxis.x() * tempAxis.y() - tempAxis.z() * sintheta) * p.y();
+ q.x() += ((1 - costheta) * tempAxis.x() * tempAxis.z() + tempAxis.y() * sintheta) * p.z();
+
+ q.y() += ((1 - costheta) * tempAxis.x() * tempAxis.y() + tempAxis.z() * sintheta) * p.x();
+ q.y() += (costheta + (1 - costheta) * tempAxis.y() * tempAxis.y()) * p.y();
+ q.y() += ((1 - costheta) * tempAxis.y() * tempAxis.z() - tempAxis.x() * sintheta) * p.z();
+
+ q.z() += ((1 - costheta) * tempAxis.x() * tempAxis.z() - tempAxis.y() * sintheta) * p.x();
+ q.z() += ((1 - costheta) * tempAxis.y() * tempAxis.z() + tempAxis.x() * sintheta) * p.y();
+ q.z() += (costheta + (1 - costheta) * tempAxis.z() * tempAxis.z()) * p.z();
+
+ prev_points[k].x = q.x();
+ prev_points[k].y = q.y();
+ prev_points[k].z = q.z();
+ }
+ GfxPreview::draw_polyline(prev_points, poly.point_list_size(), CUBIT_BLUE);
+ delete [] prev_points;
+ prev_points = NULL;
+ }
+ if (edges.size() == 0)
+ {
+ DLIList<RefVertex*> points;
+ bte->ref_vertices(points);
+ for (int i = 0; i < points.size(); i++)
+ {
+ CubitVector tempAxis = axis;
+ CubitVector p(points[i]->center_point());
+ double costheta = cos(angle*3.14159265358979323846/180);
+ double sintheta = sin(angle*3.14159265358979323846/180);
+ tempAxis.normalize();
+
+ CubitVector q;
+
+ q.x() += (costheta + (1 - costheta) * tempAxis.x() * tempAxis.x()) * p.x();
+ q.x() += ((1 - costheta) * tempAxis.x() * tempAxis.y() - tempAxis.z() * sintheta) * p.y();
+ q.x() += ((1 - costheta) * tempAxis.x() * tempAxis.z() + tempAxis.y() * sintheta) * p.z();
+
+ q.y() += ((1 - costheta) * tempAxis.x() * tempAxis.y() + tempAxis.z() * sintheta) * p.x();
+ q.y() += (costheta + (1 - costheta) * tempAxis.y() * tempAxis.y()) * p.y();
+ q.y() += ((1 - costheta) * tempAxis.y() * tempAxis.z() - tempAxis.x() * sintheta) * p.z();
+
+ q.z() += ((1 - costheta) * tempAxis.x() * tempAxis.z() - tempAxis.y() * sintheta) * p.x();
+ q.z() += ((1 - costheta) * tempAxis.y() * tempAxis.z() + tempAxis.x() * sintheta) * p.y();
+ q.z() += (costheta + (1 - costheta) * tempAxis.z() * tempAxis.z()) * p.z();
+
+ GfxPreview::draw_point(q, CUBIT_BLUE);
+ }
+ }
+
+ GfxPreview::flush();
+ return CUBIT_SUCCESS;
+ }
+
GeometryEntity* geom = bte->get_geometry_entity_ptr();
GeometryQueryEngine* engine = geom->get_geometry_query_engine();
CubitStatus result = engine->rotate( geom, axis, angle );
@@ -5153,12 +6236,38 @@
}
CubitStatus GeometryQueryTool::scale( BasicTopologyEntity* bte, double factor,
- bool check_to_transform )
+ bool check_to_transform, bool preview )
{
if( check_to_transform )
if (!okay_to_transform( bte ))
return CUBIT_FAILURE;
+ if (preview)
+ {
+ DLIList<RefEdge*> edges;
+ bte->ref_edges(edges);
+ for (int i = 0; i < edges.size(); i++)
+ {
+ GMem poly, prev;
+ edges[i]->get_graphics(poly);
+ GPoint *prev_points = NULL;
+ prev_points = new GPoint[poly.point_list_size()];
+ for (int j = 0; j < poly.point_list_size(); j++)
+ {
+ CubitVector tempV(poly.point_list()[j].x, poly.point_list()[j].y, poly.point_list()[j].z);
+ tempV *= factor;
+ prev_points[j].x = tempV.x();
+ prev_points[j].y = tempV.y();
+ prev_points[j].z = tempV.z();
+ }
+ GfxPreview::draw_polyline(prev_points, poly.point_list_size(), CUBIT_BLUE);
+ delete [] prev_points;
+ prev_points = NULL;
+ }
+ GfxPreview::flush();
+ return CUBIT_SUCCESS;
+ }
+
GeometryEntity* geom = bte->get_geometry_entity_ptr();
GeometryQueryEngine* engine = geom->get_geometry_query_engine();
CubitStatus result = engine->scale( geom, factor );
@@ -5178,12 +6287,41 @@
CubitStatus GeometryQueryTool::scale( BasicTopologyEntity* bte,
const CubitVector& factors,
- bool check_to_transform )
+ bool check_to_transform,
+ bool preview )
{
if( check_to_transform )
if (!okay_to_transform( bte ))
return CUBIT_FAILURE;
+ if (preview)
+ {
+ DLIList<RefEdge*> edges;
+ bte->ref_edges(edges);
+ for (int i = 0; i < edges.size(); i++)
+ {
+ GMem poly, prev;
+ edges[i]->get_graphics(poly);
+ GPoint *prev_points = NULL;
+ prev_points = new GPoint[poly.point_list_size()];
+ for (int j = 0; j < poly.point_list_size(); j++)
+ {
+ CubitVector tempV(poly.point_list()[j].x, poly.point_list()[j].y, poly.point_list()[j].z);
+ tempV.x(tempV.x()*factors.x());
+ tempV.y(tempV.y()*factors.y());
+ tempV.z(tempV.z()*factors.z());
+ prev_points[j].x = tempV.x();
+ prev_points[j].y = tempV.y();
+ prev_points[j].z = tempV.z();
+ }
+ GfxPreview::draw_polyline(prev_points, poly.point_list_size(), CUBIT_BLUE);
+ delete [] prev_points;
+ prev_points = NULL;
+ }
+ GfxPreview::flush();
+ return CUBIT_SUCCESS;
+ }
+
GeometryEntity* geom = bte->get_geometry_entity_ptr();
GeometryQueryEngine* engine = geom->get_geometry_query_engine();
CubitStatus result = engine->scale( geom, factors );
@@ -5202,12 +6340,44 @@
CubitStatus GeometryQueryTool::reflect( BasicTopologyEntity* bte,
const CubitVector& axis,
- bool check_to_transform )
+ bool check_to_transform,
+ bool preview )
{
if( check_to_transform )
if (!okay_to_transform( bte ))
return CUBIT_FAILURE;
+ if (preview)
+ {
+ DLIList<RefEdge*> edges;
+ bte->ref_edges(edges);
+ for (int j = 0; j < edges.size(); j++)
+ {
+ GMem poly, prev;
+ edges[j]->get_graphics(poly);
+ GPoint *prev_points = NULL;
+ prev_points = new GPoint[poly.point_list_size()];
+ for (int k = 0; k < poly.point_list_size(); k++)
+ {
+ CubitVector tempAxis = axis;
+ CubitVector tempV(poly.point_list()[k].x, poly.point_list()[k].y, poly.point_list()[k].z);
+ CubitVector b = tempV - CubitVector(0,0,0);
+ double dist = (tempAxis % b) / tempAxis.length();
+ tempAxis.length(dist);
+ CubitVector refl = tempV - tempAxis;
+ refl = refl - tempV + refl;
+ prev_points[k].x = refl.x();
+ prev_points[k].y = refl.y();
+ prev_points[k].z = refl.z();
+ }
+ GfxPreview::draw_polyline(prev_points, poly.point_list_size(), CUBIT_BLUE);
+ delete [] prev_points;
+ prev_points = NULL;
+ }
+ GfxPreview::flush();
+ return CUBIT_SUCCESS;
+ }
+
GeometryEntity* geom = bte->get_geometry_entity_ptr();
GeometryQueryEngine* engine = geom->get_geometry_query_engine();
CubitStatus result = engine->reflect( geom, axis );
@@ -5230,20 +6400,22 @@
return result;
}
-void GeometryQueryTool::ige_remove_modified(DLIList<TopologyBridge*>& geometry_list)
+void GeometryQueryTool::ige_remove_modified(DLIList<Surface*> &all_surfs,
+ DLIList<Curve*> &all_curves,
+ DLIList<Point*> &all_points)
{
IGESet::iterator itor;
for (itor = igeSet.begin(); itor != igeSet.end(); ++itor)
- (*itor)->remove_modified(geometry_list);
+ (*itor)->remove_modified(all_surfs, all_curves, all_points);
for (itor = igeSet.begin(); itor != igeSet.end(); ++itor)
(*itor)->clean_out_deactivated_geometry();
}
+
CubitBoolean GeometryQueryTool::bodies_overlap( Body *body_ptr_1,
Body *body_ptr_2 )
{
-
BodySM *body1 = body_ptr_1->get_body_sm_ptr();
BodySM *body2 = body_ptr_2->get_body_sm_ptr();
@@ -5261,3 +6433,376 @@
else
return body_ptr_1->get_geometry_query_engine()->bodies_overlap( body1, body2 );
}
+
+CubitBoolean GeometryQueryTool::volumes_overlap( RefVolume *volume_1,
+ RefVolume *volume_2 )
+{
+ Lump *lump1 = volume_1->get_lump_ptr();
+ Lump *lump2 = volume_2->get_lump_ptr();
+
+ if( is_intermediate_geometry( volume_1 ) )
+ return volume_1->get_geometry_query_engine()->volumes_overlap( lump1, lump2 );
+ else if( is_intermediate_geometry( volume_2 ) )
+ return volume_2->get_geometry_query_engine()->volumes_overlap( lump2, lump1 );
+ else if( volume_1->get_geometry_query_engine() !=
+ volume_2->get_geometry_query_engine() )
+ {
+ PRINT_ERROR("Volumes must be of the same type (ACIS, SolidWorks, etc) to\n"
+ "find if they overlap.\n");
+ return CUBIT_FALSE;
+ }
+ else
+ return volume_1->get_geometry_query_engine()->volumes_overlap( lump1, lump2 );
+}
+
+void GeometryQueryTool::find_nonmanifold_curves(DLIList<RefVolume*> &vol_list,
+ DLIList<RefEdge*> &curve_list)
+{
+ int i;
+ for(i=vol_list.size(); i>0; i--)
+ {
+ RefVolume *vol = vol_list.get_and_step();
+ DLIList<RefEdge*> vol_curves;
+ vol->ref_edges(vol_curves);
+ int j;
+ for(j=vol_curves.size(); j>0; j--)
+ {
+ RefEdge *cur_curve = vol_curves.get_and_step();
+ if(cur_curve->is_merged())
+ {
+ DLIList<RefFace*> curve_faces;
+ cur_curve->ref_faces(curve_faces);
+ bool merged_face_exists = false;
+ while(curve_faces.size() && !merged_face_exists)
+ {
+ RefFace *cur_face = curve_faces.pop();
+ if(cur_face->is_merged())
+ merged_face_exists = true;
+ }
+ if(!merged_face_exists)
+ curve_list.append(cur_curve);
+ }
+ }
+ }
+ curve_list.uniquify_ordered();
+}
+
+double GeometryQueryTool::estimate_merge_tolerance(DLIList<RefVolume*> &vol_list,
+ bool accurate_in,
+ bool report_in,
+ double lo_val_in,
+ double hi_val_in,
+ int num_calculations_in,
+ bool return_calculations_in,
+ DLIList<double> *merge_tols,
+ DLIList<int> *num_proximities)
+{
+ double return_merge_tol = -1.0; // return value of < 0.0 will mean failure
+ // to find a merge tolerance
+
+ DLIList<double> local_merge_tols;
+ DLIList<int> local_num_proximities;
+ bool accurate = accurate_in;
+ bool report = report_in;
+ double lo_val = 0.0;
+ double hi_val = get_geometry_factor()*GEOMETRY_RESABS*10.0; // 10 * merge tol -- arbitrary
+ int num_calculations = num_calculations_in;
+ bool return_calculations = return_calculations_in;
+
+ if(lo_val_in != -1.0)
+ lo_val = lo_val_in;
+ if(hi_val_in != -1.0)
+ hi_val = hi_val_in;
+
+ if(hi_val > lo_val)
+ {
+ double cur_val = lo_val;
+ double step = (hi_val - lo_val)/(double)num_calculations;
+ int i;
+ if(report)
+ {
+ PRINT_INFO("\n\nLooking for merge toleance...\n\n");
+ PRINT_INFO(" Possible range: %lf, %lf\n", lo_val, hi_val);
+ PRINT_INFO(" Number of steps: %d\n\n", num_calculations+1);
+ }
+
+ std::map <RefVertex*, DLIList<dist_vert_struct*>*> vert_dist_map;
+ GeomMeasureTool::find_near_coincident_vertices_unique(vol_list, hi_val, vert_dist_map);
+
+ int total_num_proximities = 0;
+ for(i=0; i<=num_calculations; i++)
+ {
+ int cur_num_proximities = 0;
+ local_merge_tols.append(cur_val);
+
+ std::map <RefVertex*, DLIList<dist_vert_struct*>*>::iterator iter;
+ for(iter=vert_dist_map.begin(); iter != vert_dist_map.end(); iter++ )
+ {
+ RefVertex *vert = iter->first;
+ DLIList<dist_vert_struct*> *struct_list = iter->second;
+ int m;
+ for(m=struct_list->size(); m>0; m--)
+ {
+ dist_vert_struct *dvs = struct_list->get();
+ if(dvs->dist <= cur_val)
+ {
+ // PRINT_INFO("Vertices %d and %d, distance: %.10lf\n", vert->id(), dvs->v2->id(), dvs->dist);
+ struct_list->change_to(NULL);
+ delete dvs;
+ cur_num_proximities++;
+ }
+ struct_list->step();
+ }
+ struct_list->remove_all_with_value(NULL);
+ }
+
+ total_num_proximities += cur_num_proximities;
+ local_num_proximities.append(total_num_proximities);
+
+ if(report)
+ {
+ PRINT_INFO(" At merge tolerance = %lf number of proximities = %d.\n", cur_val, total_num_proximities);
+ }
+
+ cur_val += step;
+ }
+
+ std::map <RefVertex*, DLIList<dist_vert_struct*>*>::iterator iter;
+ for(iter=vert_dist_map.begin(); iter != vert_dist_map.end(); iter++ )
+ {
+ DLIList<dist_vert_struct*> *struct_list = iter->second;
+ // I think all of the items in the lists should be gone
+ // by now but just in case...
+ while(struct_list->size())
+ delete struct_list->pop();
+ delete struct_list;
+ }
+
+ local_num_proximities.reset();
+ local_merge_tols.reset();
+ int num_total = local_merge_tols.size();
+ if(num_total > 2)
+ {
+ int num_triplets = num_total - 2;
+ int h, min_index, min_diff;
+ DLIList<int> diffs;
+ for(h=0; h<num_triplets; h++)
+ {
+ int num_begin = local_num_proximities.get();
+ local_num_proximities.step(2);
+ int num_end = local_num_proximities.get();
+ local_num_proximities.back();
+ int cur_diff = num_end - num_begin;
+ if(h==0)
+ {
+ min_index = h;
+ min_diff = cur_diff;
+ }
+ else
+ {
+ if(cur_diff < min_diff)
+ {
+ min_diff = cur_diff;
+ min_index = h;
+ }
+ }
+ }
+ local_merge_tols.step(min_index+1);
+ return_merge_tol = local_merge_tols.get();
+ }
+ else
+ PRINT_ERROR("Unable to estimate merge tolerance.\n");
+
+/*
+ // Pick off a merge tolerance.
+ local_num_proximities.reset();
+ local_merge_tols.reset();
+ DLIList<int> unique_num_proximities;
+ DLIList<int> unique_counts;
+ DLIList<double> tmp_merge_tol_list;
+ int tmp_num_proximities;
+ double tmp_merge_tol;
+
+ double cur_merge_tol = local_merge_tols.get_and_step();
+ int cur_num_prox = local_num_proximities.get_and_step();
+ int cur_unique_counts = 1;
+ // Loop over the whole size even though we have processed the
+ // first entry because we need to record the results after the
+ // last entry.
+ for(i=local_num_proximities.size(); i>0; i--)
+ {
+ if(i>1)
+ {
+ tmp_num_proximities = local_num_proximities.get_and_step();
+ tmp_merge_tol = local_merge_tols.get_and_step();
+ }
+ else
+ {
+ // On the last time in just give it a dummy value so we
+ // can record the results from the last real entry.
+ tmp_num_proximities = -1;
+ }
+ if(cur_num_prox == tmp_num_proximities)
+ {
+ cur_unique_counts++;
+ }
+ else
+ {
+ tmp_merge_tol_list.append(cur_merge_tol);
+ unique_counts.append(cur_unique_counts);
+ unique_num_proximities.append(cur_num_prox);
+ cur_unique_counts = 1;
+ cur_num_prox = tmp_num_proximities;
+ cur_merge_tol = tmp_merge_tol;
+ }
+ }
+
+ int max_index = -1;
+ int cur_max_num_counts = 0;
+ unique_counts.reset();
+ unique_num_proximities.reset();
+ tmp_merge_tol_list.reset();
+ for(i=unique_counts.size(); i>0; i--)
+ {
+ int cur_num_counts = unique_counts.get();
+ if(cur_num_counts > cur_max_num_counts)
+ {
+ cur_max_num_counts = cur_num_counts;
+ max_index = unique_counts.get_index();
+ }
+ unique_counts.step();
+ }
+
+ if(max_index > -1)
+ {
+ tmp_merge_tol_list.step(max_index);
+ return_merge_tol = tmp_merge_tol_list.get();
+ }
+ else
+ {
+ PRINT_ERROR("Unable to estimate merge tolerance.\n");
+ }
+ */
+
+ if(report)
+ PRINT_INFO("\nEstimated merge tolerance: %lf\n", return_merge_tol);
+ }
+ else
+ PRINT_ERROR("Range low value is larger than range high value.\n");
+
+ return return_merge_tol;
+}
+
+void GeometryQueryTool::find_floating_volumes(DLIList<RefVolume*> &vol_list,
+ DLIList<RefVolume*> &floating_list)
+{
+ int i;
+ for(i=vol_list.size(); i>0; i--)
+ {
+ bool floating = true;
+ RefVolume *vol = vol_list.get_and_step();
+ DLIList<RefEdge*> vol_curves;
+ DLIList<RefVertex*> vol_verts;
+ DLIList<RefFace*> vol_surfs;
+ vol->ref_edges(vol_curves);
+ vol->ref_faces(vol_surfs);
+ vol->ref_vertices(vol_verts);
+ int j;
+ for(j=vol_surfs.size(); j>0 && floating; j--)
+ {
+ RefFace *cur_surf = vol_surfs.get_and_step();
+ if(cur_surf->is_merged())
+ floating = false;
+ }
+ for(j=vol_curves.size(); j>0 && floating; j--)
+ {
+ RefEdge *cur_curve = vol_curves.get_and_step();
+ if(cur_curve->is_merged())
+ floating = false;
+ }
+ for(j=vol_verts.size(); j>0 && floating; j--)
+ {
+ RefVertex *cur_vert = vol_verts.get_and_step();
+ if(cur_vert->is_merged())
+ floating = false;
+ }
+ if(floating)
+ floating_list.append(vol);
+ }
+ floating_list.uniquify_ordered();
+}
+
+void GeometryQueryTool::find_nonmanifold_vertices(DLIList<RefVolume*> &vol_list,
+ DLIList<RefVertex*> &vertex_list)
+{
+ int i;
+ for(i=vol_list.size(); i>0; i--)
+ {
+ RefVolume *vol = vol_list.get_and_step();
+ DLIList<RefVertex*> vol_verts;
+ vol->ref_vertices(vol_verts);
+ int j;
+ for(j=vol_verts.size(); j>0; j--)
+ {
+ RefVertex *cur_vert = vol_verts.get_and_step();
+ if(cur_vert->is_merged())
+ {
+ DLIList<RefEdge*> vert_edges;
+ cur_vert->ref_edges(vert_edges);
+ bool merged_edge_exists = false;
+ while(vert_edges.size() && !merged_edge_exists)
+ {
+ RefEdge *cur_edge = vert_edges.pop();
+ if(cur_edge->is_merged())
+ merged_edge_exists = true;
+ }
+ if(!merged_edge_exists)
+ vertex_list.append(cur_vert);
+ }
+ }
+ }
+ vertex_list.uniquify_ordered();
+}
+
+CGMHistory& GeometryQueryTool::history()
+{
+ return mHistory;
+}
+
+void GeometryQueryTool::get_merged_away_free_entities( DLIList<RefEntity*> &ref_ents,
+ DLIList<TopologyBridge*> &free_ents )
+{
+ //determine if you have any free entities that were merged away
+ DLIList<RefEntity*> merged_ref_ents;
+ MergeTool::instance()->contains_merged_entities( ref_ents, &merged_ref_ents );
+ int i;
+ for( i=merged_ref_ents.size(); i--; )
+ {
+ RefEntity *tmp_ent = merged_ref_ents.get_and_step();
+ DLIList<TopologyBridge*> bridge_list;
+ TopologyEntity *te = CAST_TO(tmp_ent, TopologyEntity );
+ te->bridge_manager()->get_bridge_list( bridge_list );
+ //bridge_list.reset();
+ //bridge_list.step(); //don't want to first bridge...that's the real thing
+
+ //check for free entities...
+ int j;
+ for( j=0; j<bridge_list.size(); j++ )
+ {
+ TopologyBridge *tmp_bridge = bridge_list.get_and_step();
+
+ //ignore the representation bridge if it's a free vertex
+ if( j==0 )
+ if( tmp_ent->num_parent_ref_entities() == 0 )
+ continue;
+
+ DLIList<TopologyBridge*> parents;
+ tmp_bridge->get_parents( parents );
+ if( parents.size() == 0 )
+ free_ents.append( tmp_bridge );
+ }
+ }
+}
+
+
+
Modified: cgm/branches/cubit/geom/GeometryQueryTool.hpp
===================================================================
--- cgm/branches/cubit/geom/GeometryQueryTool.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/GeometryQueryTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -27,6 +27,7 @@
#include "DLIList.hpp"
#include "GeometryQueryEngine.hpp"
#include "IntermediateGeomEngine.hpp"
+#include "CGMHistory.hpp"
class RefGroup;
class Body;
@@ -74,6 +75,12 @@
class CubitTransformMatrix;
class TBOwner;
+#ifdef PROE
+class RefPart;
+class RefAssembly;
+#endif
+
+//! Interface class for querying geometry.
class CUBIT_GEOM_EXPORT GeometryQueryTool
{
public :
@@ -81,10 +88,13 @@
friend class GeometryModifyTool;
bool ige_is_composite(TBOwner *bridge_owner);
+ bool ige_is_composite(TopologyBridge *bridge);
bool ige_is_partition(TBOwner *bridge_owner);
- void ige_remove_modified(DLIList<TopologyBridge*>& geometry_list);
+ void ige_remove_modified(DLIList<Surface*> &all_surfs,
+ DLIList<Curve*> &all_curves,
+ DLIList<Point*> &all_points);
static GeometryQueryTool* instance( GeometryQueryEngine* gqePtr = NULL);
/**<
@@ -105,99 +115,205 @@
~GeometryQueryTool();
///< Destructor.
+ static void delete_instance();
+
+ //!
+ //! \brief Estimates a good merge tolerance for the volumes passed in.
+ //!
+ double estimate_merge_tolerance(DLIList<RefVolume*> &vol_list,
+ bool accurate_in = false,
+ bool report_in = false,
+ double lo_val_in = -1.0,
+ double hi_val_in = -1.0,
+ int num_calculations_in = 10,
+ bool return_calculations_in = false,
+ DLIList<double> *merge_tols = NULL,
+ DLIList<int> *num_proximities = NULL);
+ //!
+ //! \brief Find all of the volumes that do not contain any merged entities.
+ //!
+ void find_floating_volumes(DLIList<RefVolume*> &vol_list,
+ DLIList<RefVolume*> &floating_list);
+
+ //!
+ //! \brief Find the nonmanifold curves in the passed-in volumes based on what is merged.
+ //!
+ void find_nonmanifold_curves(DLIList<RefVolume*> &vol_list, DLIList<RefEdge*> &curve_list);
+
+ //!
+ //! \brief Find the nonmanifold vertices in the passed-in volumes based on what is merged.
+ //!
+ void find_nonmanifold_vertices(DLIList<RefVolume*> &vol_list, DLIList<RefVertex*> &vertex_list);
+
CubitStatus register_intermediate_engine( IntermediateGeomEngine* engine );
+ void unregister_intermediate_engine( IntermediateGeomEngine* engine );
void ige_remove_imprint_attributes_after_modify(DLIList<BodySM*> &old_sms,
DLIList<BodySM*> &new_sms);
void ige_push_imprint_attributes_before_modify
( DLIList<BodySM*> &geom_list );
+ void ige_push_named_attributes_to_curves_and_points
+ ( DLIList<TopologyBridge*> &tb_list, const char *name_in );
void ige_export_geom( DLIList<TopologyBridge*> &geom_list );
void ige_import_geom( DLIList<TopologyBridge*> &geom_list );
void ige_remove_attributes( DLIList<TopologyBridge*> &geom_list );
void ige_attribute_after_imprinting( DLIList<TopologyBridge*> &new_tbs,
DLIList<TopologyBridge*> &att_tbs,
- DLIList<BodySM*> &new_sms,
+ DLIList<TopologyBridge*> &tb_list,
DLIList<Body*> &old_bodies);
void ige_remove_attributes_from_unmodifed_virtual(DLIList<TopologyBridge*> &bridges);
+
+ //Using the source_bridge, finds all bridges that actually have a BridgeManager the owner.
+ //This is for obtaining the real TopologyBridge when all you have is a TopologyBridge
+ //that is Partition Entity.
+ void get_tbs_with_bridge_manager_as_owner( TopologyBridge *source_bridge,
+ DLIList<TopologyBridge*> &tbs );
/*! <HR><H1> global-list-functions Global entity list functions </H1>*/
- CubitStatus cubit_entity_list( const char* keyword,
- DLIList<CubitEntity*> &entity_list,
- const CubitBoolean print_errors = CUBIT_TRUE);
- /**< return ref entities in a generic cubit entity list (overwrites list).
- * returns CUBIT_FAILURE if keyword is not a ref entity name, and
- * optionally prints error message
- */
+ //
+ // Returns ref entities in a generic cubit entity list (overwrites list).
+ // returns CUBIT_FAILURE if keyword is not a ref entity name, and
+ // optionally prints error message
+ //
+ //CubitStatus cubit_entity_list( const char* keyword,
+ // DLIList<CubitEntity*> &entity_list,
+ // const CubitBoolean print_errors = CUBIT_TRUE);
+ //!
+ //! \brief Return ref entities in entity_list (overwrites list).
+ //! returns CUBIT_FAILURE if keyword is not a ref entity name,
+ //! and optionally prints error message
+ //!
+
CubitStatus ref_entity_list( char const* keyword,
DLIList<RefEntity*> &entity_list,
const CubitBoolean print_errors = CUBIT_TRUE);
- /**< return ref entities in entity_list (overwrites list).
- * returns CUBIT_FAILURE if keyword is not a ref entity name,
- * and optionally prints error message
- */
+ //! \brief Returns the bounding box of the model. Include free entities.
CubitBox model_bounding_box();
+
+ /*! Returns the bounding box of all bodies in the model. Excludes
+ free entities.*/
+ //! \brief Returns the bounding box of all bodies in the model.
+ CubitBox bounding_box_of_bodies();
+
+
+ //! \brief Returns all the bodies in the current session.
void bodies (DLIList<Body*> &bodies);
+
+ //! \brief Returns all volumes in the current session.
void ref_volumes (DLIList<RefVolume*> &ref_volumes);
+
+ //! \brief Returns all groups in the current session.
void ref_groups (DLIList<RefGroup*> &ref_groups);
+
+ //! \brief Returns all surfaces in the current session.
void ref_faces (DLIList<RefFace*> &ref_faces);
+
+ //! \brief Returns all curves in the current session.
void ref_edges (DLIList<RefEdge*> &ref_edges);
+
+ //! \brief Returns all the vertices in the current session.
void ref_vertices (DLIList<RefVertex*> &ref_vertices);
+
+#ifdef PROE
+ void ref_parts (DLIList<RefPart*> &ref_parts);
+ void ref_assemblies (DLIList<RefAssembly*> &ref_assemblies);
+#endif //PROE
///< Append global lists to arguments
+ //! \brief Number of bodies in current session.
int num_bodies() const;
+
+ //! \brief Number of volumes in current session.
int num_ref_volumes() const;
+
+ //! \brief Number of groups in current session.
int num_ref_groups() const;
+
+ //! \brief Number of surfaces in current session.
int num_ref_faces() const;
+
+ //! \brief Number of curves in current session.
int num_ref_edges() const;
+
+ //! \brief Number of vertices in current session.
int num_ref_vertices() const;
- ///< Return number of entities of the specified type
+ //! \brief Get RefEntity by type name and id.
RefEntity *get_ref_entity (const char *type, int id);
+
+ //! \brief Get a RefEntity of the specified type and id.
RefEntity *get_ref_entity (const type_info& type, int id);
- ///< Get a ref entity of the specified type and id
+ //! \brief Get entity by id.
Body *get_body ( int id );
+
+ //! \brief Get entity by id.
RefVolume *get_ref_volume ( int id );
+
+ //! \brief Get entity by id.
RefGroup *get_ref_group ( int id );
+
+ //! \brief Get entity by id.
RefFace *get_ref_face ( int id );
+
+ //! \brief Get entity by id.
RefEdge *get_ref_edge ( int id );
+
+ //! \brief Get entity by id.
RefVertex *get_ref_vertex ( int id );
- ///< Get an entity of the specified type and id
+
+ //! \brief Get the first entity in the global list of the specified type
Body *get_first_body ();
+ //! \brief Get the first entity in the global list of the specified type
RefVolume *get_first_ref_volume ();
+ //! \brief Get the first entity in the global list of the specified type
RefGroup *get_first_ref_group ();
+ //! \brief Get the first entity in the global list of the specified type
RefFace *get_first_ref_face ();
+ //! \brief Get the first entity in the global list of the specified type
RefEdge *get_first_ref_edge ();
+ //! \brief Get the first entity in the global list of the specified type
RefVertex *get_first_ref_vertex ();
- ///< Get the first entity in the global list of the specified type
+ //! \brief Get the next entity in the global list of the specified type
Body *get_next_body ();
+ //! \brief Get the next entity in the global list of the specified type
RefVolume *get_next_ref_volume ();
+ //! \brief Get the next entity in the global list of the specified type
RefGroup *get_next_ref_group ();
+ //! \brief Get the next entity in the global list of the specified type
RefFace *get_next_ref_face ();
+ //! \brief Get the next entity in the global list of the specified type
RefEdge *get_next_ref_edge ();
+ //! \brief Get the next entity in the global list of the specified type
RefVertex *get_next_ref_vertex ();
- ///< Get the next entity in the global list of the specified type
+ ///! \brief Get the last entity in the global list of the specified type
Body *get_last_body ();
+ ///! \brief Get the last entity in the global list of the specified type
RefVolume *get_last_ref_volume ();
+ ///! \brief Get the last entity in the global list of the specified type
RefGroup *get_last_ref_group ();
+ ///! \brief Get the last entity in the global list of the specified type
RefFace *get_last_ref_face ();
+ ///! \brief Get the last entity in the global list of the specified type
RefEdge *get_last_ref_edge ();
+ ///! \brief Get the last entity in the global list of the specified type
RefVertex *get_last_ref_vertex ();
- /**< Get the last entity in the global list of the specified type
-
- <HR><H3>File operations (import, export)</H3>
- */
-
+
+
+ //! \brief Get all free surfaces, curves, and vertices
CubitStatus get_free_ref_entities(DLIList<RefEntity*> &free_entities);
- //- returns the list of free entities in the model
+ //! \brief Get the free entities connected to, but not necessarily
+ //! vertically related to, the entity. - If merge_option, then take
+ //! into account the fact that the model may be merged (it's slower
+ //! that way).
void get_connected_free_ref_entities(
RefEntity *entity,
const int merge_option,
@@ -205,71 +321,57 @@
DLIList<RefFace*> &ref_face_list,
DLIList<RefEdge*> &ref_edge_list,
DLIList<RefVertex*> &ref_vertex_list );
- //- get the free entities connected to, but not necessarily
- //- vertically related to, the entity. - If merge_option, then take
- //- into account the fact that the model may be merged (it's slower
- //- that way).
+ //! \brief Saves out a temporary geometry file containing specified entities
+ //! that are of the same geometry engine.
CubitStatus save_temp_geom_files( DLIList<RefEntity*>& ref_entity_list,
const char* filename,
const CubitString &cubit_version,
std::list<CubitString> &files_written,
std::list<CubitString> &types_written);
+
+ //!
+ //! * Export entities to a solid model file.
+ //! * \arg ref_entity_list
+ //! * A list of RefEntities to be exported or saved to a file.
+ //! * \arg file_name
+ //! * The name of the file to write to.
+ //! * \arg file_type
+ //! * An optional type of file.
+ //! * \arg logfile_name
+ //! * Optional - name of logfile.
+ //! * \return CubitStatus - success/failure
+ //! *
+ //! * Export the current CUBIT geometry (everything in the Model) to a
+ //! * solid model format. Valid file types are:
+ //! * "ACIS_SAT" -- ACIS ASCII (SAT) file format
+ //! * "ACIS_SAB" -- ACIS BINARY (SAB) file format
+ //! * "ACIS_DEBUG" -- ACIS ASCII debug format
+ //! * "IGES" -- IGES file
+ //! * "STEP" -- STEP file
+ //! No logfile gets created for SAB/SAT files, but for IGES and
+ //! STEP file a logfile always gets created. Default filenames
+ //! are assigned if one is not given (iges_export.log, step_export.log).
+ //!
+ //! The function returns CUBIT_FAILURE if anything goes wrong with
+ //! export - improper file type, inaccessible file, mismatch between
+ //! the underlying representation and file type. It returns
+ //! CUBIT_SUCCESS if everything goes well.
+ //!
+ //! NOTE: if the ref_entity_list is empty, GeometryQueryTool gets the list of
+ //! all entities in the current model, including free ref entities
+ //! \brief Save a geometry file containing specified entities
+ //! that are of the same geometry engine.
CubitStatus export_solid_model( DLIList<RefEntity*>& ref_entity_list,
const char* filename,
const char * filetype,
int &num_ents_exported,
const CubitString &cubit_version,
const char* logfile_name = NULL );
- /**<
- * Export entities to a solid model file.
- * \arg ref_entity_list
- * A list of RefEntities to be exported or saved to a file.
- * \arg file_name
- * The name of the file to write to.
- * \arg file_type
- * An optional type of file.
- * \arg logfile_name
- * Optional - name of logfile.
- * \return CubitStatus - success/failure
- *
- * Export the current CUBIT geometry (everything in the Model) to a
- * solid model format. Valid file types are:
- * "ACIS_SAT" -- ACIS ASCII (SAT) file format
- * "ACIS_SAB" -- ACIS BINARY (SAB) file format
- * "ACIS_DEBUG" -- ACIS ASCII debug format
- * "IGES" -- IGES file
- * "STEP" -- STEP file
- * No logfile gets created for SAB/SAT files, but for IGES and
- * STEP file a logfile always gets created. Default filenames
- * are assigned if one is not given (iges_export.log, step_export.log).
- *
- * The function returns CUBIT_FAILURE if anything goes wrong with
- * export - improper file type, inaccessible file, mismatch between
- * the underlying representation and file type. It returns
- * CUBIT_SUCCESS if everything goes well.
- *
- * NOTE: if the ref_entity_list is empty, GeometryQueryTool gets the list of
- * all entities in the current model, including free ref entities
- *
- */
- CubitStatus import_temp_geom_file(FILE* file_ptr,
- const char* file_type );
-
- CubitStatus import_solid_model(const char* file_name,
- const char* file_type,
- const char* logfile_name = NULL,
- CubitBoolean heal_step = CUBIT_TRUE,
- CubitBoolean import_bodies = CUBIT_TRUE,
- CubitBoolean import_surfaces = CUBIT_TRUE,
- CubitBoolean import_curves = CUBIT_TRUE,
- CubitBoolean import_vertices = CUBIT_TRUE,
- CubitBoolean free_surfaces = CUBIT_TRUE,
- DLIList<RefEntity*> *imported_entities = NULL);
- /**<
- * Import all or specified entities in a solid model file.
+ /*!
+ Import all or specified entities in a solid model file.
* \arg file_ptr
* A pointer to the file to read (can be NULL for IGES and STEP files).
* \arg file_type
@@ -297,106 +399,120 @@
* the underlying representation and file type. It returns
* CUBIT_SUCCESS if everything goes well.
*/
+ //! \brief Import a geometry file.
+ CubitStatus import_solid_model(const char* file_name,
+ const char* file_type,
+ const char* logfile_name = NULL,
+ CubitBoolean heal_step = CUBIT_TRUE,
+ CubitBoolean import_bodies = CUBIT_TRUE,
+ CubitBoolean import_surfaces = CUBIT_TRUE,
+ CubitBoolean import_curves = CUBIT_TRUE,
+ CubitBoolean import_vertices = CUBIT_TRUE,
+ CubitBoolean free_surfaces = CUBIT_TRUE,
+ DLIList<RefEntity*> *imported_entities = NULL);
- CubitStatus construct_refentities(DLIList<TopologyBridge*> &topology_bridges,
- DLIList<RefEntity*> *imported_entities = NULL);
- //- given a list of TB's, construct ref entities for them; if the 2nd list pointer is
- //- non-NULL, pass back the list of ref entities in that list
-
- CubitStatus read_geometry_file(char const* fileName,
- char const* includePath = NULL,
- char const* type = "ACIS_SAT");
- /**<
- * Read geometry from the specified file.
- * \arg filename
- * The name of the file to read.
- * \arg includePath
- * An optional path to be used to search for the file if the file
- * is not in the current directory.
- * \arg type
- * An optional type of file.
- * \return CubitStatus - success/failure
+ /*!
+ * Fire a ray at entities, passing back distances of hits and entities hit
+ * \arg origin
+ * origin of ray
+ * \arg direction
+ * direction of ray
+ * \arg at_entity_list
+ * entities to fire ray at
+ * \arg ray_params
+ * returned array of parameters (distances) along ray at which entities were hit
+ * \arg max_hits
+ * maximum number of hits to return, 0 = unlimited (default)
+ * \arg ray_radius
+ * radius of ray to use for intersecting entities, 0 = use engine default
+ * \arg hit_entity_list (pointer)
+ * entities hit by ray (list length same as ray_params), default NULL
+ * \return - error flag
*
- * Reads a geometry file (named fileName). If the file cannot be found
- * in the current directory, and if includePath is not NULL, the include
- * path specified by includePath is added to the file name, and it is
- * searched in the given order. The file type specified in the "type"
- * argument determines what type of geometry file it is -- the default
- * is an ACIS SAT file.
- * Supported geometry file types are:
- * "ACIS_SAT" -- ACIS SAT file format
- * "ACIS_SAB" -- ACIS SAB file format (binary)
- * The function returns CUBIT_FAILURE if it cannot open the file, or
- * the "type" is not known. Otherwise it returns CUBIT_SUCCESS.
+ * Fire a ray at specified entities, returning the parameters (distances)
+ * along the ray and optionally the entities hit; return CUBIT_FAILURE if
+ * error. Returned lists are appended to.
*/
- int fire_ray(Body* body,
- const CubitVector ray_point,
- const CubitVector unit,
- DLIList<double>& ray_params,
- DLIList<RefEntity*> *entity_list);
- /**<
- * Fire a ray at a body, passing back number and distances of hits.
- * \arg body
- * Body at which you are firing rays
- * \arg ray_point
- * beginning point of ray
- * \arg unit
- * direction of ray (unit vector)
- * num_hit
- *-number of bodies hit
- * ray_params
- * array of parameters along ray at which bodies were hit
- * entity_list
- * entities hit by ray
- * \return - error flag
+ //! \brief Fire a ray at entities, passing back distances of hits and entities hit
+ CubitStatus fire_ray( CubitVector &origin,
+ CubitVector &direction,
+ DLIList<RefEntity*> &at_entity_list,
+ DLIList<double> &ray_params,
+ int max_hits = 0,
+ double ray_radius = 0.0,
+ DLIList<RefEntity*> *hit_entity_list_ptr = 0 );
+
+ /*!
+ * Fire a ray at entities, passing back distances of hits and entities hit
+ * \arg origin
+ * origin of ray
+ * \arg direction
+ * direction of ray
+ * \arg at_entity_list
+ * entities to fire ray at
+ * \arg ray_params
+ * returned array of parameters (distances) along ray at which entities were hit
+ * \arg max_hits
+ * maximum number of hits to return, 0 = unlimited (default)
+ * \arg ray_radius
+ * radius of ray to use for intersecting entities, 0 = use engine default
+ * \arg hit_entity_list (pointer)
+ * entities hit by ray (list length same as ray_params), default NULL
+ * \return - error flag
*
- * fire a ray at the specified body, returning the entities
- * hit and the parameters along the ray; return CUBIT_FAILURE
- * if error
+ * Fire a ray at specified entities, returning the parameters (distances)
+ * along the ray and optionally the entities hit; return CUBIT_FAILURE if
+ * error. Returned lists are appended to. NOTE: ALL ENTITIES MUST BE FROM
+ * THE SAME GEOMETRY ENGINE.
*/
+ //! \brief Fire a ray at entities, passing back distances of hits and entities hit
+ CubitStatus fire_ray( CubitVector &origin,
+ CubitVector &direction,
+ DLIList<TopologyEntity*> &at_entity_list,
+ DLIList<double> &ray_params,
+ int max_hits = 0,
+ double ray_radius = 0.0,
+ DLIList<TopologyEntity*> *hit_entity_list_ptr = 0 );
+
+ //! \brief Debugging function.
+ static void geom_debug( DLIList<TopologyEntity*> );
- static void geom_debug( DLIList<TopologyEntity*> );
- /**< Temporary debug tool -- Steve Jankovich
- */
+ //! \brief Set facet box flag
static void set_facet_bbox( CubitBoolean pass_flag )
{useFacetBBox = pass_flag;}
+
+ //! \brief Get facet box flag
static CubitBoolean get_facet_bbox()
{return useFacetBBox;}
- /**< get and set the useFacetBBox flag. (compute our own bbox
- * instead of relying on bad ACIS geometry)
- */
-
+ //! \brief Calls engine version of the active geometry engine.
CubitString get_engine_version_string();
- /**< Calls get_engine_version_string() function of underlying ModelingEngine.
- */
+ //! \brief Set the major/minor version of the active geometry engine.
CubitStatus set_export_allint_version(int version);
- /**< set the major/minor version of the geometry engine
- */
+ //! \brief Get the major/minor version of the active geometry engine.
int get_allint_version();
- /**< get the major/minor version of the geometry engine
- */
+ //! \brief Returns a string with the versions of the active geometry engine.
CubitStatus list_engine_versions(CubitString &versions);
- /**< returns a string with the engine version choices
- */
+ //! \brief Gets solid modeler's resolution absolute tolerance
double get_sme_resabs_tolerance();
+
+ //! \brief Sets solid modeler's resolution absolute tolerance
double set_sme_resabs_tolerance( double new_resabs );
- /**< Gets/Sets solid modeler's resolution absolute tolerance
- */
+ //! \brief Set solid modeler integer option.
CubitStatus set_sme_int_option( const char* opt_name, int val );
+ //! \brief Set solid modeler double option.
CubitStatus set_sme_dbl_option( const char* opt_name, double val );
+ //! \brief Set solid modeler string option.
CubitStatus set_sme_str_option( const char* opt_name, const char* val );
- /**< Set solid modeler options
- */
+
///< <HR><H3>Topology/geometry creation functions</H3>
-
Body* make_Body(BodySM *bodysm_ptr) const;
RefFace* make_RefFace(Surface* surface_ptr ) const;
RefEdge* make_RefEdge(Curve* curve_ptr) const;
@@ -404,7 +520,7 @@
static CubitSense relative_sense( Surface* surface1, Surface* surface2 );
- RefFace* make_free_RefFace(Surface *surface_ptr ) const;
+ RefFace* make_free_RefFace(Surface *surface_ptr, bool is_free_surface) const;
RefEdge* make_free_RefEdge(Curve *curve_ptr ) const;
RefVertex* make_free_RefVertex(Point *point_ptr) const;
/**< These functions can be used to create free ref-entities
@@ -416,13 +532,12 @@
///<HR><H3>Topology and geometry deletion</H3>
+ /*! \brief Deletes all Bodies in the input list from the model. Their
+ associated Solid Model entities are deleted as well, if they exist,
+ and if remove_solid_model_entities is CUBIT_TRUE.
+ */
void delete_Body( DLIList<Body*>& body_list );
- /**< Deletes all Bodies in the input list from the model. Their
- * associated Solid Model entities are deleted as well, if they exist,
- * and if remove_solid_model_entities is CUBIT_TRUE.
- */
- CubitStatus delete_Body( Body* body_ptr );
/**< Deletes the input Body from the model.
* Its associated Solid Model entities are deleted as well, if
* they exist, and if remove_solid_model_entities is CUBIT_TRUE.
@@ -430,96 +545,106 @@
* as the Body itself has been deleted.
* Returns CUBIT_SUCCESS if all went well, otherwise, CUBIT_FAILURE.
*/
+ //! \brief Deletes a body.
+ CubitStatus delete_Body( Body* body_ptr );
- CubitStatus delete_single_Body( Body* body_ptr );
- /**< Behaves exactly as delete_Body, but in addition checks to see if
+ /*! Behaves exactly as delete_Body, but in addition checks to see if
* children of Body are merged. In some cases, 2 entities can be
* forced-merged, where they are not spatially equal. This regenerates
* the graphics on merged entities so they look correct after a partner
* has been deleted.
*/
+ //! \brief Deletes a body.
+ CubitStatus delete_single_Body( Body* body_ptr );
+ //! \brief Deletes free RefEnties
CubitStatus delete_RefEntity( RefEntity* ref_entity_ptr );
+
+ //! \brief Deletes the RefFace if it is free
CubitStatus delete_RefFace( RefFace* ref_face_ptr );
+
+ //! \brief Deletes the RefEdge if it is free
CubitStatus delete_RefEdge( RefEdge* ref_edge_ptr );
+
+ //! \brief Deletes the RefVertex if it is free
CubitStatus delete_RefVertex( RefVertex* ref_vertex_ptr );
- /**< This function is used to delete free-floating RefFaces, RefEdges
- * or RefVertex'es. All underlying VGI and solid model entities (if
- * any) are also deleted. The entities will *not* be deleted is
- * the input RefEntity has an owner (e.g., if the input RefEdge
- * is owned by a RefFace).
- */
void cleanout_deactivated_geometry();
void cleanout_temporary_geometry ();
-
+
+ //! \brief Deletes all geometry.
void delete_geometry();
- ///< <HR><H3>Miscellaneous geometry evaluation functions</H3>
-
+
+ /*! \brief Creates a list of vectors the length of the number_points that
+ interpolate between vector_1 and vector_2. All of the points
+ will lie on the underlying equation of the refface.
+ */
CubitStatus interpolate_along_surface( CubitVector *vector_1,
CubitVector *vector_2,
DLIList<CubitVector*> &vector_list,
RefFace* ref_face_ptr,
int number_points ) const;
- /**< Creates a list of vectors the length of the number_points that
- * interpolate between vector_1 and vector_2. All of the points
- * will lie on the underlying equation of the refface.
+ /*! \return CubitBoolean
+ \return - CUBIT_TRUE/CUBIT_FALSE
+ \arg Vec1
+ A reference to the first vector.
+ \arg Vec2
+ A reference to the second vector.
+ \arg tolerance_factor
+ Factor by which the absolute internal tolerance shall be
+ multiplied.
+ * Returns CUBIT_TRUE if the input Vec1 and Vec2 are spatially
+ equivalent within a tolerance. The internal spatial tolerance
+ value is multiplied by tolerance_factor before the (spatial)
+ test is done. Else, returns CUBIT_FALSE.
*/
-
+ //! \brief Compares two positions for coincidence.
CubitBoolean about_spatially_equal (const CubitVector& Vec1,
const CubitVector& Vec2,
double tolerance_factor = 1.0);
- /**< \return CubitBoolean
- * \return - CUBIT_TRUE/CUBIT_FALSE
- * \arg Vec1
- * A reference to the first vector.
- * \arg Vec2
- * A reference to the second vector.
- * \arg tolerance_factor
- * Factor by which the absolute internal tolerance shall be
- * multiplied.
- *
- * Returns CUBIT_TRUE if the input Vec1 and Vec2 are spatially
- * equivalent within a tolerance. The internal spatial tolerance
- * value is multiplied by tolerance_factor before the (spatial)
- * test is done. Else, returns CUBIT_FALSE.
- */
+ //! \brief Compares two vertices for coincidence.
CubitBoolean about_spatially_equal (RefVertex* refVertex1,
RefVertex* refVertex2,
double tolerance_factor = 1.0);
+ /*! \brief Calculates internal surface angles given 2 refedges on the
+ * surface. CoEdge version correctly handles curves in a surface
+ * twice. */
double geometric_angle(RefEdge* ref_edge_1,
RefEdge* ref_edge_2,
RefFace* ref_face );
+
+ /*! \brief Calculates internal surface angles given 2 refedges on the
+ surface. This version correctly handles curves in a surface twice. */
double geometric_angle(CoEdge* co_edge_1,
CoEdge* co_edge_2 );
- /**< calculates internal surface angles given 2 refedges on the
- * surface. CoEdge version correctly handles curves in a surface
- * twice.
- */
+ /*! \brief Calculate dihedral angle at curve between two surfaces of the
+ volume. */
double surface_angle( RefFace *ref_face_1, RefFace *ref_face_2,
RefEdge *ref_edge = NULL,
RefVolume *ref_volume = NULL,
double frac = 0.5);
- /**< Calculate dihedral angle at ref_edge between two faces of the
- * volume.
- */
+ /*! Finds the intersections between a curve and a line If the bounded flag
+ * is true, it finds only those intersections within the parameter range
+ * of the curve; otherwise it uses the extensions of the curve. The
+ * closest option is currently valid only if the curve is straight,
+ * in which case it will return the 2 closest intersection locations,
+ * if the straight lines don't actually intersect. The function allocates
+ * allocates the CubitVectors in the returned list, so be sure to free them.
+ */
+ //! \brief Finds the intersections of a straight line and a curve.
CubitStatus get_intersections( RefEdge* ref_edge1,
CubitVector& point1,
CubitVector& point2,
DLIList<CubitVector*>& intersection_list,
CubitBoolean bounded = CUBIT_FALSE,
CubitBoolean closest = CUBIT_FALSE);
-
- CubitStatus get_intersections( RefEdge* ref_edge1, RefEdge* ref_edge2,
- DLIList<CubitVector*>& intersection_list,
- CubitBoolean bounded = CUBIT_FALSE,
- CubitBoolean closest = CUBIT_FALSE );
- /**< Finds the intersections of the two curves. If the bounded flag is
+
+ /*! Finds the intersections of the two curves. If the bounded flag is
* true, it finds only those intersections within the parameter range
* of both curves; otherwise it uses the extensions of the curves. The
* closest option is currently valid only if both curves are straight,
@@ -529,56 +654,83 @@
* curves, unless both curves are linear. The function allocates the
* CubitVectors in the returned list, so be sure to free them.
*/
+ //! \brief Finds the intersections of two curves.
+ CubitStatus get_intersections( RefEdge* ref_edge1, RefEdge* ref_edge2,
+ DLIList<CubitVector*>& intersection_list,
+ CubitBoolean bounded = CUBIT_FALSE,
+ CubitBoolean closest = CUBIT_FALSE );
+ /*! Finds the intersections of the curve and surface. The curve is extended
+ * if the bounded flag is not false. The function allocates the CubitVectors
+ * in the returned list, so be sure to free them.
+ */
+ //! \brief Finds the intersections of the curve and surface.
CubitStatus get_intersections( RefEdge* ref_edge, RefFace* ref_face,
DLIList<CubitVector*>& intersection_list,
CubitBoolean bounded = CUBIT_FALSE );
- /**< Finds the intersections of the curve and surface. The curve is extended
- * if the bounded flag is not false. The function allocates the CubitVectors
- * in the returned list, so be sure to free them.
+
+ /*! Gets the extrema position along the first given direction. If there
+ * is more than one extrema position, the other directions will be used
+ * to determine a unique position. Directions 2 and 3 can be NULL.
+ * Entities supported include bodies, volumes, surfaces, curves and
+ * vertices.
*/
-
+ //! \brief Gets extrema position on an entity.
CubitStatus entity_extrema( RefEntity *ref_entity_ptr,
const CubitVector *dir1,
const CubitVector *dir2,
const CubitVector *dir3,
CubitVector &extrema,
RefEntity *&extrema_entity_ptr );
+
+ /*! Gets the extrema position along the first given direction. If there
+ * is more than one extrema position, the other directions will be used
+ * to determine a unique position. Directions 2 and 3 can be NULL.
+ * Entities supported include bodies, volumes, surfaces, curves and
+ * vertices. The entity the extrema is found on is also returned.
+ */
+ //! \brief Gets extrema position on a list of entities.
CubitStatus entity_extrema( DLIList<RefEntity*> &ref_entity_list,
const CubitVector *dir1,
const CubitVector *dir2,
const CubitVector *dir3,
CubitVector &extrema,
RefEntity *&extrema_entity_ptr );
- /** Gets the extrema position along the first given direction. If there
- * is more than one extrema position, the other directions will be used
- * to determine a unique position. Directions 2 and 3 can be NULL.
- * Entities supported include bodies, volumes, surfaces, curves and
- * vertices. The entity the extrema is found on is also returned.
- */
+ /*! Gets the minimum distance between two entities and the closest positions
+ * on those entities. Supports vertices, curves, surfaces, volumes and bodies.
+ */
+ //! \brief Get the minimum distance between two entities.
CubitStatus entity_entity_distance( GeometryEntity *ge1,
- GeometryEntity *ge2,
- CubitVector &pos1, CubitVector &pos2,
- double &distance );
+ GeometryEntity *ge2,
+ CubitVector &pos1, CubitVector &pos2,
+ double &distance );
+
+ /*! Gets the minimum distance between two entities and the closest positions
+ on those entities. Supports vertices, curves, surfaces, volumes and bodies.
+ */
+ //! \brief Get the minimum distance between two entities. (CGM internal use)
CubitStatus entity_entity_distance( RefEntity *ref_entity_ptr1,
RefEntity *ref_entity_ptr2,
CubitVector &pos1, CubitVector &pos2,
double &distance );
- /** Gets the minimum distance between two entities and the closest positions
- * on those entities. Supports vertices, curves, surfaces, volumes and bodies.
- */
- CubitBox bounding_box_of_bodies();
- /**< returns the bounding box of all bodies in the model
- */
- ///< <HR><H3>Merging functions.</H3>
+ //! \brief Resets geometry factor back to 500.0
+ static void reset_geometry_factor();
+
+ //! \brief Sets geometry factor.
+ static void set_geometry_factor( double fac );
- static void set_geometry_factor( double fac );
+ //! \brief Gets geometry factor.
static double get_geometry_factor();
+
+ //! \brief Sets bboxMergeTest variable.
static void set_merge_test_bbox(CubitBoolean tof);
+
+ //! \brief Gets bboxMergeTest variable.
static CubitBoolean get_merge_test_bbox();
+
static void set_merge_test_internal(int tof);
static int get_merge_test_internal();
static void set_sliver_curve_cleanup_tolerance( double tol );
@@ -586,22 +738,17 @@
static double get_sliver_curve_cleanup_tolerance();
static double get_sliver_surface_cleanup_tolerance();
- //Initializes all settings of this class
+ //! \brief Initializes all settings of this class
static void initialize_settings();
+ //! \brief Causes attributes hanging on entities to be applied.
static CubitStatus import_actuate( DLIList<RefEntity*> &entity_list );
+ /*! \brief Returns CUBIT_TRUE if all the entities have the same geometric query engine and
+ if that is the same one as the default. */
CubitBoolean same_query_engine(DLIList<TopologyEntity*> &topo_list) const;
- /**< Returns CUBIT_TRUE if all the entities have the same geometric query engine and
- * if that is the same one as the default.
- */
- GeometryQueryEngine* common_query_engine(
- DLIList<TopologyEntity*>& topology_list,
- DLIList<TopologyBridge*>& engine_bridges,
- CubitBoolean allow_default_engine
- = CUBIT_FALSE ) const;
- /**< \return GeometryQueryEngine*
+ /*! \return GeometryQueryEngine*
* A GeometryQueryEngine common at least one
* TopologyBridge of each of the passed TopologyEntities, or
* NULL if no common geometry engine is found.
@@ -624,99 +771,174 @@
* if possible, otherwise with the first topology bridge attached
* to each of the passed TopologyEntities.
*/
+ //! \brief Gets geometry beloning to a common modeling engine.
+ GeometryQueryEngine* common_query_engine(
+ DLIList<TopologyEntity*>& topology_list,
+ DLIList<TopologyBridge*>& engine_bridges,
+ CubitBoolean allow_default_engine
+ = CUBIT_FALSE ) const;
+ //! \brief Determine if any of the input entities contain the given query engine
CubitBoolean does_geom_contain_query_engine(DLIList<TopologyEntity*> &topo_list,
GeometryQueryEngine *engine) const;
- /**< \return CubitBoolean
- * Determine if any of the input entities contain the given query engine
- */
+ //! \brief Determine if any of the input entities contain the given query engine
CubitBoolean does_geom_contain_query_engine(DLIList<RefEntity*> &ref_entity_list,
GeometryQueryEngine *engine,
CubitBoolean children_too = CUBIT_FALSE) const;
- /**< \return CubitBoolean
- * Determine if any of the input entities contain the given query engine
- */
+ //! \brief Retrieves the TopologyEntity from the underlying TopologyBridge
TopologyEntity* entity_from_bridge( TopologyBridge* bridge_ptr ) const;
+ //! \brief Adds a geometry query engine to the list
void add_gqe(GeometryQueryEngine *gqe_ptr);
- /**< add a geometry query engine to the list
- */
+ /*! \brief Removes a geometry query engine from the list. Returns CUBIT_FAILURE
+ if it wasn't in the list */
CubitStatus remove_gqe(GeometryQueryEngine *gqe_ptr);
- /**< remove a geometry query engine from the list; returns CUBIT_FAILURE
- * if it wasn't on the list
- */
+ //! \brief Return the list of GeometryQureyEngines.
void get_gqe_list(DLIList<GeometryQueryEngine*> &gqe_list);
- /**< return the list of gqe's
- */
+ //! \brief Returns the first gqe on the list.
GeometryQueryEngine *get_gqe();
- /**< return the first gqe on the list
- */
+ //! \brief Set the default GeometryQueryEngine.
CubitStatus set_default_gqe(GeometryQueryEngine* gqe);
- /**< set the default GeometryQueryEngine
- */
bool contains_intermediate_geometry(RefEntity*) const;
bool contains_intermediate_geometry(DLIList<RefEntity*>& ref_entitylist) const;
bool is_intermediate_geometry(RefEntity*) const;
bool is_intermediate_geometry(TopologyBridge*) const;
-// GeometryQueryEngine *get_gqe(const EntityType gqe_type);
- /**< return the gqe of the specified type
- */
-
+ /*!- Remove this entity and any dead children where
+ a dead child a) has no parent entities and b) has no topology_bridges. */
CubitStatus destroy_dead_entity( TopologyEntity* topo_ent, bool top = true ) const;
- //- Remove this entity and any dead children where
- //- a dead child a) has no parent entities and b)
- //- has no topology_bridges.
- //Translate
- CubitStatus translate( Body* entity, const CubitVector& delta,
- bool check_to_transform = true);
- CubitStatus translate( BasicTopologyEntity* entity, const CubitVector& delta,
- bool check_to_transform = true);
+ //! \brief Translate a Body some delta.
+ CubitStatus translate( Body* entity, const CubitVector& delta, bool check_to_transform = true,
+ bool preview = false );
- //Rotate
- CubitStatus rotate ( Body* entity, const CubitVector& axis, double degrees,
- bool check_to_transform = true);
- CubitStatus rotate ( Body* entity,
- const CubitVector& point,
- const CubitVector& direction,
- double degrees,
- bool check_to_transform = true);
- CubitStatus rotate ( BasicTopologyEntity* entity, const CubitVector& axis, double degrees,
- bool check_to_transform = true);
+ //! \brief Translate a BasicTopologyEntity some delta.
+ CubitStatus translate( BasicTopologyEntity* entity, const CubitVector& delta, bool check_to_transform = true,
+ bool preview = false );
- //Scale
- CubitStatus scale ( Body* entity, double factor, bool check_to_transform = true);
- CubitStatus scale ( Body* entity, const CubitVector& factors, bool check_to_transform = true);
- CubitStatus scale ( BasicTopologyEntity* entity, double factor, bool check_to_transform = true);
- CubitStatus scale ( BasicTopologyEntity* entity, const CubitVector& factors,
- bool check_to_transform = true);
+ void translate( DLIList<RefEntity*> &entities_to_transform,
+ double x, double y, double z, bool check_before_transforming,
+ DLIList<RefEntity*> &entities_transformed,
+ bool preview = false );
- //Reflect
- CubitStatus reflect ( DLIList<Body*> bodies, const CubitVector& axis );
- CubitStatus reflect ( BasicTopologyEntity* entity, const CubitVector& axis,
- bool check_to_transform = true);
+
+ //! \brief Rotate a Body an angle about an axis.
+ CubitStatus rotate( Body* entity, const CubitVector& axis, double degrees, bool check_to_transform = true,
+ bool preview = false );
+
+ //! \brief Rotate a Body an angle about an axis, defined by a point and a
+ //! direction.
+ CubitStatus rotate( Body* entity,
+ const CubitVector& point,
+ const CubitVector& direction,
+ double degrees,
+ bool check_to_transform = true,
+ bool preview = false);
+
+ CubitStatus rotate( DLIList<RefEntity*> &entities_to_transform,
+ const CubitVector& point,
+ const CubitVector& direction,
+ double degrees,
+ bool check_to_transform,
+ DLIList<RefEntity*> &entities_transformed,
+ bool preview = false);
+
+ //! \brief Rotate a BacisTopologyEntity an angle about an axis.
+ CubitStatus rotate( BasicTopologyEntity* entity,
+ const CubitVector& axis,
+ double degrees,
+ bool check_to_transform = true,
+ bool preview = false);
+
+ //! \brief Scale a Body.
+ CubitStatus scale( Body* entity, double factor, bool check_to_transform = true, bool preview = false);
+
+ //! \brief Scale a Body different factors in x, y, and z.
+ CubitStatus scale( Body* entity, const CubitVector& factors, bool check_to_transform = true, bool preview = false);
+
+ //! \brief Scale a BasicTopologyEntity.
+ CubitStatus scale( BasicTopologyEntity* entity, double factor, bool check_to_transform = true, bool preview = false);
+
+ //! \brief Scale a BasicTopologyEntity different factors in x, y, and z.
+ CubitStatus scale( BasicTopologyEntity* entity, const CubitVector& factors,bool check_to_transform = true,
+ bool preview = false);
+
+ void scale( DLIList<RefEntity*> &entities_to_transform,
+ double scale_x, double scale_y, double scale_z,
+ bool check_to_transform,
+ DLIList<RefEntity*> &entities_scaled,
+ bool preview = false);
+
+ //! \brief Reflect a list of bodies about a plane defined by an axis.
+ CubitStatus reflect( DLIList<Body*> bodies, const CubitVector& axis, bool preview = false );
+
+ //! \brief Reflect a BasicTopologyEntity about a plane defined by an axis.
+ CubitStatus reflect( BasicTopologyEntity* entity,
+ const CubitVector& axis,
+ bool check_to_transform = true,
+ bool preview = false);
+
+ void reflect( DLIList<RefEntity*> &entities_to_transform,
+ double x, double y, double z,
+ bool check_before_transforming,
+ DLIList<RefEntity*> &entities_transformed,
+ bool preview = false);
+
+ //! \brief Need to deprecate.
CubitStatus restore_transform( Body* body );
+ /*! Query to determine if volumes intersect, share common volume.
+ Returns CUBIT_TRUE if the two volumes overlap, CUBIT_FALSE if they don't
+ overlap. If the volumes are touching the function should return CUBIT_FALSE.
+ volume_1,
+ volume_2
+ The two volume pointers that are being tested for overlap.
+ The function uses the intersect call to test if the volumes
+ are overlaping. The full intersect Boolean is needed to see if
+ the volumes actually overlap and don't just touch. */
+ //! \brief Query to determine if volumes intersect, share common volume.
+ CubitBoolean volumes_overlap( RefVolume *volume_1, RefVolume *volume_2);
+
+ /*! Query to determine if bodies intersect, share common volume.
+ Returns CUBIT_TRUE if the two bodies overlap, CUBIT_FALSE if they don't
+ overlap. If the bodies are touching the function should return CUBIT_FALSE.
+ body_ptr_1, body_ptr_2
+ The two body pointers that are being tested for overlap.
+ The function uses the intersect call to test if the bodies
+ are overlaping. The full intersect Boolean is needed to see if
+ the bodies actually overlap and don't just touch. */
+ //! \brief Query to determine if bodies intersect, share common volume.
CubitBoolean bodies_overlap( Body *body_ptr_1, Body *body_ptr_2 );
- //R CubitBoolean
- //R- CUBIT_TRUE if the two bodies overlap, CUBIT_FALSE if they don't
- //R- overlap. If the bodies are touching the function
- //R- should return CUBIT_FALSE.
- //I body_ptr_1, body_ptr_2
- //I- The two body pointers that are being tested for overlap.
- //- The function uses the intersect call to test if the bodies
- //- are overlaping. The full intersect Boolean is needed to see if
- //- the bodies actually overlap and don't just touch.
+ //! Given a list of TB's, construct ref entities for them; if the 2nd list pointer is
+ //! non-NULL, pass back the list of ref entities in that list
+ CubitStatus construct_refentities(DLIList<TopologyBridge*> &topology_bridges,
+ DLIList<RefEntity*> *imported_entities = NULL);
+ /*! When importing a cub file, embedded in the cub file is how many
+ geometry entities it is supposed to restore. If geometry that
+ you are improrting is merged with geometry already in the session,
+ you need to keep track of how many geometry entieies get 'merged-away'
+ like this so that import does not fail. Taking into account
+ the 'merged-away' geometry allows CUBIT to successfully import
+ when you have geometry that will merge-away. */
+ /*! \brief Variable needed when importing geometry that will be
+ merged-away with already existing geometry in the session */
+ static CubitBoolean trackMergedAwayEnts;
+
+
+ static DLIList<int> uidsOfImportingEnts;
+ static int entitiesMergedAway;
+
+ CGMHistory& history();
+
protected :
GeometryQueryTool(GeometryQueryEngine* GQEPtr);
@@ -750,6 +972,11 @@
// check for mergeable sense entity, which is a child of the entity pointed
// to by a merge attribute on bridge, which corresponds to re_ptr
+
+ void get_merged_away_free_entities( DLIList<RefEntity*> &ref_ents,
+ DLIList<TopologyBridge*> &free_ents );
+
+
CubitStatus straightline_intersections( RefEdge* ref_edge1,
CubitVector & origin2,
CubitVector & dir2,
@@ -757,18 +984,15 @@
CubitBoolean bounded = CUBIT_FALSE,
CubitBoolean closest = CUBIT_FALSE);
+ //! static pointer to the unique instance of this class.
static GeometryQueryTool* instance_;
- /**< static pointer to the unique instance of this class.
- */
+ //! For use in calculating a bounding box, you can do it based on
+ //! a set of facets, rather than what default modeling engine uses.
static CubitBoolean useFacetBBox;
- /**< For use in calculating a bounding box, you can do it based on
- * a set of facets, rather than what default modeling engine uses.
- */
+ //! The list of geometry query engines
DLIList<GeometryQueryEngine*> gqeList;
- /**< The list of geometry query engines
- */
struct IGEComp : public std::binary_function<IntermediateGeomEngine*,
IntermediateGeomEngine*,
@@ -780,29 +1004,29 @@
typedef std::set<IntermediateGeomEngine*,IGEComp> IGESet;
IGESet igeSet;
+ //! \brief The default geometry query engine
GeometryQueryEngine *default_gqe;
- /**< The default geometry query engine
- */
+ //! After imprinting, an attempt at removing sliver curves is made.
+ //! Curves less than this tolerance will be removed.
static double curveSliverCleanUpTolerance;
- // After imprinting, an attempt at removing sliver curves is made.
- // Curves less than this tolerance will be removed.
+ //! After imprinting, an attempt at removing sliver surfaces is made.
+ //! Removes sliver surfaces whose maximum gap distance among the long
+ //! edges is smaller than the tolerance and who have at most three long edges.
static double surfaceSliverCleanUpTolerance;
- // After imprinting, an attempt at removing sliver surfaces is made.
- // Removes sliver surfaces whose maximum gap distance among the long
- // edges is smaller than the tolerance and who have at most three long edges.
+ //! This factor is the the multiplier for the ACIS resabs
+ //! when comparingcurves. ALWAYS when using a multiplier
+ //! use this factor for consistancy.
static double geometryToleranceFactor;
- /**< This factor is the the multiplier for the ACIS resabs
- * when comparingcurves. ALWAYS when using a multiplier
- * use this factor for consistancy.
- */
static CubitBoolean bboxMergeTest;
- static int internalSurfaceMergeTest; //0=off, 1=all, 2=splines only
- ///< Options for refface merging.
+ //! Options for refface merging.
+ //! 0=off, 1=all, 2=splines only
+ static int internalSurfaceMergeTest;
+
int maxPersistentBodyId;
int maxPersistentRefVolumeId;
int maxPersistentRefGroupId;
@@ -812,8 +1036,14 @@
static const int CGM_MAJOR_VERSION;
static const int CGM_MINOR_VERSION;
+
+ CGMHistory mHistory;
};
+inline void GeometryQueryTool::reset_geometry_factor()
+{
+ geometryToleranceFactor = DEFAULT_GEOM_FACTOR;
+}
inline void GeometryQueryTool::set_geometry_factor( double factor )
{
Added: cgm/branches/cubit/geom/GfxPreview.cpp
===================================================================
--- cgm/branches/cubit/geom/GfxPreview.cpp (rev 0)
+++ cgm/branches/cubit/geom/GfxPreview.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,293 @@
+
+
+#include "GfxPreview.hpp"
+#include "GMem.hpp"
+#include "CubitVector.hpp"
+#include "Curve.hpp"
+#include "Surface.hpp"
+#include "GeometryQueryEngine.hpp"
+#include "Point.hpp"
+#include <assert.h>
+
+GfxPreview* GfxPreview::mInstance = 0;
+
+GfxPreview::GfxPreview()
+{
+ if(mInstance)
+ {
+ assert(0);
+ // if you want a new instance in place of a previous one,
+ // delete the previous one first
+ }
+ mInstance = this;
+}
+
+GfxPreview::~GfxPreview()
+{
+ mInstance = 0;
+}
+
+
+// This clears preview data ONLY
+void GfxPreview::clear()
+{
+ if(!mInstance) return;
+ mInstance->p_clear();
+}
+
+// causes the current window to be redrawn
+void GfxPreview::flush()
+{
+ if(!mInstance) return;
+ mInstance->p_flush();
+}
+
+// Geometry Drawing Functions
+
+void GfxPreview::draw_ref_entity(RefEntity* entity, int color, CubitTransformMatrix* mat)
+{
+ if(!mInstance) return;
+ mInstance->p_draw_ref_entity(entity, color, mat);
+}
+
+void GfxPreview::draw_ref_vertex(RefVertex* entity, int color)
+{
+ if(!mInstance) return;
+ mInstance->p_draw_ref_vertex(entity, color);
+}
+
+void GfxPreview::draw_ref_edge(RefEdge* entity, int color)
+{
+ if(!mInstance) return;
+ mInstance->p_draw_ref_edge(entity, color);
+}
+
+void GfxPreview::draw_ref_face(RefFace* entity, int color)
+{
+ if(!mInstance) return;
+ mInstance->p_draw_ref_face(entity, color);
+}
+
+void GfxPreview::draw_ref_face_edges(RefFace* entity, int color)
+{
+ if(!mInstance) return;
+ mInstance->p_draw_ref_face_edges(entity, color);
+}
+
+void GfxPreview::draw_ref_volume(RefVolume* entity, int color)
+{
+ if(!mInstance) return;
+ mInstance->p_draw_ref_volume(entity, color);
+}
+
+void GfxPreview::draw_ref_volume_edges(RefVolume* entity, int color)
+{
+ if(!mInstance) return;
+ mInstance->p_draw_ref_volume_edges(entity, color);
+}
+
+void GfxPreview::draw_ref_body(Body* entity, int color)
+{
+ if(!mInstance) return;
+ mInstance->p_draw_ref_body(entity, color);
+}
+
+// Generic Primitive Drawing Functions
+
+void GfxPreview::draw_box(CubitBox& box, int color)
+{
+ if(!mInstance) return;
+ mInstance->p_draw_box(box, color);
+}
+
+// draw point x,y,z of color
+void GfxPreview::draw_point(float x, float y, float z, int color)
+{
+ if(!mInstance) return;
+ mInstance->p_draw_point(x, y, z, color);
+}
+
+void GfxPreview::draw_point(const CubitVector& vector, int color)
+{
+ if(!mInstance) return;
+ mInstance->p_draw_point(vector, color);
+}
+
+void GfxPreview::draw_point(CubitVector* vector, int color)
+{
+ if(!mInstance) return;
+ mInstance->p_draw_point(*vector, color);
+}
+
+// draw line of points {x,y,z}, {x,y,z} of color
+void GfxPreview::draw_line(float x1, float y1, float z1, float x2, float y2, float z2, int color)
+{
+ if(!mInstance) return;
+ mInstance->p_draw_line(x1, y1, z1, x2, y2, z2, color);
+}
+
+void GfxPreview::draw_line(const CubitVector& x, const CubitVector& y, int color)
+{
+ if(!mInstance) return;
+ mInstance->p_draw_line(x, y, color);
+}
+
+// draw a polyline with a number of points of a color
+void GfxPreview::draw_polyline(const GPoint* points, int num_points, int color)
+{
+ if(!mInstance) return;
+ mInstance->p_draw_polyline(points, num_points, color);
+}
+
+// draw polygons given the coordinates and the connectivity. Note that the
+// connectivity (face_list) is given as the number of points in the polygon
+// followed by the point ids for that polygon. So, the num_face_points is
+// the total number of data points in the face_list such that
+// num_face_points = number of points + number of polygons
+void GfxPreview::draw_polygons(int num_points, const float* xyzs, int num_face_points,
+ const int* face_list, int color )
+{
+ if (!mInstance)
+ return;
+ mInstance->p_draw_polygons( num_points, xyzs, num_face_points, face_list, color);
+}
+
+// draw a polyline with a number of points of a color
+void GfxPreview::draw_polygon(const GPoint* points, int num_points, int color, int border_color, bool filled)
+{
+ if(!mInstance) return;
+ mInstance->p_draw_polygon(points, num_points, color, border_color, filled);
+}
+
+// draw a quad of a color
+void GfxPreview::draw_quad(const GPoint* points, int color)
+{
+ if(!mInstance) return;
+ mInstance->p_draw_quad(points, color);
+}
+
+// draw a tri of a color
+void GfxPreview::draw_tri(const GPoint* points, int color)
+{
+ if(!mInstance) return;
+ mInstance->p_draw_tri(points, color);
+}
+
+void GfxPreview::draw_vector(const CubitVector& tail, const CubitVector& head, int color)
+{
+ if(!mInstance) return;
+ mInstance->p_draw_vector(tail, head, color);
+}
+
+void GfxPreview::draw_vector(const GPoint* tail, const GPoint* head, int color)
+{
+ if(!mInstance) return;
+ mInstance->p_draw_vector(CubitVector(tail->x, tail->y, tail->z), CubitVector(head->x, head->y, head->z), color);
+}
+
+// draw a label at position x,y,z of color
+void GfxPreview::draw_label(const char* label, float x, float y, float z, int color)
+{
+ if(!mInstance) return;
+ mInstance->p_draw_label(label, x, y, z, color);
+}
+void GfxPreview::draw_label(int label, float x, float y, float z, int color)
+{
+ if(!mInstance) return;
+ mInstance->p_draw_label(label, x, y, z, color);
+}
+
+void GfxPreview:: draw_cylinder(const CubitVector& axis, const CubitVector& origin,
+ CubitBox& bounding_box, float radius, int color)
+{
+ if(!mInstance) return;
+ mInstance->p_draw_cylinder(axis, origin, bounding_box, radius, color);
+}
+
+void GfxPreview::draw_point(Point *pt, int color)
+{
+ CubitVector v = pt->coordinates();
+ draw_point(v, color);
+ flush();
+}
+
+void GfxPreview::draw_curve(Curve *curve, int color)
+{
+ int num_divs = 20;
+ double lo, hi;
+ curve->get_param_range(lo, hi);
+ double dv = (hi-lo)/(double)num_divs;
+ int i;
+ double param = lo;
+ for(i=0; i<num_divs; i++)
+ {
+ CubitVector p1, p2;
+ curve->position_from_u(param, p1);
+ param += dv;
+ curve->position_from_u(param, p2);
+ draw_line(p1.x(), p1.y(), p1.z(), p2.x(), p2.y(), p2.z(), color);
+ }
+ flush();
+ DLIList<Point*> pts;
+ curve->points(pts);
+ for(i=pts.size(); i>0; i--)
+ {
+ Point *cur_pt = pts.get_and_step();
+ draw_point(cur_pt, color);
+ }
+}
+
+void GfxPreview::draw_surface(Surface *surf, int color)
+{
+ int num_divs = 20;
+ double ulo, uhi, vlo, vhi;
+ surf->get_param_range_U(ulo, uhi);
+ surf->get_param_range_V(vlo, vhi);
+ double du = (uhi-ulo)/(double)num_divs;
+ double dv = (vhi-vlo)/(double)num_divs;
+ int i, j;
+ double uparam, vparam;
+ uparam = ulo;
+ for(i=0; i<num_divs; i++)
+ {
+ vparam = vlo;
+ for(j=0; j<num_divs; j++)
+ {
+ CubitVector p1, p2;
+ p1 = surf->position_from_u_v(uparam, vparam);
+ vparam += dv;
+ p2 = surf->position_from_u_v(uparam, vparam);
+ draw_line(p1.x(), p1.y(), p1.z(), p2.x(), p2.y(), p2.z(), color);
+ }
+ uparam += du;
+ }
+ vparam = vlo;
+ for(i=0; i<num_divs; i++)
+ {
+ uparam = ulo;
+ for(j=0; j<num_divs; j++)
+ {
+ CubitVector p1, p2;
+ p1 = surf->position_from_u_v(uparam, vparam);
+ uparam += du;
+ p2 = surf->position_from_u_v(uparam, vparam);
+ draw_line(p1.x(), p1.y(), p1.z(), p2.x(), p2.y(), p2.z(), color);
+ }
+ vparam += dv;
+ }
+ flush();
+}
+
+void GfxPreview::draw_surface_facets_shaded(Surface *surf, int color)
+{
+ GMem g_mem;
+
+ surf->get_geometry_query_engine()->get_graphics(surf, &g_mem);
+
+ 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);
+ flush();
+}
+
Added: cgm/branches/cubit/geom/GfxPreview.hpp
===================================================================
--- cgm/branches/cubit/geom/GfxPreview.hpp (rev 0)
+++ cgm/branches/cubit/geom/GfxPreview.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,166 @@
+
+
+#ifndef GFX_PREVIEW_INTERFACE_HPP
+#define GFX_PREVIEW_INTERFACE_HPP
+
+// An interface for any tools, algorithms, etc... to draw preview objects.
+// NOTE: this is an "interface" in the sense that using it will not
+// create additional depedencies in your code. If a subclass of GfxPreview
+// is not instantiated, then this class acts as a stub with empty implementation.
+// CGM users may implement preview code by deriving from this class and implementing
+// graphics code in the pure virtual p_* methods. Creating an instance of the
+// derived class will result in the correct methods being called by this interface.
+
+// PLEASE!!! use this interface to implement any graphical preview code in CGM.
+// This will identify graphics code that must be maintained for end users.
+
+//
+// any graphics primitives drawn with this interface are temporary primitives and
+// not permanent ones. All items are draw into a single drawing set owned by the
+//
+
+
+// We only have forward declarations and NO #includes !!! (except those already in the util folder)
+template <class X> class DLIList;
+class RefEntity;
+struct GPoint;
+class CubitVector;
+class RefEntity;
+class RefVertex;
+class RefEdge;
+class RefFace;
+class RefVolume;
+class Body;
+class CubitTransformMatrix;
+class CubitBox;
+class Curve;
+class Surface;
+class Point;
+
+#include "CubitColorConstants.hpp"
+#include "CubitGeomConfigure.h"
+
+class CUBIT_GEOM_EXPORT GfxPreview
+{
+ // the one instance of the Graphics Preview object
+ // creating a second instance will delete and replace the first instance.
+ static GfxPreview* mInstance;
+
+ public:
+ GfxPreview();
+ virtual ~GfxPreview();
+
+ // this will clear out all temporary data and delete any graphics windows created
+ // with this interface. It'll restore the persistent geom/mesh model.
+ //static void reset();
+
+ // this will clear out any objects drawn using preview graphics.
+ // no other graphics will be affected so you can now do something like
+ // draw vol 4
+ // webcut vol all plane x preview
+ // and then clear the preview and you will still only have vol 4 displaye.
+ static void clear();
+
+ // causes the window(s) to be redrawn
+ static void flush();
+
+ // Geometry Drawing Functions
+ static void draw_ref_entity(RefEntity* entity, int color = CUBIT_DEFAULT_COLOR,
+ CubitTransformMatrix* trans_mat = 0);
+ static void draw_ref_vertex(RefVertex* entity, int color = CUBIT_DEFAULT_COLOR);
+ static void draw_ref_edge(RefEdge* entity, int color = CUBIT_DEFAULT_COLOR);
+ static void draw_ref_face(RefFace* entity, int color = CUBIT_DEFAULT_COLOR);
+ static void draw_ref_face_edges(RefFace* entity, int color = CUBIT_DEFAULT_COLOR);
+ static void draw_ref_volume(RefVolume* entity, int color = CUBIT_DEFAULT_COLOR);
+ static void draw_ref_volume_edges(RefVolume* entity, int color = CUBIT_DEFAULT_COLOR);
+ static void draw_ref_body(Body* entity, int color = CUBIT_DEFAULT_COLOR);
+
+ static void draw_point(Point *pt, int color);
+ static void draw_curve(Curve *curve, int color);
+ static void draw_surface(Surface *surf, int color);
+ static void draw_surface_facets_shaded(Surface *surf, int color);
+
+ // Generic Primitive Drawing Functions
+
+ static void draw_box(CubitBox& box, int color);
+
+ // draw point x,y,z of color
+ static void draw_point(float x, float y, float z, int color);
+ static void draw_point(const CubitVector& vector, int color);
+ static void draw_point(CubitVector* vector, int color);
+
+ // draw line of points {x,y,z}, {x,y,z} of color
+ static void draw_line(float x1, float y1, float z1,
+ float x2, float y2, float z2, int color);
+
+ static void draw_line(const CubitVector& x, const CubitVector& y, int color);
+
+ // draw a polyline with a number of points of a color
+ static void draw_polyline(const GPoint* points, int num_points, int color);
+
+ // draw a polygon with a number of points of a color and filled or not
+ static void draw_polygon(const GPoint* points, int num_points, int color, int border_color, bool filled = true);
+ // draw a list of polygons (much more efficent than drawing a single polygon multiple times.)
+ // pass in the coordinates and the connectivity
+ // the face_list is comprised of a list num_points_in_face, face_pt1, face_pt2, face_pt3, ...
+ static void draw_polygons(int num_points, const float* xyzs, int num_face_points,
+ const int* face_list, int color);
+
+ //! \brief draw a cylinder for previewing
+ //! \param axis - orientation of the length of the cylinder
+ //! \param origin - the center of the cylinder in x, y, and z
+ //! \param bounding_box - the bounding box of the cylinder
+ //! \param radius - radius of the cylinder
+ //! \param color - color of the cylinder
+ static void draw_cylinder(const CubitVector& axis, const CubitVector& origin,
+ CubitBox& bounding_box, float radius, int color);
+ // draw a quad of a color
+ static void draw_quad(const GPoint* points, int color);
+
+ // draw a tri of a color
+ static void draw_tri(const GPoint* points, int color);
+
+ // draw a vector (tail -> head) of color
+ static void draw_vector(const GPoint* tail, const GPoint* head, int color);
+ static void draw_vector(const CubitVector& tail, const CubitVector& head, int color);
+
+ // draw a label at position x,y,z of color
+ static void draw_label(const char* label, float x, float y, float z, int color);
+ static void draw_label(int label, float x, float y, float z, int color);
+
+ protected:
+
+ // p is for protected in case you were wondering :)
+
+ virtual void p_clear() = 0;
+ virtual void p_flush() = 0;
+
+ virtual void p_draw_ref_entity(RefEntity* entity, int color, CubitTransformMatrix* mat) = 0;
+ virtual void p_draw_ref_vertex(RefVertex* entity, int color) = 0;
+ virtual void p_draw_ref_edge(RefEdge* entity, int color) = 0;
+ virtual void p_draw_ref_face(RefFace* entity, int color) = 0;
+ virtual void p_draw_ref_face_edges(RefFace* entity, int color) = 0;
+ virtual void p_draw_ref_volume(RefVolume* entity, int color) = 0;
+ virtual void p_draw_ref_volume_edges(RefVolume* entity, int color) = 0;
+ virtual void p_draw_ref_body(Body* entity, int color) = 0;
+ virtual void p_draw_box(CubitBox& box, int color) = 0;
+ virtual void p_draw_point(float, float, float, int) = 0;
+ virtual void p_draw_point(const CubitVector& vector, int color) = 0;
+ virtual void p_draw_line(float, float, float, float, float, float, int) = 0;
+ virtual void p_draw_line(const CubitVector& x, const CubitVector& y, int color) = 0;
+ virtual void p_draw_polyline(const GPoint*, int, int) = 0;
+ virtual void p_draw_polygon(const GPoint* points, int num_points, int color, int border_color, bool filled) = 0;
+ virtual void p_draw_polygons(int num_points, const float* xyzs, int num_face_points,
+ const int* face_list, int color) = 0;
+ virtual void p_draw_cylinder(const CubitVector& axis, const CubitVector& origin,
+ CubitBox& bounding_box, float radius, int color) = 0;
+ virtual void p_draw_quad(const GPoint*, int) = 0;
+ virtual void p_draw_tri(const GPoint*, int) = 0;
+ virtual void p_draw_vector(const CubitVector&, const CubitVector&, int) = 0;
+ virtual void p_draw_label(const char*, float, float, float, int) = 0;
+ virtual void p_draw_label(int, float, float, float, int) = 0;
+};
+
+#endif
+
+
Modified: cgm/branches/cubit/geom/GroupingEntity.cpp
===================================================================
--- cgm/branches/cubit/geom/GroupingEntity.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/GroupingEntity.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -196,7 +196,7 @@
sense_entity->get_grouping_entity_ptr() != this )
return CUBIT_FAILURE;
}
-
+
// Special case for first entity in list.
list.reset();
SenseEntity* new_first = list.get_and_step();
Modified: cgm/branches/cubit/geom/IntermediateGeomEngine.hpp
===================================================================
--- cgm/branches/cubit/geom/IntermediateGeomEngine.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/IntermediateGeomEngine.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -5,6 +5,9 @@
class TopologyBridge;
class CubitTransformMatrix;
class Body;
+class Surface;
+class Curve;
+class Point;
class BodySM;
class TBOwner;
@@ -13,6 +16,7 @@
public:
virtual bool is_composite(TBOwner *bridge_owner) = 0;
+ virtual bool is_composite(TopologyBridge *bridge ) = 0;
virtual bool is_partition(TBOwner *bridge_owner) = 0;
virtual int level() const = 0;
@@ -22,6 +26,8 @@
DLIList<BodySM*> &new_sms )=0;
virtual void push_imprint_attributes_before_modify
( DLIList<BodySM*> &body_sms ) = 0;
+ virtual void push_named_attributes_to_curves_and_points
+ ( DLIList<TopologyBridge*> &tb_list, const char *name_in ) = 0;
virtual CubitStatus export_geometry( DLIList<TopologyBridge*>& geometry_list ) = 0;
virtual CubitStatus import_geometry( DLIList<TopologyBridge*>& geometry_list ) = 0;
@@ -31,13 +37,18 @@
virtual void remove_attributes( DLIList<TopologyBridge*> &bridge_list ) = 0;
virtual void attribute_after_imprinting( DLIList<TopologyBridge*> &new_tbs,
DLIList<TopologyBridge*> &att_tbs,
- DLIList<BodySM*> &new_sms,
+ DLIList<TopologyBridge*> &tb_list,
DLIList<Body*> &old_bodies)=0;
virtual void remove_attributes_from_unmodifed_virtual(DLIList<TopologyBridge*> &bridges) = 0;
- virtual void remove_modified(DLIList<TopologyBridge*>& geometry_list) = 0;
+ virtual void remove_modified(DLIList<Surface*> &all_surfs,
+ DLIList<Curve*> &all_curves, DLIList<Point*> &all_pts) = 0;
virtual CubitStatus notify_transform( TopologyBridge* entity,
const CubitTransformMatrix& xform ) = 0;
+
+ virtual void get_tbs_with_bridge_manager_as_owner( TopologyBridge *source_bridge,
+ DLIList<TopologyBridge*> &tbs ) = 0;
+
};
#endif
Modified: cgm/branches/cubit/geom/Loop.cpp
===================================================================
--- cgm/branches/cubit/geom/Loop.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Loop.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -89,6 +89,17 @@
set_topology_bridge(OSMEPtr) ;
}
+LoopType Loop::loop_type() const
+{
+ LoopSM* loop_sm = get_loop_sm_ptr();
+ if (loop_sm)
+ {
+ return loop_sm->loop_type();
+ }
+ assert(0);
+ return LOOP_TYPE_UNKNOWN;
+}
+
//-------------------------------------------------------------------------
// Purpose : Gets the angle metric for this Loop.
//
Modified: cgm/branches/cubit/geom/Loop.hpp
===================================================================
--- cgm/branches/cubit/geom/Loop.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Loop.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -20,6 +20,7 @@
// ********** BEGIN CUBIT INCLUDES **********
#include "CubitDefines.h"
+#include "GeometryDefines.h"
#include "CubitBox.hpp"
#include "GroupingEntity.hpp"
// ********** END CUBIT INCLUDES **********
@@ -45,11 +46,9 @@
DagType dag_type() const { return DagType::loop_type(); }
- CubitBoolean is_external() ;
- //R CubitBoolean
- //R- CUBIT_TRUE/CUBIT_FALSE
- //- Returns CUBIT_TRUE if the Loop is an external Loop and CUBIT_FALSE
- //- otherwise.
+ LoopType loop_type() const;
+ //R LoopType
+ //- Gets the type of this loop. See LoopType enum for more details.
CubitStatus get_angle_metric(double& angle_metric);
//R CubitStatus
Modified: cgm/branches/cubit/geom/LoopSM.hpp
===================================================================
--- cgm/branches/cubit/geom/LoopSM.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/LoopSM.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -37,6 +37,7 @@
// ********** BEGIN CUBIT INCLUDES **********
#include "CubitDefines.h"
+#include "GeometryDefines.h"
#include "TopologyBridge.hpp"
@@ -54,6 +55,8 @@
virtual ~LoopSM() ;
//- The destructor
+
+ virtual LoopType loop_type() = 0;
virtual const type_info& topology_entity_type_info() const;
Modified: cgm/branches/cubit/geom/Lump.hpp
===================================================================
--- cgm/branches/cubit/geom/Lump.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Lump.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -47,6 +47,10 @@
//R- The enumerated type of the geometric representation
virtual CubitStatus mass_properties( CubitVector ¢roid, double &volume ) = 0;
+ virtual CubitStatus mass_properties( CubitVector principal_axes[3],
+ CubitVector &principal_moments,
+ CubitVector ¢roid,
+ double &volume ) {return CUBIT_FAILURE;}
protected:
Modified: cgm/branches/cubit/geom/Makefile.am
===================================================================
--- cgm/branches/cubit/geom/Makefile.am 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Makefile.am 2010-01-06 19:22:14 UTC (rev 3423)
@@ -11,6 +11,7 @@
if build_parallel
SUBDIRS += parallel
endif
+SUBDIRS += testing
# Override default defines with the ones we want from the configure script
DEFS = $(TEMPLATE_DEFS_INCLUDED) $(LITTLE_ENDIAN)
@@ -26,6 +27,7 @@
libcubit_geom_la_SOURCES = \
AllocMemManagersGeom.cpp \
AnalyticGeometryTool.cpp \
+ AutoMidsurfaceTool.cpp \
BasicTopologyEntity.cpp \
Body.cpp \
BodySM.cpp \
@@ -43,6 +45,7 @@
CAUniqueId.cpp \
CGMApp.cpp \
CGMEngineDynamicLoader.cpp \
+ CGMHistory.cpp \
Chain.cpp \
CoEdge.cpp \
CoEdgeSM.cpp \
@@ -73,6 +76,7 @@
GeometryQueryTool.cpp \
GeometryUtil.cpp \
GeomMeasureTool.cpp \
+ GfxPreview.cpp \
GroupingEntity.cpp \
GSaveOpen.cpp \
Loop.cpp \
@@ -88,6 +92,7 @@
ModelQueryEngine.cpp \
OffsetSplitTool.cpp \
OldUnmergeCode.cpp \
+ PeriodicParamTool.cpp \
Point.cpp \
PointSM.cpp \
RefCollection.cpp \
@@ -121,6 +126,7 @@
# not be installed, move it to the _SOURCES list above.
libcubit_geom_la_include_HEADERS = \
AnalyticGeometryTool.hpp \
+ AutoMidsurfaceTool.hpp \
BasicTopologyEntity.hpp \
Body.hpp \
BodySM.hpp \
@@ -139,6 +145,7 @@
CAUniqueId.hpp \
CGMApp.hpp \
CGMEngineDynamicLoader.hpp \
+ CGMHistory.hpp \
Chain.hpp \
CoEdge.hpp \
CoEdgeSM.hpp \
@@ -176,6 +183,7 @@
GeometryQueryEngine.hpp \
GeometryQueryTool.hpp \
GeometryUtil.hpp \
+ GfxPreview.hpp \
GroupingEntity.hpp \
IntermediateGeomEngine.hpp \
Loop.hpp \
@@ -191,6 +199,7 @@
ModelQueryEngine.hpp \
OffsetSplitTool.hpp \
OldUnmergeCode.hpp \
+ PeriodicParamTool.hpp \
Point.hpp \
PointSM.hpp \
RefCollection.hpp \
Modified: cgm/branches/cubit/geom/MergeTool.cpp
===================================================================
--- cgm/branches/cubit/geom/MergeTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/MergeTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -13,6 +13,10 @@
#include "GeometryQueryTool.hpp"
#include "GeometryQueryEngine.hpp"
#include "ModelQueryEngine.hpp"
+#include "GeometryModifyTool.hpp"
+#include "SurfaceOverlapTool.hpp"
+#include "GeometryModifyEngine.hpp"
+#include "CGMHistory.hpp"
#include "CubitObserver.hpp"
#include "MergeEvent.hpp"
@@ -103,8 +107,82 @@
instance_ = 0;
}
+void MergeTool::merge_with_auto_imprint(RefFace *surf1, RefFace *surf2)
+{
+ DLIList<CubitString*> ds, cs, ps;
+ RefFace *local_surf1 = surf1;
+ RefFace *local_surf2 = surf2;
+ bool time_to_stop = false;
+ int cntr = 0;
+ bool first_time = true;
+ while(!time_to_stop && local_surf1 &&
+ local_surf2 && !local_surf1->is_merged() &&
+ !local_surf2->is_merged() )
+ {
+ int surf1_id = local_surf1->id();
+ int surf2_id = local_surf2->id();
+ if(first_time)
+ {
+ Body *b1 = local_surf1->body();
+ Body *b2 = local_surf2->body();
+ if(b1 && b2)
+ {
+ DLIList<Body*> body_list, new_bodies;
+ body_list.append(b1);
+ body_list.append(b2);
+ GeometryModifyTool::instance()->tolerant_imprint( body_list, new_bodies, true );
+ first_time = false;
+ }
+ }
+ else
+ {
+ this->imprint_merge_solutions_for_overlapping_surfaces(local_surf1,
+ local_surf2, true, ds, cs, ps);
+ }
+ RefFace *new_surf1 = RefEntityFactory::instance()->get_ref_face(surf1_id);
+ RefFace *new_surf2 = RefEntityFactory::instance()->get_ref_face(surf2_id);
+ if(new_surf1 && new_surf1->is_merged())
+ time_to_stop = true;
+ else if(new_surf2 && new_surf2->is_merged())
+ time_to_stop = true;
+ else
+ {
+ if(new_surf1 && new_surf2)
+ {
+ DLIList<RefFace*> current_face_list, out1, out2;
+ DLIList<RefEntity*> faces_to_draw;
+ current_face_list.append(new_surf1);
+ current_face_list.append(new_surf2);
+ SurfaceOverlapTool::instance()->find_overlapping_surfaces(current_face_list,
+ out1,
+ out2,
+ faces_to_draw,
+ CUBIT_FALSE,
+ CUBIT_TRUE);
+ if(out1.size() == 1 && out2.size() == 1 &&
+ (out1.get() == new_surf1 && out2.get() == new_surf2) ||
+ (out1.get() == new_surf2 && out2.get() == new_surf1))
+ {
+ local_surf1 = new_surf1;
+ local_surf2 = new_surf2;
+ }
+ else
+ time_to_stop = true;
+ }
+ else
+ {
+ time_to_stop = true;
+ }
+ }
+ cntr++;
+ if(cntr > 5)
+ time_to_stop = true;
+ }
+}
+
//Public Functions:
-CubitBoolean MergeTool::contains_merged_entities( DLIList<RefEntity*> &ref_entities)
+CubitBoolean MergeTool::contains_merged_entities( DLIList<RefEntity*> &ref_entities,
+ DLIList<RefEntity*> *merged_ref_ents )
{
//Loop through the entities and their children to find
//merged entities. For now, just do it quickly, so
@@ -121,9 +199,18 @@
for (int i = all_entities.size(); i > 0; i--) {
RefEntity *temp_entity = all_entities.get_and_step();
if (entity_merged(CAST_TO(temp_entity, TopologyEntity)))
- return CUBIT_TRUE;
+ {
+ if( NULL == merged_ref_ents )
+ return CUBIT_TRUE;
+ else
+ merged_ref_ents->append( temp_entity );
+ }
}
+ if( merged_ref_ents )
+ if( merged_ref_ents->size() )
+ return CUBIT_TRUE;
+
return CUBIT_FALSE;
}
@@ -132,9 +219,8 @@
{
RefEntity *ref_ent = NULL;
- ref_ent = CAST_TO(body, RefEntity);
DLIList<RefEntity*> ref_ent_list;
- ref_ent->get_all_child_ref_entities( ref_ent_list );
+ body->get_all_child_ref_entities( ref_ent_list );
int i;
for( i=ref_ent_list.size(); i--;)
{
@@ -170,6 +256,18 @@
CubitStatus MergeTool::merge_all_bodies()
{
+ int number_volumes = GeometryQueryTool::instance()->num_ref_volumes();
+
+ DLIList<RefEntity*> free_ref_ents;
+ int number_free_entities =
+ GeometryQueryTool::instance()->get_free_ref_entities( free_ref_ents );
+
+ if( number_volumes == 1 && free_ref_ents.size() == 0 )
+ {
+ PRINT_WARNING("Need more than 1 volume to merge anything\n");
+ return CUBIT_FAILURE;
+ }
+
PRINT_INFO( "\n...Merging all features in the model\n" );
set_merge_occurance( CUBIT_TRUE );
@@ -410,6 +508,16 @@
GeometryQueryTool::instance()->get_merge_test_internal() );
if( status == CUBIT_FALSE )
continue;
+
+ //don't merge 2 surfaces of solid volumes if they have
+ //opposite sense..indicative that they overlap
+ if( refface_ptr->compare_alignment(compare_refface_ptr) == CUBIT_FORWARD )
+ {
+ //if they are both on solid volumes...bail
+ if( refface_ptr->body()->is_sheet_body() == CUBIT_FALSE &&
+ compare_refface_ptr->body()->is_sheet_body() == CUBIT_FALSE )
+ continue;
+ }
// If we are in this block, we want to merge the
// two entities. If they do not merge, there was
@@ -446,6 +554,14 @@
if (print_info) PRINT_INFO( "Try changing the merge tolerance.\n" );
continue;
}
+
+ /*
+ //don't merge 2 surfaces of solid volumes if they have
+ //opposite sense..indicative that they overlap
+ if( refface_ptr->compare_alignment(compare_refface_ptr) == CUBIT_FORWARD )
+ {
+ continue;
+ } */
// Always retain the entity with the lowest id.
int nullify = j;
@@ -543,6 +659,8 @@
if( destroyDeadGeometry )
GeometryQueryTool::instance()->cleanout_deactivated_geometry();
+
+ CubitObserver::notify_static_observers(NULL, MERGE_COMPLETED);
PRINT_DEBUG_3( "cleanout time: %f secs\n", timer.cpu_secs() );
if (print_info)
@@ -572,6 +690,7 @@
else
return CUBIT_SUCCESS;
}
+
// The basic algorithm is to step through the input list,
// compare every entity with every entity within range of
// its bounding box and merge the spatially equivellant entities.
@@ -677,6 +796,16 @@
GeometryQueryTool::instance()->get_merge_test_internal() );
if( status == CUBIT_FALSE )
continue;
+
+ //don't merge 2 surfaces of solid volumes if they have
+ //opposite sense..indicative that they overlap
+ if( refface_ptr->compare_alignment(compare_refface_ptr) == CUBIT_FORWARD )
+ {
+ //if they are both on solid volumes...bail
+ if( refface_ptr->body()->is_sheet_body() == CUBIT_FALSE &&
+ compare_refface_ptr->body()->is_sheet_body() == CUBIT_FALSE )
+ continue;
+ }
// If we are in this block, we want to merge the
// two entities. If they do not merge, there was
@@ -1406,21 +1535,10 @@
return CUBIT_SUCCESS;
}
-CubitStatus MergeTool::find_only_mergeable_curves( DLIList<BodySM*> &body_list,
+CubitStatus MergeTool::find_only_mergeable_curves( DLIList<Curve*> &all_curves,
DLIList< DLIList<Curve*>*> &lists_of_mergeable_curves )
{
- //collect all the curves from off the bodies
- DLIList<Curve*> all_curves;
- body_list.reset();
int i;
- for(i=body_list.size(); i--; )
- {
- BodySM* tmp_body = body_list.get_and_step();
- DLIList<Curve*> tmp_curves;
- tmp_body->curves( tmp_curves);
- all_curves += tmp_curves;
- }
-
double geom_factor = GeometryQueryTool::get_geometry_factor();
//build up a tree for speed purposes
@@ -1436,6 +1554,8 @@
Curve *curr_curve = all_curves.get_and_step();
if( curr_curve == NULL )
continue;
+
+ BodySM *cur_sm = curr_curve->bodysm();
//get close curves
DLIList<Curve*> close_curves;
@@ -1448,46 +1568,66 @@
if( curr_curve == other_curve )
continue;
- CubitSense rel_sense;
- CubitBoolean abs = about_spatially_equal( curr_curve, other_curve, rel_sense,
- geom_factor );
- if( abs )
+ BodySM *other_sm = other_curve->bodysm();
+
+ if(cur_sm != other_sm)
{
- //check to see if curves have already been inserted into lists
- DLIList<Curve*> *curve1_list = NULL;
+ bool mergeable = false;
- list_iter = curve_to_list_map.find( curr_curve );
- if( list_iter != curve_to_list_map.end() )
- curve1_list = list_iter->second;
-
- if( curve1_list == NULL )
+ // If these curves are already merged add them to the list.
+ if(curr_curve->bridge_manager() &&
+ curr_curve->bridge_manager() == other_curve->bridge_manager())
{
- curve1_list = new DLIList<Curve*>;
- curve1_list->append( curr_curve );
- curve1_list->append( other_curve );
- curve_to_list_map.insert( std::map<Curve*,
- DLIList<Curve*>*>::value_type( curr_curve , curve1_list ));
- curve_to_list_map.insert( std::map<Curve*,
- DLIList<Curve*>*>::value_type( other_curve, curve1_list ));
- lists_of_mergeable_curves.append( curve1_list );
+ mergeable = true;
}
- else
+
+ if(!mergeable)
{
- curve1_list->append( other_curve );
- curve_to_list_map.insert( std::map<Curve*,
- DLIList<Curve*>*>::value_type( other_curve, curve1_list ));
+ CubitSense rel_sense;
+ CubitBoolean abs = about_spatially_equal( curr_curve, other_curve, rel_sense,
+ geom_factor );
+ if(abs)
+ mergeable = true;
}
-
- //remove mergeable curves from list and reset list
- int item_index = all_curves.where_is_item( other_curve );
- if( item_index > 0 )
+
+ if( mergeable )
{
- int curr_index = all_curves.get_index();
- all_curves.reset();
- all_curves.step( item_index );
- all_curves.change_to( NULL );
- all_curves.reset();
- all_curves.step( curr_index );
+ //check to see if curves have already been inserted into lists
+ DLIList<Curve*> *curve1_list = NULL;
+
+ list_iter = curve_to_list_map.find( curr_curve );
+ if( list_iter != curve_to_list_map.end() )
+ curve1_list = list_iter->second;
+
+ if( curve1_list == NULL )
+ {
+ curve1_list = new DLIList<Curve*>;
+ curve1_list->append( curr_curve );
+ curve1_list->append( other_curve );
+ curve_to_list_map.insert( std::map<Curve*,
+ DLIList<Curve*>*>::value_type( curr_curve , curve1_list ));
+ curve_to_list_map.insert( std::map<Curve*,
+ DLIList<Curve*>*>::value_type( other_curve, curve1_list ));
+ lists_of_mergeable_curves.append( curve1_list );
+ }
+ else
+ {
+ curve1_list->append( other_curve );
+ curve_to_list_map.insert( std::map<Curve*,
+ DLIList<Curve*>*>::value_type( other_curve, curve1_list ));
+ }
+
+ //remove mergeable curves from list and reset list
+ int item_index = all_curves.where_is_item( other_curve );
+ if( item_index > 0 )
+ {
+ int curr_index = all_curves.get_index();
+ all_curves.reset();
+ all_curves.step( item_index );
+ all_curves.change_to( NULL );
+ all_curves.reset();
+ all_curves.step( curr_index );
+ }
}
}
}
@@ -1495,6 +1635,43 @@
return CUBIT_SUCCESS;
}
+CubitStatus MergeTool::find_only_mergeable_curves( DLIList<Surface*> &surf_list,
+ DLIList< DLIList<Curve*>*> &lists_of_mergeable_curves )
+{
+ //collect all the curves from off the bodies
+ DLIList<Curve*> all_curves;
+ surf_list.reset();
+ int i;
+ for(i=surf_list.size(); i--; )
+ {
+ Surface* tmp_surf = surf_list.get_and_step();
+ DLIList<Curve*> tmp_curves;
+ tmp_surf->curves(tmp_curves);
+ all_curves += tmp_curves;
+ }
+
+ return find_only_mergeable_curves(all_curves, lists_of_mergeable_curves);
+}
+
+CubitStatus MergeTool::find_only_mergeable_curves( DLIList<BodySM*> &body_list,
+ DLIList< DLIList<Curve*>*> &lists_of_mergeable_curves )
+{
+ //collect all the curves from off the bodies
+ DLIList<Curve*> all_curves;
+ body_list.reset();
+ int i;
+ for(i=body_list.size(); i--; )
+ {
+ BodySM* tmp_body = body_list.get_and_step();
+ DLIList<Curve*> tmp_curves;
+ tmp_body->curves( tmp_curves);
+ all_curves += tmp_curves;
+ }
+
+ return find_only_mergeable_curves(all_curves, lists_of_mergeable_curves);
+
+}
+
CubitStatus MergeTool::find_mergeable_refvertices( DLIList<RefEntity*> &entities,
DLIList< DLIList<RefVertex*>*> &lists_of_mergeable_ref_vertices,
bool clean_up_compare_data )
@@ -1771,6 +1948,20 @@
refedge_ptr->id(), compare_refedge_ptr->id() );
continue;
}
+
+ /*
+ //refuse to merge free edges
+ if( refedge_ptr->ref_volume() == NULL )
+ {
+ PRINT_WARNING("Merging of free curves prohibited: Curve %d\n", refedge_ptr->id() );
+ continue;
+ }
+
+ if( compare_refedge_ptr->ref_volume() == NULL )
+ {
+ PRINT_WARNING("Merging of free curves prohibited: Curve %d\n", compare_refedge_ptr->id() );
+ continue;
+ } */
// Always retain the entity with the lowest id.
int nullify = compare_refedge_ptr->marked();
@@ -2049,7 +2240,20 @@
std::swap(refedge_ptr, compare_refedge_ptr);
nullify = i;
}
+/*
+ //refuse to merge free edges
+ if( refedge_ptr->ref_volume() == NULL )
+ {
+ PRINT_WARNING("Merging of free curves prohibited: Curve %d\n", refedge_ptr->id() );
+ continue;
+ }
+ if( compare_refedge_ptr->ref_volume() == NULL )
+ {
+ PRINT_WARNING("Merging of free curves prohibited: Curve %d\n", compare_refedge_ptr->id() );
+ continue;
+ } */
+
// Now check if merge is okay with all assistants.
CubitBoolean assistant_says_no = CUBIT_FALSE;
for( int k = assistant_list_.size(); k > 0; k-- )
@@ -2138,7 +2342,12 @@
PRINT_DEBUG_3( "cleanout time: %f secs\n",
timer.cpu_secs() );
}
- if (print_info) PRINT_INFO( "Consolidated %d curves\n", merge_count );
+
+ CubitObserver::notify_static_observers(NULL, MERGE_COMPLETED);
+
+ if(print_info)
+ PRINT_INFO( "Consolidated %d curves\n", merge_count );
+
if( CubitMessage::instance()->Interrupt() )
{
PRINT_WARNING("Curve merging aborted.\n");
@@ -2259,6 +2468,19 @@
CUBIT_TRUE );
if( status == CUBIT_FALSE )
continue;
+
+/* //refuse to merge free edges
+ if( refvertex_ptr->ref_edge() == NULL )
+ {
+ PRINT_WARNING("Merging of free vertices prohibited: Vertex %d\n", refvertex_ptr->id() );
+ continue;
+ }
+
+ if( compare_refvertex_ptr->ref_edge() == NULL )
+ {
+ PRINT_WARNING("Merging of free vertices prohibited: Vertex %d\n", compare_refvertex_ptr->id() );
+ continue;
+ } */
//Make sure we arn't merging two vertices on a
//curve.
@@ -2511,7 +2733,20 @@
CUBIT_TRUE );
if( status == CUBIT_FALSE )
continue;
-
+/*
+ //refuse to merge free edges
+ if( refvertex_ptr->ref_edge() == NULL )
+ {
+ PRINT_WARNING("Merging of free vertices prohibited: Vertex %d\n", refvertex_ptr->id() );
+ continue;
+ }
+
+ if( compare_refvertex_ptr->ref_edge() == NULL )
+ {
+ PRINT_WARNING("Merging of free vertices prohibited: Vertex %d\n", compare_refvertex_ptr->id() );
+ continue;
+ }
+ */
//Make sure we arn't merging two vertices on a
//curve.
DLIList<RefEdge*> edges_1, edges_2;
@@ -2627,8 +2862,12 @@
GeometryQueryTool::instance()->cleanout_deactivated_geometry();
PRINT_DEBUG_3( "cleanout time: %f secs\n",
timer.cpu_secs() );
+
+ CubitObserver::notify_static_observers(NULL, MERGE_COMPLETED);
- if (print_info) PRINT_INFO( "Consolidated %d pairs of vertices\n", merge_count );
+ if(print_info)
+ PRINT_INFO( "Consolidated %d pairs of vertices\n", merge_count );
+
if( CubitMessage::instance()->Interrupt() )
{
PRINT_WARNING("Vertex merging aborted.\n");
@@ -2779,7 +3018,7 @@
CubitBoolean top = start_unmerge();
CubitStatus result = CUBIT_SUCCESS;
int i;
-
+
DLIList<TopologyBridge*> bridge_list;
face_ptr->bridge_manager()->get_bridge_list(bridge_list);
if (bridge_list.size() < 2)
@@ -2922,7 +3161,11 @@
if (parents.size() == 0)
{
if (new_list.insert(new_ptr).second)
+ {
CubitObserver::notify_static_observers( new_ptr, FREE_REF_ENTITY_GENERATED );
+ CGMHistory::Event evt(CGMHistory::TOP_LEVEL_ENTITY_CREATED, new_ptr);
+ GeometryQueryTool::instance()->history().add_event(evt);
+ }
}
while (parents.size())
@@ -2939,7 +3182,11 @@
std::set<CubitObservable*>::iterator iter;
for (iter = modified_list.begin(); iter != modified_list.end(); ++iter)
+ {
(*iter)->notify_all_observers( TOPOLOGY_MODIFIED );
+ CGMHistory::Event evt(CGMHistory::TOPOLOGY_CHANGED, static_cast<RefEntity*>(*iter));
+ GeometryQueryTool::instance()->history().add_event(evt);
+ }
for( int a = assistant_list_.size(); a--; )
assistant_list_.get_and_step()->finish_unmerge();
@@ -2968,7 +3215,11 @@
{
CubitStatus result = CUBIT_FAILURE;
DLIList<ModelEntity*> query_results, query_results_2;
-
+
+ // save to notify at end
+ DLIList<RefEntity*> dead_parents;
+ dead_entity->get_parent_ref_entities(dead_parents);
+
// Make sure that the 2 BTE's are of the same type
if( keeper_entity->dag_type() != dead_entity->dag_type() )
{
@@ -3052,7 +3303,7 @@
"numbers of GroupingEntities.\n"
" THIS IS A BUG - PLEASE REPORT IT!\n" );
assert(0);
- }
+ }
// Merge all child BTEs
BasicTopologyEntity *bte_ptr_1, *bte_ptr_2;
@@ -3086,7 +3337,7 @@
return CUBIT_FAILURE;
}
}
-
+
// If RefFace or RefEdge, adjust sense of parent sense entities,
// if necessary. This was previously handled by the
// switch_child_notify() callback in DAGNode/ModelEntity.
@@ -3096,6 +3347,7 @@
// compare_alignment() does not need to be called for every
// SenseEntitiy merge. We only need to call it once.
CubitBoolean switch_sense = CUBIT_FALSE;
+
if(CAST_TO( keeper_entity, RefFace ) )
{
RefFace* keep_face = CAST_TO(keeper_entity,RefFace);
@@ -3104,7 +3356,7 @@
{
switch_sense = CUBIT_TRUE;
}
- warn_about_refface_sense( keep_face, dead_face, switch_sense );
+ //warn_about_refface_sense( keep_face, dead_face, switch_sense );
}
else if( CAST_TO( keeper_entity, RefEdge ) )
{
@@ -3191,10 +3443,14 @@
// Merge the name(s) of dead_entity to those of keeper_entity
keeper_entity->merge_entity_names( dead_entity );
- bool is_free_entity = false;
+ bool is_dead_entity_free_entity = false;
if( dead_entity->num_parent_ref_entities() == 0 )
- is_free_entity = true;
+ is_dead_entity_free_entity = true;
+ bool is_keeper_entity_free_entity = false;
+ if( keeper_entity->num_parent_ref_entities() == 0 )
+ is_keeper_entity_free_entity = true;
+
// Next, merge the links of these two BTEs
SenseEntity* co_edge_ptr;
result = CUBIT_SUCCESS;
@@ -3236,8 +3492,12 @@
dead_entity->notify_all_observers( MergeEvent(dead_entity, keeper_entity) );
dead_entity->notify_all_observers( MODEL_ENTITY_DESTRUCTED );
- if( is_free_entity ) //is free entity...top level
+ if( is_dead_entity_free_entity ) //is free entity...top level
+ {
dead_entity->notify_all_observers( TOP_LEVEL_ENTITY_DESTRUCTED );
+ CGMHistory::Event evt(CGMHistory::TOP_LEVEL_ENTITY_DELETED, dead_entity);
+ GeometryQueryTool::instance()->history().add_event(evt);
+ }
dead_entity->deactivated(CUBIT_TRUE);
@@ -3267,7 +3527,22 @@
MergeEvent merge_event(dead_entity, keeper_entity);
merge_event.set_event_type(ENTITY_SURVIVED_MERGE);
CubitObserver::notify_static_observers(keeper_entity, merge_event);
-
+
+ if( is_keeper_entity_free_entity && !is_dead_entity_free_entity ) //is free entity...top level
+ {
+ keeper_entity->notify_all_observers( TOP_LEVEL_ENTITY_DESTRUCTED );
+ CGMHistory::Event evt(CGMHistory::TOP_LEVEL_ENTITY_DELETED, keeper_entity);
+ GeometryQueryTool::instance()->history().add_event(evt);
+ }
+
+
+ for(int i=0; i<dead_parents.size(); i++)
+ {
+ dead_parents[i]->notify_all_observers(TOPOLOGY_MODIFIED);
+ CGMHistory::Event evt(CGMHistory::TOPOLOGY_CHANGED, dead_parents[i]);
+ GeometryQueryTool::instance()->history().add_event(evt);
+ }
+
return CUBIT_SUCCESS;
}
@@ -3941,6 +4216,8 @@
if (destroyDeadGeometry)
GeometryQueryTool::instance()->cleanout_deactivated_geometry();
+
+ CubitObserver::notify_static_observers(NULL, MERGE_COMPLETED);
return vtx1;
}
@@ -4033,6 +4310,9 @@
remove_compare_data();
if (destroyDeadGeometry)
GeometryQueryTool::instance()->cleanout_deactivated_geometry();
+
+ CubitObserver::notify_static_observers(NULL, MERGE_COMPLETED);
+
return edge1;
}
@@ -4248,6 +4528,9 @@
remove_compare_data();
if (destroyDeadGeometry)
GeometryQueryTool::instance()->cleanout_deactivated_geometry();
+
+ CubitObserver::notify_static_observers(NULL, MERGE_COMPLETED);
+
return face1;
}
@@ -4654,6 +4937,7 @@
surfaces.step( j );
// Create new face
RefFace* new_face = RefEntityFactory::instance()->construct_RefFace( surfaces.get() );
+
for (i = surfaces.size(); i > 1; i-- )
new_face->bridge_manager()->add_bridge( surfaces.step_and_get() );
@@ -4792,6 +5076,7 @@
// Find the curve(s) in the just-unmerged refface
bridge_list.reset();
+ DLIList<Curve*> other_curves_to_unmerge;
for (j = bridge_list.size(); j--; )
{
TopologyBridge* bridge = bridge_list.get_and_step();
@@ -4799,6 +5084,7 @@
bridge->get_parents( bridge_parents );
bridge_parents.reset();
bool in_old = false, in_new = false;
+
while (bridge_parents.size())
{
CoEdge* coedge = dynamic_cast<CoEdge*>(bridge_parents.pop()->topology_entity());
@@ -4817,7 +5103,28 @@
else if(in_new)
{
curve_list.append( dynamic_cast<Curve*>(bridge) );
+ continue;
}
+
+ //Some other curves might be merge candidates now..
+ //If both surfaces on either side of the curve have been unmerged,
+ //then this curve can be unmerged too.
+ bool unmerge_curve = true;
+ bridge_parents.clean_out();
+ bridge->get_parents( bridge_parents );
+ while (bridge_parents.size())
+ {
+ CoEdge* coedge = dynamic_cast<CoEdge*>(bridge_parents.pop()->topology_entity());
+ if( coedge->bridge_manager()->number_of_bridges() != 1 )
+ {
+ unmerge_curve = false;
+ break;
+ }
+ }
+
+ if( unmerge_curve == true )
+ other_curves_to_unmerge.append_unique( dynamic_cast<Curve*>(bridge) );
+
} // for( j in bridge_list )
// Find curve(s) that must remain merged.
@@ -4851,6 +5158,10 @@
{
separate_edge( curve_list, true );
}
+
+ if( other_curves_to_unmerge.size() )
+ separate_edge( other_curves_to_unmerge, true );
+
} // for (i in edge_list)
} // if (unmerge_curves)
@@ -4878,6 +5189,10 @@
RefEdge* old_edge = dynamic_cast<RefEdge*>( can_separate( bridge_list, true ) );
if (!old_edge)
return 0;
+
+ bool old_edge_free_before = true;
+ if( old_edge->num_parent_ref_entities() )
+ old_edge_free_before = false;
CubitBoolean top = start_unmerge();
@@ -4895,6 +5210,7 @@
curves.step( j );
// Create new edge
RefEdge* new_edge = RefEntityFactory::instance()->construct_RefEdge( curves.get() );
+
for (i = curves.size(); i > 1; i-- )
new_edge->bridge_manager()->add_bridge( curves.step_and_get() );
@@ -4987,10 +5303,11 @@
point_list.append( point );
}
- point_list.reset();
for (j = 0; j < point_list.size(); j++)
{
- Point* point = point_list.get_and_step();
+ point_list.reset();
+ point_list.step(j);
+ Point* point = point_list.get();
parent_curves.clean_out();
point->get_parents( parent_curves );
@@ -5001,7 +5318,7 @@
BridgeManager* bm = curve->bridge_manager();
bridge_list.clean_out();
bm->get_bridge_list( bridge_list );
-
+
bridge_list.reset();
for (int l = bridge_list.size(); l--; )
{
@@ -5015,10 +5332,17 @@
}
}
}
-
separate_vertex( point_list );
}
}
+
+ if( !old_edge_free_before && old_edge->num_parent_ref_entities() == 0 )
+ {
+ CubitObserver::notify_static_observers( old_edge, FREE_REF_ENTITY_GENERATED );
+ CGMHistory::Event evt(CGMHistory::TOP_LEVEL_ENTITY_CREATED, old_edge );
+ GeometryQueryTool::instance()->history().add_event(evt);
+ }
+
end_unmerge(top);
return new_edge;
@@ -5038,16 +5362,18 @@
RefVertex* MergeTool::separate_vertex( DLIList<Point*>& points )
{
int i, j;
-
DLIList<TopologyBridge*> bridge_list( points.size() );
CAST_LIST_TO_PARENT( points, bridge_list );
RefVertex* old_vtx = dynamic_cast<RefVertex*>( can_separate( bridge_list, true ) );
if (!old_vtx)
return 0;
+
+ bool old_vtx_free_before = true;
+ if( old_vtx->num_parent_ref_entities() )
+ old_vtx_free_before = false;
CubitBoolean top = start_unmerge();
-
// Split the RefVertex
// Remove points from old vertex
@@ -5092,6 +5418,14 @@
for (i = assistant_list_.size(); i--; )
assistant_list_.get_and_step()->unmerged( old_vtx, new_vtx, false );
+ if( !old_vtx_free_before && old_vtx->num_parent_ref_entities() == 0 )
+ {
+ CubitObserver::notify_static_observers( old_vtx, FREE_REF_ENTITY_GENERATED );
+ CGMHistory::Event evt(CGMHistory::TOP_LEVEL_ENTITY_CREATED, old_vtx );
+ GeometryQueryTool::instance()->history().add_event(evt);
+ }
+
+
end_unmerge(top);
return new_vtx;
}
@@ -5128,7 +5462,14 @@
}
if (smallest)
- bte->set_id(smallest);
+ {
+ //make sure this id isn't in use already
+ RefEntity *tmp_ent =
+ RefEntityFactory::instance()->get_ref_entity( bte->entity_type_info(), smallest );
+
+ if( tmp_ent == NULL )
+ bte->set_id(smallest);
+ }
return CUBIT_SUCCESS;
}
@@ -5426,4 +5767,1139 @@
return CUBIT_TRUE;
}
+void MergeTool::imprint_merge_solutions_for_overlapping_surfaces(
+ RefFace *face1,
+ RefFace *face2,
+ bool execute,
+ DLIList<CubitString*> &display_strings,
+ DLIList<CubitString*> &command_strings,
+ DLIList<CubitString*> &preview_strings )
+{
+ //collect all the unmerged curves between the 2 surfaces
+ DLIList<RefEdge*> edges1, edges2, tmp_list;
+ face1->ref_edges( edges1 );
+ face2->ref_edges( edges2 );
+ tmp_list += edges1;
+ tmp_list.intersect_unordered( edges2 );
+
+ //remove all the common edges from both lists
+ edges1 -= tmp_list;
+ edges2 -= tmp_list;
+
+ double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS;
+ CubitString *preview_string;
+
+ if(!execute)
+ {
+ preview_string = new CubitString("draw surface ");
+ *preview_string += face1->id();
+ *preview_string += " ";
+ *preview_string += face2->id();
+ *preview_string += " overlap";
+ }
+
+ //if all curves of both surfaces are merged, suggest 'force merge'
+ if( edges1.size() == 0 && edges2.size() == 0 )
+ {
+ //quick check to make sure that centerpoints are nearly coincident
+ CubitVector center1 = face1->center_point();
+ CubitVector center2 = face2->center_point();
+
+ if( center1.distance_between( center2 ) <= (tolerance*5) )
+ {
+ if(execute)
+ {
+ MergeTool::instance()->force_merge(face1, face2);
+ }
+ else
+ {
+ //display strings
+ CubitString *display_string = new CubitString("Force merge Surface ");
+ *display_string += face1->id();
+ *display_string += " ";
+ *display_string += face2->id();
+ display_strings.append( display_string );
+
+ CubitString *command_string = new CubitString("merge surface ");
+ *command_string += face1->id();
+ *command_string += " ";
+ *command_string += face2->id();
+ *command_string += " force";
+ command_strings.append( command_string );
+
+ preview_strings.append( preview_string );
+ }
+
+ return;
+ }
+ }
+
+ //get all the vertices
+ DLIList<RefVertex*> verts1, verts2, merged_vertices;
+ face1->ref_vertices( verts1 );
+ face2->ref_vertices( verts2 );
+ merged_vertices += verts1;
+ merged_vertices.intersect_unordered( verts2 );
+
+ //remove all the merged vertices from both lists
+ verts1 -= merged_vertices;
+ verts2 -= merged_vertices;
+
+ int i,j,k;
+ //another force merge case...all vertices are merged, but some
+ //coincident curves remain unmerged still.
+ if( verts1.size() == 0 && verts2.size() == 0 )
+ {
+ DLIList<RefEdge*> tmp_edges1( edges1 );
+ DLIList<RefEdge*> tmp_edges2( edges2 );
+
+ //find edges that are close to one another
+ for( i=tmp_edges1.size(); i--; )
+ {
+ RefEdge *edge1 = tmp_edges1.get_and_step();
+
+ //get some random point on curve edge1
+ CubitVector position_on_edge1;
+ edge1->position_from_fraction( 0.634, position_on_edge1 );
+
+ bool found_pair = false;
+ for( j=tmp_edges2.size(); j--; )
+ {
+ RefEdge *edge2 = tmp_edges2.get_and_step();
+
+ if( edge2 == NULL )
+ continue;
+
+ //make sure that they have the same vertices
+ if( (edge1->start_vertex() == edge2->start_vertex() ||
+ edge1->start_vertex() == edge2->end_vertex() ) &&
+ (edge1->end_vertex() == edge2->end_vertex() ||
+ edge1->end_vertex() == edge2->start_vertex() ) )
+ {
+ //find the closest point
+ CubitVector close_pt;
+ edge2->closest_point_trimmed( position_on_edge1, close_pt );
+
+ //adjust tolerance to be larger possibly, a thousandanth of the curve's length
+ double tmp_tolerance = edge2->measure()*0.01;
+ if( tolerance > tmp_tolerance )
+ tmp_tolerance = tolerance;
+
+ if( close_pt.distance_between( position_on_edge1 ) < tmp_tolerance )
+ {
+ //remove both from the list
+ tmp_edges2.back();
+ tmp_edges2.change_to( NULL );
+ found_pair = true;
+ break;
+ }
+ }
+ }
+ if( found_pair == true )
+ {
+ tmp_edges1.back();
+ tmp_edges1.change_to( NULL );
+ tmp_edges1.step();
+ }
+ }
+
+ tmp_edges1.remove_all_with_value( NULL );
+ tmp_edges2.remove_all_with_value( NULL );
+
+ if( tmp_edges1.size() == 0 && tmp_edges2.size() == 0 )
+ {
+ if(execute)
+ {
+ MergeTool::instance()->force_merge(face1, face2);
+ }
+ else
+ {
+ //display strings
+ CubitString *display_string = new CubitString("Force merge Surface ");
+ *display_string += face1->id();
+ *display_string += " ";
+ *display_string += face2->id();
+ display_strings.append( display_string );
+
+ CubitString *command_string = new CubitString("merge surface ");
+ *command_string += face1->id();
+ *command_string += " ";
+ *command_string += face2->id();
+ *command_string += " force";
+ command_strings.append( command_string );
+
+ preview_strings.append( preview_string );
+ }
+ return;
+ }
+ }
+
+ //Look for near-coincident vertices between surfaces.
+ //If any vertices are less than merge_tolerance*5 apart,
+ //merge all the vertices
+ verts1.clean_out();
+ verts2.clean_out();
+ face1->ref_vertices( verts1 );
+ face2->ref_vertices( verts2 );
+ double tmp_tol = tolerance * 5;
+ double recommended_tol = -1;
+ RefVertex *near_coincident_verts[2];
+
+ for( i=verts1.size(); i--; )
+ {
+ RefVertex *vert1 = verts1.get_and_step();
+ CubitVector pos1 = vert1->coordinates();
+
+ for( j=verts2.size(); j--; )
+ {
+ RefVertex *vert2 = verts2.get_and_step();
+ if( vert2 == vert1 )//already merged case
+ continue;
+ CubitVector pos2 = vert2->coordinates();
+
+ double tmp_dist = pos1.distance_between( pos2 );
+ if( tmp_dist < tmp_tol )
+ {
+ if( tmp_dist > recommended_tol )
+ {
+ recommended_tol = tmp_dist;
+ near_coincident_verts[0] = vert1;
+ near_coincident_verts[1] = vert2;
+ }
+ }
+ }
+ }
+
+ if( recommended_tol > 0 )
+ {
+ double merge_tol = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS;
+
+ if(execute)
+ {
+ double old_merge_tol = -1;
+ if( recommended_tol > merge_tol )
+ {
+ old_merge_tol = GeometryQueryTool::get_geometry_factor();
+ GeometryQueryTool::set_geometry_factor(recommended_tol);
+ }
+ DLIList<RefVertex*> merge_vert_list;
+ face1->ref_vertices(merge_vert_list);
+ face2->ref_vertices(merge_vert_list);
+ MergeTool::instance()->merge_refvertices( merge_vert_list );
+ if( old_merge_tol != -1 )
+ GeometryQueryTool::set_geometry_factor( old_merge_tol );
+ }
+ else
+ {
+ CubitString *display_string = new CubitString("Merge vertices of surface ");
+ *display_string += face1->id();
+ *display_string += " ";
+ *display_string += face2->id();
+ if( recommended_tol > merge_tol )
+ {
+ recommended_tol *= 1.1;
+ *display_string += " tolerance ";
+ *display_string += CubitString( recommended_tol, 0, 7 );
+ }
+ display_strings.append( display_string );
+
+ CubitString *command_string = new CubitString("merge vertex in surface ");
+ *command_string += face1->id();
+ *command_string += " ";
+ *command_string += face2->id();
+ if( recommended_tol > merge_tol )
+ {
+ *command_string += " tolerance ";
+ *command_string += CubitString( recommended_tol, 0, 7 );
+ }
+ command_strings.append( command_string );
+
+ preview_strings.append( preview_string );
+ }
+ return;
+ }
+
+ DLIList<CubitVector*> positions_to_imprint_onto_face1;
+ DLIList<CubitVector*> positions_to_imprint_onto_face2;
+
+ double possible_slivers_on_face1 = 0;
+ double possible_slivers_on_face2 = 0;
+
+ double dist1, dist2, dist3;
+
+ //if you have overlapping curves, suggest imprinting owning volume with vertex
+ std::map<RefEdge*, DLIList<CurveOverlapFacet*>* > facet_map;
+
+ DLIList<RefEdge*> overlapping_edges2;
+
+ for( i=edges1.size(); i--; )
+ {
+ RefEdge *edge1 = edges1.get_and_step();
+
+ DLIList<RefVertex*> verts1;
+ edge1->ref_vertices( verts1 );
+ RefVertex *s_vert1 = verts1.get_and_step();
+ RefVertex *e_vert1 = verts1.get();
+
+ bool overlaps_with_another_curve = false;
+ double edge1_length = edge1->measure();
+ double curve_overlap_tolerance = 0.005;
+
+ for( j=edges2.size(); j--; )
+ {
+ RefEdge *edge2 = edges2.get_and_step();
+
+ if( edge2 == NULL )
+ continue;
+
+ if( SurfaceOverlapTool::instance()->check_overlap( edge1, edge2,
+ &facet_map,
+ &curve_overlap_tolerance ))
+ {
+ overlapping_edges2.append_unique( edge2 );
+ overlaps_with_another_curve = true;
+
+ DLIList<RefVertex*> verts2;
+ edge2->ref_vertices( verts2 );
+ RefVertex *s_vert2 = verts2.get_and_step();
+ RefVertex *e_vert2 = verts2.get();
+
+ CubitVector close_pt;
+ edge1->closest_point_trimmed( s_vert2->coordinates(), close_pt );
+
+ double edge2_length = edge2->measure();
+
+ double tmp_tolerance = edge2_length;
+ if( edge1_length < edge2_length )
+ tmp_tolerance = edge1_length;
+
+ //For a vertex of curve A to be imprinted on curve B, that vertex of A
+ //must be a distance greater than 1/2 a percent of the lenght of
+ //whichever curve is smaller (A or B)
+ tmp_tolerance *= 0.005;
+ double sliver_tolerance = tmp_tolerance * 2;
+
+ if( tolerance < tmp_tolerance )
+ tolerance = tmp_tolerance;
+
+ dist1 = close_pt.distance_between( s_vert2->coordinates() );
+ dist2 = close_pt.distance_between( s_vert1->coordinates() );
+ dist3 = close_pt.distance_between( e_vert1->coordinates() );
+
+ //decide what vertex needs to be imprinted where
+ if( dist1 < tolerance &&
+ dist2 > tolerance &&
+ dist3 > tolerance )
+ {
+
+ //make sure this position doesn't already exist
+ bool add_position = true;
+ for( k=positions_to_imprint_onto_face1.size(); k--; )
+ {
+ CubitVector *tmp_vec = positions_to_imprint_onto_face1.get_and_step();
+
+ if( close_pt.distance_between( *tmp_vec ) < tolerance )
+ {
+ add_position = false;
+ break;
+ }
+ }
+
+ if( add_position )
+ {
+ //imprint body of edge1 with vertex at this location
+ CubitVector *tmp_vec = new CubitVector( close_pt );
+ positions_to_imprint_onto_face1.append( tmp_vec );
+
+ //watch for possible sliver creation
+ if( dist2 < sliver_tolerance || dist3 < sliver_tolerance )
+ possible_slivers_on_face1++;
+ }
+ }
+
+ edge1->closest_point_trimmed( e_vert2->coordinates(), close_pt );
+
+ dist1 = close_pt.distance_between( e_vert2->coordinates() );
+ dist2 = close_pt.distance_between( s_vert1->coordinates() );
+ dist3 = close_pt.distance_between( e_vert1->coordinates() );
+
+ if( dist1 < tolerance &&
+ dist2 > tolerance &&
+ dist3 > tolerance )
+ {
+ //make sure this position doesn't already exist
+ bool add_position = true;
+ for( k=positions_to_imprint_onto_face1.size(); k--; )
+ {
+ CubitVector *tmp_vec = positions_to_imprint_onto_face1.get_and_step();
+
+ if( close_pt.distance_between( *tmp_vec ) < tolerance )
+ {
+ add_position = false;
+ break;
+ }
+ }
+
+ if( add_position )
+ {
+ //imprint body of edge1 with vertex at this location
+ CubitVector *tmp_vec = new CubitVector( close_pt );
+ positions_to_imprint_onto_face1.append( tmp_vec );
+
+ //watch for possible sliver creation
+ if( dist2 < sliver_tolerance || dist3 < sliver_tolerance )
+ possible_slivers_on_face1++;
+ }
+ }
+
+ edge2->closest_point_trimmed( s_vert1->coordinates(), close_pt );
+
+ dist1 = close_pt.distance_between( s_vert1->coordinates() );
+ dist2 = close_pt.distance_between( s_vert2->coordinates() );
+ dist3 = close_pt.distance_between( e_vert2->coordinates() );
+
+ if( dist1 < tolerance &&
+ dist2 > tolerance &&
+ dist3 > tolerance )
+ {
+ //make sure this position doesn't already exist
+ bool add_position = true;
+ for( k=positions_to_imprint_onto_face2.size(); k--; )
+ {
+ CubitVector *tmp_vec = positions_to_imprint_onto_face2.get_and_step();
+
+ if( close_pt.distance_between( *tmp_vec ) < tolerance )
+ {
+ add_position = false;
+ break;
+ }
+ }
+
+ if( add_position )
+ {
+ //imprint body of edge1 with vertex at this location
+ CubitVector *tmp_vec = new CubitVector( close_pt );
+ positions_to_imprint_onto_face2.append( tmp_vec );
+
+ //watch for possible sliver creation
+ if( dist2 < sliver_tolerance || dist3 < sliver_tolerance )
+ possible_slivers_on_face2++;
+ }
+ }
+
+ edge2->closest_point_trimmed( e_vert1->coordinates(), close_pt );
+
+ dist1 = close_pt.distance_between( e_vert1->coordinates() );
+ dist2 = close_pt.distance_between( s_vert2->coordinates() );
+ dist3 = close_pt.distance_between( e_vert2->coordinates() );
+
+ if( dist1 < tolerance &&
+ dist2 > tolerance &&
+ dist3 > tolerance )
+ {
+ //make sure this position doesn't already exist
+ bool add_position = true;
+ for( k=positions_to_imprint_onto_face2.size(); k--; )
+ {
+ CubitVector *tmp_vec = positions_to_imprint_onto_face2.get_and_step();
+
+ if( close_pt.distance_between( *tmp_vec ) < tolerance )
+ {
+ add_position = false;
+ break;
+ }
+ }
+
+ if( add_position )
+ {
+ //imprint body of edge1 with vertex at this location
+ CubitVector *tmp_vec = new CubitVector( close_pt );
+ positions_to_imprint_onto_face2.append( tmp_vec );
+
+ //watch for possible sliver creation
+ if( dist2 < sliver_tolerance || dist3 < sliver_tolerance )
+ possible_slivers_on_face2++;
+ }
+ }
+ }
+ }
+
+ //remove this curve if it really overlaps
+ if( overlaps_with_another_curve == true )
+ {
+ edges1.back();
+ edges1.change_to( NULL );
+ edges1.step();
+ }
+ }
+
+ //clean up facets
+ std::map<RefEdge*, DLIList<CurveOverlapFacet*>* >::iterator facet_iter;
+ facet_iter=facet_map.begin();
+ for(; facet_iter != facet_map.end(); facet_iter++ )
+ {
+ DLIList<CurveOverlapFacet*> *co_facet_list = facet_iter->second;
+
+ //delete all the facets in the list
+ for( i=co_facet_list->size(); i--; )
+ delete co_facet_list->get_and_step();
+ delete co_facet_list;
+ }
+
+ //reset tolerance
+ tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS;
+
+ //after this you should only be left with unmerged, non-overlapping edges
+ edges1.remove_all_with_value( NULL );
+ edges2 -= overlapping_edges2;
+
+ //if all the curves are either merged or overlapping and
+ //no vertices of any curve will imprint onto any other curve...
+ //suggest force merging the 2 surfaces
+ if( edges1.size() == 0 && edges2.size() == 0 &&
+ positions_to_imprint_onto_face1.size() == 0 &&
+ positions_to_imprint_onto_face2.size() == 0 )
+ {
+
+ //make sure the 2 surfaces have same number of curves and vertices
+ if( face1->num_ref_vertices() == face2->num_ref_vertices() &&
+ face1->num_ref_edges() == face2->num_ref_edges() )
+ {
+ if(execute)
+ {
+ MergeTool::instance()->force_merge(face1, face2);
+ }
+ else
+ {
+ CubitString *display_string = new CubitString("Force merge Surface ");
+ *display_string += face1->id();
+ *display_string += " ";
+ *display_string += face2->id();
+ display_strings.append( display_string );
+
+ CubitString *command_string = new CubitString("merge surface ");
+ *command_string += face1->id();
+ *command_string += " ";
+ *command_string += face2->id();
+ *command_string += " force";
+ command_strings.append( command_string );
+
+ preview_strings.append( preview_string );
+ }
+ return;
+ }
+ }
+
+ //try to suggest some curves you can imprint onto a surface
+ if( edges1.size() || edges2.size() )
+ {
+ DLIList<RefFace*> face_list(1);
+ face_list.append( face2 );
+
+ //see what edges in edges1 will imprint onto face2
+ DLIList<RefEdge*> edges_to_imprint_onto_face2;
+ for( i=edges1.size(); i--; )
+ {
+ RefEdge *edge1 = edges1.get_and_step();
+
+ //project
+ DLIList<RefEdge*> edge_list(1);
+ DLIList<RefEdge*> new_edges;
+ edge_list.append( edge1);
+ bool print_error = false;
+
+ DLIList<Surface*> surface_list(1);
+ DLIList<Curve*> curves_to_project(1), projected_curves;
+ GeometryModifyEngine* gme = GeometryModifyTool::instance()->common_modify_engine(
+ face_list,
+ edge_list,
+ surface_list,
+ curves_to_project);
+ CubitStatus status = gme->
+ project_edges( surface_list, curves_to_project, projected_curves);
+
+ if( projected_curves.size() == 0 )
+ continue;
+
+ Curve *projected_curve = projected_curves.get();
+
+ //if midpoint of projected curve is far from original curve, continue
+ CubitVector original_curve_mid_point = edge1->center_point();
+ if( original_curve_mid_point.distance_between( projected_curve->center_point() ) > tolerance )
+ {
+ gme->get_gqe()->delete_solid_model_entities( projected_curve );
+ continue;
+ }
+
+ bool is_curve_on_surface = false;
+ //do a surface-curve intersection to see if the curve lies on the surface
+ DLIList<Curve*> intersection_curves;
+ status = gme->curve_surface_intersection( surface_list.get(),
+ projected_curve,
+ intersection_curves);
+
+ if( status == CUBIT_SUCCESS && intersection_curves.size() )
+ {
+ //remove any sliver curves
+ for( j=intersection_curves.size(); j--; )
+ {
+ Curve *tmp_curve = intersection_curves.get_and_step();
+ if( tmp_curve->measure() < tolerance )
+ {
+ gme->get_gqe()->delete_solid_model_entities( tmp_curve );
+ intersection_curves.back();
+ intersection_curves.change_to( NULL );
+ intersection_curves.step();
+ }
+ }
+
+ intersection_curves.remove_all_with_value( NULL );
+
+ if( intersection_curves.size() )
+ is_curve_on_surface = true;
+
+ //delete the intersection curves
+ for( j=intersection_curves.size(); j--; )
+ gme->get_gqe()->delete_solid_model_entities( intersection_curves.get_and_step() );
+ }
+
+ //maybe the surface-curve intersection method above didn't work...do
+ //this more primitive method instead
+ if( is_curve_on_surface == false )
+ {
+ double distances_on_curves[3];
+ distances_on_curves[0] = .235;
+ distances_on_curves[1] = .468;
+ distances_on_curves[2] = .894;
+
+ for( j=0; j<3; j++ )
+ {
+ CubitVector position_on_curve;
+ projected_curve->position_from_fraction( distances_on_curves[j],
+ position_on_curve );
+
+ CubitVector closest_point_on_surface;
+ face2->find_closest_point_trimmed( position_on_curve,
+ closest_point_on_surface );
+
+ if( position_on_curve.distance_between( closest_point_on_surface ) < tolerance )
+ {
+ is_curve_on_surface = true;
+ break;
+ }
+ }
+ }
+
+ //delete the projected curve
+ gme->get_gqe()->delete_solid_model_entities( projected_curve );
+
+ if( is_curve_on_surface == false )
+ continue;
+
+ edges_to_imprint_onto_face2.append( edge1 );
+ }
+
+ //a possible force merge situation???
+ if( edges_to_imprint_onto_face2.size() )
+ {
+ //are the number of vertices on both faces the same?
+ if( face1->num_ref_vertices() == face2->num_ref_vertices() &&
+ face1->num_ref_edges() == face2->num_ref_edges() )
+ {
+ double overlapping_area = 0;
+ SurfaceOverlapTool::instance()->check_overlap(
+ face1, face2, CUBIT_FALSE, CUBIT_FALSE, &overlapping_area );
+ double face1_area = face1->area();
+ double face2_area = face2->area();
+
+ //make sure overlapping area is more than 99% of both surface areas
+ double area_diff1 = fabs( overlapping_area - face1_area );
+ double area_diff2 = fabs( overlapping_area - face2_area );
+
+ if( area_diff1 < (face1_area*0.01) &&
+ area_diff2 < (face2_area*0.01) )
+ {
+ if(execute)
+ {
+ MergeTool::instance()->force_merge(face1, face2);
+ }
+ else
+ {
+ CubitString *display_string = new CubitString("Force merge Surface ");
+ *display_string += face1->id();
+ *display_string += " ";
+ *display_string += face2->id();
+ display_strings.append( display_string );
+
+ CubitString *command_string = new CubitString("merge surface ");
+ *command_string += face1->id();
+ *command_string += " ";
+ *command_string += face2->id();
+ *command_string += " force";
+ command_strings.append( command_string );
+
+ preview_strings.append( preview_string );
+ }
+ return;
+ }
+ }
+ }
+
+ face_list.clean_out();
+ face_list.append( face1 );
+
+ DLIList<RefEdge*> edges_to_imprint_onto_face1;
+ //see what edges in edges2 will imprint onto face1
+ for( i=edges2.size(); i--; )
+ {
+ RefEdge *edge2 = edges2.get_and_step();
+
+ //project
+ DLIList<RefEdge*> edge_list(1);
+ DLIList<RefEdge*> new_edges;
+ edge_list.append( edge2);
+ bool print_error = false;
+
+ DLIList<Surface*> surface_list(1);
+ DLIList<Curve*> curves_to_project(1), projected_curves;
+ GeometryModifyEngine* gme = GeometryModifyTool::instance()->common_modify_engine(
+ face_list,
+ edge_list,
+ surface_list,
+ curves_to_project);
+ CubitStatus status = gme->
+ project_edges( surface_list, curves_to_project, projected_curves);
+
+ if( projected_curves.size() == 0 )
+ continue;
+
+ Curve *projected_curve = projected_curves.get();
+
+ //if midpoint of projected curve is far from original curve, continue
+ CubitVector original_curve_mid_point = edge2->center_point();
+ if( original_curve_mid_point.distance_between( projected_curve->center_point() ) > tolerance )
+ {
+ gme->get_gqe()->delete_solid_model_entities( projected_curve );
+ continue;
+ }
+
+ bool is_curve_on_surface = false;
+ //do a surface-curve intersection to see if the curve lies on the surface
+ DLIList<Curve*> intersection_curves;
+ status = gme->curve_surface_intersection( surface_list.get(),
+ projected_curve,
+ intersection_curves);
+
+ if( status == CUBIT_SUCCESS && intersection_curves.size() )
+ {
+ //remove any sliver curves
+ for( j=intersection_curves.size(); j--; )
+ {
+ Curve *tmp_curve = intersection_curves.get_and_step();
+ if( tmp_curve->measure() < tolerance )
+ {
+ gme->get_gqe()->delete_solid_model_entities( tmp_curve );
+ intersection_curves.back();
+ intersection_curves.change_to( NULL );
+ intersection_curves.step();
+ }
+ }
+
+ intersection_curves.remove_all_with_value( NULL );
+
+ if( intersection_curves.size() )
+ is_curve_on_surface = true;
+
+ //delete the intersection curves
+ for( j=intersection_curves.size(); j--; )
+ gme->get_gqe()->delete_solid_model_entities( intersection_curves.get_and_step() );
+ }
+
+ //maybe the surface-curve intersection method above didn't work...do
+ //this more primitive method instead
+ if( is_curve_on_surface == false )
+ {
+ double distances_on_curves[3];
+ distances_on_curves[0] = .235;
+ distances_on_curves[1] = .468;
+ distances_on_curves[2] = .894;
+
+ for( j=0; j<3; j++ )
+ {
+ CubitVector position_on_curve;
+ projected_curve->position_from_fraction( distances_on_curves[j],
+ position_on_curve );
+
+ CubitVector closest_point_on_surface;
+ face1->find_closest_point_trimmed( position_on_curve,
+ closest_point_on_surface );
+
+ if( position_on_curve.distance_between( closest_point_on_surface ) < tolerance )
+ {
+ is_curve_on_surface = true;
+ break;
+ }
+ }
+ }
+
+ //delete the projected curve
+ gme->get_gqe()->delete_solid_model_entities( projected_curve );
+
+ if( is_curve_on_surface == false )
+ continue;
+
+ edges_to_imprint_onto_face1.append( edge2 );
+ }
+
+ //a possible force merge situation???
+ if( edges_to_imprint_onto_face1.size() )
+ {
+ //are the number of vertices on both faces the same?
+ if( face1->num_ref_vertices() == face2->num_ref_vertices() &&
+ face1->num_ref_edges() == face2->num_ref_edges() )
+ {
+ double overlapping_area = 0;
+ SurfaceOverlapTool::instance()->check_overlap(
+ face1, face2, CUBIT_FALSE, CUBIT_FALSE, &overlapping_area );
+ double face1_area = face1->area();
+ double face2_area = face2->area();
+
+ //make sure overlapping area is less than 1% of both surface areas
+ double area_diff1 = fabs( overlapping_area - face1_area );
+ double area_diff2 = fabs( overlapping_area - face2_area );
+
+ if( area_diff1 < (face1_area*0.01) &&
+ area_diff2 < (face2_area*0.01) )
+ {
+ if(execute)
+ {
+ MergeTool::instance()->force_merge(face1, face2);
+ }
+ else
+ {
+ CubitString *display_string = new CubitString("Force merge Surface ");
+ *display_string += face1->id();
+ *display_string += " ";
+ *display_string += face2->id();
+ display_strings.append( display_string );
+
+ CubitString *command_string = new CubitString("merge surface ");
+ *command_string += face1->id();
+ *command_string += " ";
+ *command_string += face2->id();
+ *command_string += " force";
+ command_strings.append( command_string );
+
+ preview_strings.append( preview_string );
+ }
+ return;
+ }
+ }
+ }
+
+ //imprint all the edges onto both surfaces in a single command
+ if( edges_to_imprint_onto_face1.size() &&
+ edges_to_imprint_onto_face2.size() )
+ {
+ if(execute)
+ {
+ DLIList<RefFace*> ref_face_list;
+ ref_face_list.append(face1);
+ ref_face_list.append(face2);
+ DLIList<RefEdge*> ref_edge_list;
+ for( i=edges_to_imprint_onto_face2.size(); i--; )
+ ref_edge_list.append(edges_to_imprint_onto_face2.get_and_step());
+ for( i=edges_to_imprint_onto_face1.size(); i--; )
+ ref_edge_list.append(edges_to_imprint_onto_face1.get_and_step());
+ DLIList<Body*> tmp_new_bodies;
+ GeometryModifyTool::instance()->tolerant_imprint( ref_face_list,
+ ref_edge_list,
+ tmp_new_bodies, true );
+ return;
+ }
+ else
+ {
+ CubitString *command_string = new CubitString("Imprint tolerant surface ");
+ *command_string += face1->id();
+ *command_string += " ";
+ *command_string += face2->id();
+ *command_string += " with curve ";
+
+ CubitString *display_string = new CubitString("Imprint with curves ");
+
+ CubitString curve_ids;
+ for( i=edges_to_imprint_onto_face2.size(); i--; )
+ {
+ RefEdge *tmp_edge = edges_to_imprint_onto_face2.get_and_step();
+ curve_ids += tmp_edge->id();
+ curve_ids += " ";
+ }
+ for( i=edges_to_imprint_onto_face1.size(); i--; )
+ {
+ RefEdge *tmp_edge = edges_to_imprint_onto_face1.get_and_step();
+ curve_ids += tmp_edge->id();
+ curve_ids += " ";
+ }
+
+ *display_string += curve_ids;
+ *command_string += curve_ids;
+ *command_string += "merge";
+
+ *preview_string += " &&& highlight curve ";
+ *preview_string += curve_ids;
+
+ display_strings.append( display_string );
+ command_strings.append( command_string );
+ preview_strings.append( preview_string );
+ }
+ }
+ //imprint edges onto a single surface
+ else if( edges_to_imprint_onto_face2.size() )
+ {
+ if(execute)
+ {
+ DLIList<RefFace*> ref_face_list;
+ ref_face_list.append(face2);
+ DLIList<Body*> tmp_new_bodies;
+ GeometryModifyTool::instance()->tolerant_imprint( ref_face_list,
+ edges_to_imprint_onto_face2,
+ tmp_new_bodies, true );
+ return;
+ }
+ else
+ {
+ CubitString *command_string = new CubitString("Imprint tolerant surface ");
+ *command_string += face2->id();
+ *command_string += " with curve ";
+
+ CubitString *display_string = new CubitString("Imprint with curves ");
+ *preview_string += " &&& highlight curve ";
+
+ CubitString curve_ids;
+ for( i=edges_to_imprint_onto_face2.size(); i--; )
+ {
+ RefEdge *tmp_edge = edges_to_imprint_onto_face2.get_and_step();
+ curve_ids += tmp_edge->id();
+ curve_ids += " ";
+ }
+
+ *command_string += curve_ids;
+ *display_string += curve_ids;
+ *preview_string += curve_ids;
+
+ *command_string += " merge";
+
+ display_strings.append( display_string );
+ command_strings.append( command_string );
+ preview_strings.append( preview_string );
+ }
+ }
+ //imprint edges onto a single surface
+ else if( edges_to_imprint_onto_face1.size() )
+ {
+ if(execute)
+ {
+ DLIList<RefFace*> ref_face_list;
+ ref_face_list.append(face1);
+ DLIList<Body*> tmp_new_bodies;
+ GeometryModifyTool::instance()->tolerant_imprint( ref_face_list,
+ edges_to_imprint_onto_face1,
+ tmp_new_bodies, true );
+ return;
+ }
+ else
+ {
+ CubitString *command_string = new CubitString("Imprint tolerant surface ");
+ *command_string += face1->id();
+ *command_string += " with curve ";
+
+ CubitString *display_string = new CubitString("Imprint with curves ");
+ *preview_string += " &&& highlight curve ";
+
+ CubitString curve_ids;
+ for( i=edges_to_imprint_onto_face1.size(); i--; )
+ {
+ RefEdge *tmp_edge = edges_to_imprint_onto_face1.get_and_step();
+ curve_ids += tmp_edge->id();
+ curve_ids += " ";
+ }
+
+ *command_string += curve_ids;
+ *display_string += curve_ids;
+ *preview_string += curve_ids;
+
+ *command_string += " merge";
+
+ display_strings.append( display_string );
+ command_strings.append( command_string );
+ preview_strings.append( preview_string );
+ }
+ }
+
+ //if we came up with some solutions, get out
+ if( display_strings.size() )
+ return;
+ }
+
+ //just suggest some vertex imprints
+ if( positions_to_imprint_onto_face1.size() ||
+ positions_to_imprint_onto_face2.size() )
+ {
+ //Are you possibly generating sliver curves?
+ //Offer a merge force merge instead if topology is identical
+ if( face1->num_ref_vertices() == face2->num_ref_vertices() &&
+ face1->num_ref_edges() == face2->num_ref_edges() )
+ {
+ if((positions_to_imprint_onto_face1.size() &&
+ positions_to_imprint_onto_face1.size() == possible_slivers_on_face1 ) ||
+ (positions_to_imprint_onto_face2.size() &&
+ positions_to_imprint_onto_face2.size() == possible_slivers_on_face2 ))
+ {
+ if(execute)
+ {
+ MergeTool::instance()->force_merge(face1, face2);
+ }
+ else
+ {
+ CubitString *display_string = new CubitString("Force merge Surface ");
+ *display_string += face1->id();
+ *display_string += " ";
+ *display_string += face2->id();
+ display_strings.append( display_string );
+
+ CubitString *command_string = new CubitString("merge surface ");
+ *command_string += face1->id();
+ *command_string += " ";
+ *command_string += face2->id();
+ *command_string += " force";
+ command_strings.append( command_string );
+ }
+
+ return;
+ }
+ }
+
+ CubitString *command_string = NULL;
+ // CubitString *preview_string = NULL;
+ if( positions_to_imprint_onto_face1.size() )
+ {
+ if(execute)
+ {
+ Body *b = face1->body();
+ if(b)
+ {
+ DLIList<Body*> body_list;
+ body_list.append(b);
+ DLIList<Body*> new_bodies;
+ GeometryModifyTool::instance()->imprint( body_list, positions_to_imprint_onto_face1,
+ new_bodies, false, true );
+ while(positions_to_imprint_onto_face1.size())
+ delete positions_to_imprint_onto_face1.pop();
+ }
+ }
+ else
+ {
+ command_string = new CubitString("Imprint volume ");
+ RefVolume *volume1 = face1->ref_volume();
+ *command_string += volume1->id();
+ *command_string += " with";
+ *preview_string += " &&& highlight";
+ for( i=positions_to_imprint_onto_face1.size(); i--; )
+ {
+ //construct the command string
+ *command_string += " position {";
+ CubitVector *tmp_pos = positions_to_imprint_onto_face1.get_and_step();
+ *command_string += CubitString( tmp_pos->x(), 0, 7 );
+ *command_string += "} {";
+ *command_string += CubitString( tmp_pos->y(), 0, 7 );
+ *command_string += "} {";
+ *command_string += CubitString( tmp_pos->z(), 0, 7 );
+ *command_string += "}";
+
+ //construct the preview string
+ *preview_string += " location ";
+ *preview_string += CubitString( tmp_pos->x(), 0, 7 );
+ *preview_string += " ";
+ *preview_string += CubitString( tmp_pos->y(), 0, 7 );
+ *preview_string += " ";
+ *preview_string += CubitString( tmp_pos->z(), 0, 7 );
+ *preview_string += " ";
+
+ delete tmp_pos;
+ }
+ *command_string += " merge";
+ }
+ }
+
+ if( positions_to_imprint_onto_face2.size() )
+ {
+ if(execute)
+ {
+ Body *b = face2->body();
+ if(b)
+ {
+ DLIList<Body*> body_list;
+ body_list.append(b);
+ DLIList<Body*> new_bodies;
+ GeometryModifyTool::instance()->imprint( body_list, positions_to_imprint_onto_face2,
+ new_bodies, false, true );
+ while(positions_to_imprint_onto_face2.size())
+ delete positions_to_imprint_onto_face2.pop();
+ }
+ }
+ else
+ {
+ if( command_string == NULL )
+ command_string = new CubitString("Imprint volume ");
+ else
+ *command_string += " &&& Imprint volume ";
+
+ if( positions_to_imprint_onto_face1.size() == 0 )
+ *preview_string += " &&& highlight";
+
+ RefVolume *volume2 = face2->ref_volume();
+ *command_string += volume2->id();
+ *command_string += " with";
+ for( i=positions_to_imprint_onto_face2.size(); i--; )
+ {
+ *command_string += " position {";
+ CubitVector *tmp_pos = positions_to_imprint_onto_face2.get_and_step();
+
+ *command_string += CubitString( tmp_pos->x(), 0, 7 );
+ *command_string += "} {";
+ *command_string += CubitString( tmp_pos->y(), 0, 7 );
+ *command_string += "} {";
+ *command_string += CubitString( tmp_pos->z(), 0, 7 );
+ *command_string += "}";
+
+ //construct the preview string
+ *preview_string += " location ";
+ *preview_string += CubitString( tmp_pos->x(), 0, 7 );
+ *preview_string += " ";
+ *preview_string += CubitString( tmp_pos->y(), 0, 7 );
+ *preview_string += " ";
+ *preview_string += CubitString( tmp_pos->z(), 0, 7 );
+ *preview_string += " ";
+
+ delete tmp_pos;
+ }
+ *command_string += " merge";
+ }
+ }
+
+ if(!execute)
+ {
+ command_strings.append( command_string );
+ preview_strings.append( preview_string );
+
+ //create the display string
+ CubitString *display_string = new CubitString("Imprint with positions" );
+ display_strings.append( display_string );
+ }
+ }
+
+ return;
+}
+
+
Modified: cgm/branches/cubit/geom/MergeTool.hpp
===================================================================
--- cgm/branches/cubit/geom/MergeTool.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/MergeTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -71,284 +71,350 @@
~MergeTool();
//- Destructor.
+
+ static void delete_instance() {if(instance_) delete instance_; }
- CubitBoolean contains_merged_entities( DLIList<Body*> &bodies );
- //- Tests the entities in the list of bodies to see if they
- //- have been merged with other entities and result in
- //- of multiple volumes. This returns CUBIT_TRUE at the first
- //- lower entity that shares two volumes.
-
+ void imprint_merge_solutions_for_overlapping_surfaces(
+ RefFace *face1,
+ RefFace *face2,
+ bool execute,
+ DLIList<CubitString*> &display_strings,
+ DLIList<CubitString*> &command_strings,
+ DLIList<CubitString*> &preview_strings );
+
+ void merge_with_auto_imprint(RefFace *surf1, RefFace *surf2);
+
+ //! Tests the entities in the list of bodies to see if they
+ //! have been merged with other entities and result in
+ //! of multiple volumes. This returns CUBIT_TRUE at the first
+ //! lower entity that shares two volumes.
+ CubitBoolean contains_merged_entities( DLIList<Body*> &bodies );
+
+ //! Determines if the specified body conatins child entities that are merged.
CubitBoolean contains_merged_children( Body *body,
DLIList<RefEntity*> &merged_children );
-
- CubitBoolean contains_merged_entities( DLIList<RefEntity*> &ref_entities);
- //- Tests the entities in the list to see if they or their descendents
- //- have been merged with other entities
+ //! Tests the entities in the list to see if they or their descendents
+ //! have been merged with other entities
+ //! If merged_ref_ents is not NULL, fill it will all the merged ref entities.
+ CubitBoolean contains_merged_entities( DLIList<RefEntity*> &ref_entities,
+ DLIList<RefEntity*> *merged_ref_ents = NULL );
+ //! Tests the entities in the list to see if their ANY children of ancestors
+ //! have been merged with other entities
CubitBoolean parents_contain_merged_entities( DLIList<RefEntity*> &ref_entities);
- //- Tests the entities in the list to see if their ANY children of ancestors
- //- have been merged with other entities
- CubitBoolean entity_merged( TopologyEntity *entity );
- //- Takes a RefEntity, makes sure it is not a volume, and
- //- checks to see if it has more than one volume.
+ //! Takes a RefEntity, makes sure it is not a volume, and
+ //! checks to see if it has more than one volume.
+ CubitBoolean entity_merged( TopologyEntity *entity );
- CubitStatus merge_all_bodies();
- //- Compare all RefFaces, RefEdges, and RefVertices in the
- //- model and merge the matches
+ //! Compare all RefFaces, RefEdges, and RefVertices in the
+ //! model and merge the matches
+ CubitStatus merge_all_bodies();
- CubitStatus merge_bodies( DLIList<Body*>& refbody_list );
- //- Compare all RefFaces, RefEdges, and RefVertices in
- //- refbody_list and merge the matches
+ //! Compare all RefFaces, RefEdges, and RefVertices in
+ //! refbody_list and merge the matches
+ CubitStatus merge_bodies( DLIList<Body*>& refbody_list );
- CubitStatus merge_volumes( DLIList<RefVolume*>& vol_list,
- CubitBoolean print_info = CUBIT_TRUE );
- //- Compare all RefFaces, RefEdges, and RefVertices in
- //- vol_list and merge the matches
+ //! Compare all RefFaces, RefEdges, and RefVertices in
+ //! vol_list and merge the matches
+ CubitStatus merge_volumes( DLIList<RefVolume*>& vol_list,
+ CubitBoolean print_info = CUBIT_TRUE );
- CubitStatus merge_all_reffaces ();
- //- Compare all RefFaces in the model and merge the matches
+ //! Compare all RefFaces in the model and merge the matches.
+ CubitStatus merge_all_reffaces();
- CubitStatus merge_reffaces_old( DLIList<RefFace*>& refface_list,
+ //! Compare all input RefFaces and merge the matches.
+ CubitStatus merge_reffaces_old( DLIList<RefFace*>& refface_list,
CubitBoolean print_info = CUBIT_TRUE);
- //- Compare all input RefFaces and merge the matches
- CubitStatus merge_reffaces( DLIList<RefFace*>& refface_list,
+ //! Compare all input RefFaces and merge the matches.
+ //! Uses AbstractTree rather than O(nlogn) comparisons.
+ CubitStatus merge_reffaces( DLIList<RefFace*>& refface_list,
CubitBoolean print_info = CUBIT_TRUE);
- //- Compare all input RefFaces and merge the matches
- //- Uses AbstractTree rather than O(nlogn) comparisons.
- CubitStatus merge_all_refedges();
- //- Compare all RefEdges in the model and merge the matches
-
- CubitStatus old_merge_refedges( DLIList<RefEdge*>& refedge_list,
+ //! Compare all RefEdges in the model and merge the matches.
+ CubitStatus merge_all_refedges();
+
+ //! Merges specified curves. List should contains max 20 curves.
+ CubitStatus old_merge_refedges( DLIList<RefEdge*>& refedge_list,
CubitBoolean should_clean_out = CUBIT_TRUE,
CubitBoolean print_info = CUBIT_TRUE);
- CubitStatus merge_refedges( DLIList<RefEdge*>& refedge_list,
+
+ //! Compare all input RefEdges and merge the matches
+ //! BE CAREFUL with the should_clean_out flag. If you set
+ //! it to false, then YOU (the caller) are responsible for
+ //! cleaning out the deactivated geometry.
+ //! Merges specified curves. If list contains < 20 curves, use old_merge_ref_edges.
+ CubitStatus merge_refedges( DLIList<RefEdge*>& refedge_list,
CubitBoolean should_clean_out = CUBIT_TRUE,
CubitBoolean print_info = CUBIT_TRUE);
- //- Compare all input RefEdges and merge the matches
- //- BE CAREFUL with the should_clean_out flag. If you set
- //- it to false, then YOU (the caller) are responsible for
- //- cleaning out the deactivated geometry.
- CubitStatus merge_all_refvertices();
- //- Compare all RefVertices in the model and merge the matches
+ //! Compare all RefVertices in the model and merge the matches
+ CubitStatus merge_all_refvertices();
+
+ //! Compare all input RefVertices and merge the matches. For lists < 20
+ CubitStatus old_merge_refvertices( DLIList<RefVertex*>& refvertex_list,
+ CubitBoolean print_info = CUBIT_TRUE );
+
+ //! Compare all input RefVertices and merge the matches.
+ CubitStatus merge_refvertices( DLIList<RefVertex*>& refvertex_list,
+ CubitBoolean print_info = CUBIT_TRUE );
- CubitStatus old_merge_refvertices( DLIList<RefVertex*>& refvertex_list,
- CubitBoolean print_info = CUBIT_TRUE );
- CubitStatus merge_refvertices( DLIList<RefVertex*>& refvertex_list,
- CubitBoolean print_info = CUBIT_TRUE );
- //- Compare all input RefVertices and merge the matches
-
- CubitStatus merge_entities( DLIList<RefEntity*>& entity_list,
+ //! merge the entities in list; asserts if they're not all the same type
+ CubitStatus merge_entities( DLIList<RefEntity*>& entity_list,
CubitBoolean should_clean_out = CUBIT_TRUE,
CubitBoolean print_info = CUBIT_TRUE);
- //- merge the entities in list; asserts if they're not all the same type
- CubitStatus unmerge_all();
- //- Unmerge everything.
+ //! Unmerge everything.
+ CubitStatus unmerge_all();
- CubitStatus
- unmerge( DLIList<RefEntity*>& entity_list, CubitBoolean descend = CUBIT_TRUE );
- //- Unmerge entities in list.
- //- If decend is true, will decend topology graph, unmerging child topology
- //- of the passed topology. If decend is false, a.) passing bodies or volumes
- //- in entity list will have no effect and b.) when a surface is unmerged
- //- its child curves will not be unmerged, and the child vertices will not be
- //- unmerged when an edge is unmerged.
+ //! Unmerge entities in list.
+ //! If decend is true, will decend topology graph, unmerging child topology
+ //! of the passed topology. If decend is false, a.) passing bodies or volumes
+ //! in entity list will have no effect and b.) when a surface is unmerged
+ //! its child curves will not be unmerged, and the child vertices will not be
+ //! unmerged when an edge is unmerged.
+ CubitStatus unmerge( DLIList<RefEntity*>& entity_list, CubitBoolean descend = CUBIT_TRUE );
+
+ //@{
+ //! Unmerge the passed entity. All parents must already be
+ //! unmerged.
+ //! If decend is true, will decend topology graph, unmerging child topology
+ //! of the passed topology. If decend is false, a.) passing bodies or volumes
+ //! in entity list will have no effect and b.) when a surface is unmerged
+ //! its child curves will not be unmerged, and the child vertices will not be
+ //! unmerged when an edge is unmerged.
+ CubitStatus unmerge( RefEntity* entity_ptr, CubitBoolean descend = CUBIT_TRUE );
+ CubitStatus unmerge( RefFace* face_ptr, CubitBoolean descend = CUBIT_TRUE );
+ CubitStatus unmerge( RefEdge* edge_ptr, CubitBoolean descend = CUBIT_TRUE );
+ CubitStatus unmerge( Body* body_ptr );
+ CubitStatus unmerge( RefVolume* vol_ptr );
+ CubitStatus unmerge( RefVertex* vertex_ptr );
+ //@}
- CubitStatus unmerge( RefEntity* entity_ptr, CubitBoolean descend = CUBIT_TRUE );
- CubitStatus unmerge( RefFace* face_ptr, CubitBoolean descend = CUBIT_TRUE );
- CubitStatus unmerge( RefEdge* edge_ptr, CubitBoolean descend = CUBIT_TRUE );
- CubitStatus unmerge( Body* body_ptr );
- CubitStatus unmerge( RefVolume* vol_ptr );
- CubitStatus unmerge( RefVertex* vertex_ptr );
- //- Unmerge the passed entity. All parents must already be
- //- unmerged.
- //- If decend is true, will decend topology graph, unmerging child topology
- //- of the passed topology. If decend is false, a.) passing bodies or volumes
- //- in entity list will have no effect and b.) when a surface is unmerged
- //- its child curves will not be unmerged, and the child vertices will not be
- //- unmerged when an edge is unmerged.
+ //! Return number of entities unmerged in last call to one
+ //! of the unmerge methods. If an entity list is passed,
+ //! it will be populated with unmerged entities.
+ int unmerged_entities( DLIList<RefEntity*>* entities = NULL ) const;
- int unmerged_entities( DLIList<RefEntity*>* entities = NULL ) const;
- //- Return number of entities unmerged in last call to one
- //- of the unmerge methods. If an entity list is passed,
- //- it will be populated with unmerged entities.
-
- CubitStatus separate_bodies( DLIList<Body*>& separate_list,
+ //! Unmerge such that the group of entities in
+ //! separate_list share no topology with the entities
+ //! in from_list, or if from_list is is null, any other
+ //! entities.
+ CubitStatus separate_bodies( DLIList<Body*>& separate_list,
DLIList<Body*>* from_list = NULL );
- //- Unmerge such that the group of entities in
- //- separate_list share no topology with the entities
- //- in from_list, or if from_list is is null, any other
- //- entities.
-
- CubitStatus separate_volumes( DLIList<RefVolume*>& separate_list,
- DLIList<RefVolume*>* from_list = NULL );
- //- Unmerge such that the group of entities in
- //- separate_list share no topology with the entities
- //- in from_list, or if from_list is is null, any other
- //- entities.
-
- CubitStatus separate_faces( DLIList<RefFace*>& separate_list,
- DLIList<RefFace*>* from_list = NULL );
- //- Unmerge such that the group of entities in
- //- separate_list share no topology with the entities
- //- in from_list, or if from_list is is null, any other
- //- entities.
- CubitStatus separate_edges( DLIList<RefEdge*>& separate_list,
- DLIList<RefEdge*>* from_list = NULL );
- //- Unmerge such that the group of entities in
- //- separate_list share no topology with the entities
- //- in from_list, or if from_list is is null, any other
- //- entities.
-
- RefFace* force_merge( RefFace* face1, RefFace* face2 );
- RefEdge* force_merge( RefEdge* edge1, RefEdge* edge2 );
- RefVertex* force_merge( RefVertex* vtx1, RefVertex* vtx2 );
- RefEntity* force_merge( RefEntity* ent1, RefEntity* ent2 );
- RefEntity* force_merge( const DLIList<RefEntity*>& list );
-
- static CubitBoolean merge_has_occured();
- static void set_merge_occurance( CubitBoolean t_or_f );
- //- Sets/Gets the mergeCalled flag. This signifies
- //- that currently a merge operation has been called for
- //- the model.
+ //@{
+ //! Unmerge such that the group of entities in
+ //! separate_list share no topology with the entities
+ //! in from_list, or if from_list is is null, any other
+ //! entities.
+ CubitStatus separate_volumes( DLIList<RefVolume*>& separate_list,
+ DLIList<RefVolume*>* from_list = NULL );
+ //@}
+
+ //@{
+ //! Unmerge such that the group of entities in
+ //! separate_list share no topology with the entities
+ //! in from_list, or if from_list is is null, any other
+ //! entities.
+ CubitStatus separate_faces( DLIList<RefFace*>& separate_list,
+ DLIList<RefFace*>* from_list = NULL );
+ //@}
+
+ //@{
+ //! Unmerge such that the group of entities in
+ //! separate_list share no topology with the entities
+ //! in from_list, or if from_list is is null, any other
+ //! entities.
+ CubitStatus separate_edges( DLIList<RefEdge*>& separate_list,
+ DLIList<RefEdge*>* from_list = NULL );
+ //@}
+
+ //@{
+ //! Force the merging of entities.
+ //! Entities must have like topology though, i.e,
+ //! two surfaces must have the same number of vertices and curves.
+ RefFace* force_merge( RefFace* face1, RefFace* face2 );
+ RefEdge* force_merge( RefEdge* edge1, RefEdge* edge2 );
+ RefVertex* force_merge( RefVertex* vtx1, RefVertex* vtx2 );
+ RefEntity* force_merge( RefEntity* ent1, RefEntity* ent2 );
+ RefEntity* force_merge( const DLIList<RefEntity*>& list );
+
+ //@{
+ //! Sets/Gets the mergeCalled flag. This signifies
+ //! that currently a merge operation has been called for
+ //! the model.
+ static CubitBoolean merge_has_occured();
+ static void set_merge_occurance( CubitBoolean t_or_f );
+ //@}
- static void group_results( CubitBoolean t_or_f );
- //- tells us to group the results or not.
-
- static void set_new_ids_on_unmerge( CubitBoolean value );
- static CubitBoolean get_new_ids_on_unmerge();
-
- static void initialize_settings();
+ //! Tells us to group the results or not.
+ static void group_results( CubitBoolean t_or_f );
+ //@{
+ //! Get/Sets flag for producing new ids when unmerging.
+ static void set_new_ids_on_unmerge( CubitBoolean value );
+ static CubitBoolean get_new_ids_on_unmerge();
+ //@}
+
+ //! Resets all member variables in this calls to defaults.
+ static void initialize_settings();
+
+ //! Notifies MergeTool about comparisons found and put on ref entities
void compare_notify(RefEntity *entity, CubitEventType event);
- //- notifies MergeTool about comparisons found and put on ref entities
+ //! Remove TDCompares from RefEntities.
void remove_compare_data();
- //- Remove TDCompares from RefEntities.
- void add_merge_tool_assistant( MergeToolAssistant* mta_ptr );
- void remove_merge_tool_assistant( MergeToolAssistant* mta_ptr );
- MergeToolAssistant* find_merge_tool_assistant( const type_info& type );
+ void add_merge_tool_assistant( MergeToolAssistant* mta_ptr );
+ void remove_merge_tool_assistant( MergeToolAssistant* mta_ptr );
+ MergeToolAssistant* find_merge_tool_assistant( const type_info& type );
static void destroy_dead_geometry( CubitBoolean yes_no )
{ destroyDeadGeometry = yes_no; }
+ //! This function is to be used only right
+ //! after merging is called. It is a way to
+ //! access the groups that are created during the
+ //! merge. Note the groups can be destroyed
+ //! and these pointers can be stale if the
+ //! function is not called immediatly following merging...
RefGroup* get_group_last_merged_surfs()
- {
- //clear this out once this function has been called.
- RefGroup *temp = lastSurfsMerged;
- lastSurfsMerged = NULL;
- return temp;
- }
- ///
- /// This function is to be used only right
- /// after merging is called. It is a way to
- /// access the groups that are created during the
- /// merge. Note the groups can be destroyed
- /// and these pointers can be stale if the
- /// function is not called immediatly following merging...
- ///
+ {
+ //clear this out once this function has been called.
+ RefGroup *temp = lastSurfsMerged;
+ lastSurfsMerged = NULL;
+ return temp;
+ }
+
+
+ //! This function is to be used only right
+ //! after merging is called. It is a way to
+ //! access the groups that are created during the
+ //! merge. Note the groups can be destroyed
+ //! and these pointers can be stale if the
+ //! function is not called immediatly following merging...
RefGroup* get_group_last_merged_curvs()
- {
- //clear this out once this function has been called.
- RefGroup *temp = lastCurvsMerged;
- lastCurvsMerged = NULL;
- return temp;
- }
- ///
- /// This function is to be used only right
- /// after merging is called. It is a way to
- /// access the groups that are created during the
- /// merge. Note the groups can be destroyed
- /// and these pointers can be stale if the
- /// function is not called immediatly following merging...
- ///
+ {
+ //clear this out once this function has been called.
+ RefGroup *temp = lastCurvsMerged;
+ lastCurvsMerged = NULL;
+ return temp;
+ }
+
+ //! This function is to be used only right
+ //! after merging is called. It is a way to
+ //! access the groups that are created during the
+ //! merge. Note the groups can be destroyed
+ //! and these pointers can be stale if the
+ //! function is not called immediatly following merging...
RefGroup* get_group_last_merged_verts()
- {
- //clear this out once this function has been called.
- RefGroup *temp = lastVertsMerged;
- lastVertsMerged = NULL;
- return temp;
- }
- ///
- /// This function is to be used only right
- /// after merging is called. It is a way to
- /// access the groups that are created during the
- /// merge. Note the groups can be destroyed
- /// and these pointers can be stale if the
- /// function is not called immediatly following merging...
- ///
+ {
+ //clear this out once this function has been called.
+ RefGroup *temp = lastVertsMerged;
+ lastVertsMerged = NULL;
+ return temp;
+ }
- //Note: The caller of the following 4 functions is responsible to
- //delete the DLIList*s that are returned.
- CubitStatus find_mergeable_refentities( DLIList<RefEntity*> &entities,
+
+ //! From the specified list of entities, find mergeable surfaces, curves,
+ //! and vertices. If two surfaces are found to be mergeable, their mergeable
+ //! children, i.e, curves and vertices, are not included reported.
+ //! Note: The caller of the following 4 functions is responsible to
+ //! delete the DLIList*s that are returned.
+ CubitStatus find_mergeable_refentities( DLIList<RefEntity*> &entities,
DLIList< DLIList<RefFace*>*> &lists_of_mergeable_ref_faces,
DLIList< DLIList<RefEdge*>*> &lists_of_mergeable_ref_edges,
DLIList< DLIList<RefVertex*>*> &lists_of_mergeable_ref_vertices);
- CubitStatus find_mergeable_reffaces( DLIList<RefEntity*> &entities,
+
+ //! From the specified list of entities, find mergeable surfaces.
+ //! Note: The caller of this function responsible for
+ //! deleting the DLIList*s that are returned.
+ CubitStatus find_mergeable_reffaces( DLIList<RefEntity*> &entities,
DLIList< DLIList<RefFace*>*> &lists_of_mergeable_ref_faces,
bool clean_up_compare_data = true );
- CubitStatus find_mergeable_refedges( DLIList<RefEntity*> &entities,
+
+ //! From the specified list of entities, find mergeable curves.
+ //! Note: The caller of this function responsible for
+ //! deleting the DLIList*s that are returned.
+ CubitStatus find_mergeable_refedges( DLIList<RefEntity*> &entities,
DLIList< DLIList<RefEdge*>*> &lists_of_mergeable_ref_edges,
bool clean_up_compare_data = true );
- CubitStatus find_mergeable_refvertices( DLIList<RefEntity*> &entities,
+
+ //! From the specified list of entities, find mergeable vertices.
+ //! Note: The caller of this function responsible for
+ //! deleting the DLIList*s that are returned.
+ CubitStatus find_mergeable_refvertices( DLIList<RefEntity*> &entities,
DLIList< DLIList<RefVertex*>*> &lists_of_mergeable_ref_vertices,
bool clean_up_compare_data = true );
- //Faster comparison that only check for mergeable refedges between volumes.
- //It reports all edges, even when the owning face is mergeable
- CubitStatus find_only_mergeable_curves( DLIList<BodySM*> &body_list,
- DLIList< DLIList<Curve*>*> &lists_of_mergeable_curves );
+
+ //@{
+ //! Faster comparison that only checks for mergeable RefEdge
+ //! or curves between bodies, surfaces, or curves.
+ //! It reports all edges, even if the owning faces are mergeable
+ CubitStatus find_only_mergeable_curves( DLIList<Surface*> &surf_list,
+ DLIList< DLIList<Curve*>*> &lists_of_mergeable_curves );
+ CubitStatus find_only_mergeable_curves( DLIList<Curve*> &all_curves,
+ DLIList< DLIList<Curve*>*> &lists_of_mergeable_curves );
+ CubitStatus find_only_mergeable_curves( DLIList<BodySM*> &body_list,
+ DLIList< DLIList<Curve*>*> &lists_of_mergeable_curves );
+ CubitStatus find_only_mergeable_refedges( DLIList<Body*> &body_list,
+ DLIList< DLIList<RefEdge*>*> &lists_of_mergeable_ref_edges );
+ //@}
- CubitStatus find_only_mergeable_surfaces( DLIList<BodySM*> &body_list,
- DLIList< DLIList<Surface*>*> &lists_of_mergeable_surfaces);
+ //! Faster comparison that only checks for mergeable surfaces.
+ CubitStatus find_only_mergeable_surfaces( DLIList<BodySM*> &body_list,
+ DLIList< DLIList<Surface*>*> &lists_of_mergeable_surfaces);
- CubitStatus find_only_mergeable_refedges( DLIList<Body*> &body_list,
- DLIList< DLIList<RefEdge*>*> &lists_of_mergeable_ref_edges );
-
- CubitBoolean about_spatially_equal( Surface *surf_1, Surface *surf_2,
- double tolerance_factor );
- CubitBoolean about_spatially_equal( LoopSM *loop_1, LoopSM *loop_2,
- CubitSense relative_sense, double tolerance_factor );
- CubitBoolean about_spatially_equal( CoEdgeSM *coedge_1, CoEdgeSM *coedge_2,
- CubitSense relative_sense, double tolerance_factor );
- CubitBoolean about_spatially_equal( Curve *curve_1, Curve *curve_2,
- CubitSense &relative_sense, double tolerance_factor );
- CubitBoolean about_spatially_equal( Point *point_1, Point *point_2,
- double tolerance_factor );
+ //! Check for mergeability of two surfaces.
+ CubitBoolean about_spatially_equal( Surface *surf_1, Surface *surf_2,
+ double tolerance_factor );
+
+ //! Check for mergeability of two loops.
+ CubitBoolean about_spatially_equal( LoopSM *loop_1, LoopSM *loop_2,
+ CubitSense relative_sense, double tolerance_factor );
+
+ //! Check for mergeability of two coedges.
+ CubitBoolean about_spatially_equal( CoEdgeSM *coedge_1, CoEdgeSM *coedge_2,
+ CubitSense relative_sense, double tolerance_factor );
+
+ //! Check for mergeability of two curves.
+ CubitBoolean about_spatially_equal( Curve *curve_1, Curve *curve_2,
+ CubitSense &relative_sense, double tolerance_factor );
+
+ //! Check for mergeability of two points.
+ CubitBoolean about_spatially_equal( Point *point_1, Point *point_2,
+ double tolerance_factor );
- protected :
+ protected :
- CubitStatus separate_entities( DLIList<TopologyEntity*>& separate_list,
- DLIList<TopologyEntity*>* from_list = NULL );
- //- Common implementation for public separate() functions.
- //- All passed entities must be of the same type.
- //- Unmerge such that the group of entities in
- //- separate_list share no topology with the entities
- //- in from_list, or if from_list is is null, any other
- //- entities.
-
- BasicTopologyEntity* can_separate( DLIList<TopologyBridge*>& bridge_list,
- bool check_parents );
- //- Check if the passed list of bridges can be unmerged and if
- //- so, return their owning BTE. If check_parents is false, skip
- //- check for merged parents.
+ //! Common implementation for public separate() functions.
+ //! All passed entities must be of the same type.
+ //! Unmerge such that the group of entities in
+ //! separate_list share no topology with the entities
+ //! in from_list, or if from_list is is null, any other
+ //! entities.
+ CubitStatus separate_entities( DLIList<TopologyEntity*>& separate_list,
+ DLIList<TopologyEntity*>* from_list = NULL );
+
+ //! Check if the passed list of bridges can be unmerged and if
+ //! so, return their owning BTE. If check_parents is false, skip
+ //! check for merged parents.
+ BasicTopologyEntity* can_separate( DLIList<TopologyBridge*>& bridge_list,
+ bool check_parents );
- RefFace* separate_face( DLIList<Surface*>& bridges, bool descend );
- //- Split a merged entity into two such that the returned, new
- //- entity contains the passed list of bridges. If descend
- //- is false, skip attempt to unmerge child entities.
+ //! Split a merged entity into two such that the returned, new
+ //! entity contains the passed list of bridges. If descend
+ //! is false, skip attempt to unmerge child entities.
+ RefFace* separate_face( DLIList<Surface*>& bridges, bool descend );
- RefEdge* separate_edge( DLIList<Curve*>& bridges, bool descend );
- //- Split a merged entity into two such that the returned, new
- //- entity contains the passed list of bridges. If descend
- //- is false, skip attempt to unmerge child entities.
+ //! Split a merged entity into two such that the returned, new
+ //! entity contains the passed list of bridges. If descend
+ //! is false, skip attempt to unmerge child entities.
+ RefEdge* separate_edge( DLIList<Curve*>& bridges, bool descend );
RefVertex* separate_vertex( DLIList<Point*>& bridges );
//- Split a merged entity into two such that the returned, new
Modified: cgm/branches/cubit/geom/ModelQueryEngine.hpp
===================================================================
--- cgm/branches/cubit/geom/ModelQueryEngine.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/ModelQueryEngine.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -89,6 +89,8 @@
~ModelQueryEngine() ;
//- Destructor
+ static void delete_instance() {if(instance_) delete instance_; }
+
//HEADER- Query functions on single source objects
CubitStatus query_model( ModelEntity & source_object,
Modified: cgm/branches/cubit/geom/OffsetSplitTool.cpp
===================================================================
--- cgm/branches/cubit/geom/OffsetSplitTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/OffsetSplitTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -23,7 +23,7 @@
#include "GeometryQueryTool.hpp"
#include "CubitUtil.hpp"
#include "DLIList.hpp"
-#include "GfxDebug.hpp"
+#include "GfxPreview.hpp"
#include "GMem.hpp"
#include "Curve.hpp"
#include "BodySM.hpp"
@@ -61,17 +61,20 @@
if(ref_face_list.size() < 1)
{
PRINT_ERROR( "No surfaces specified for splitting\n" );
- return CUBIT_FAILURE;
- }
+ return CUBIT_FAILURE;
+ }
- if(edge_list.size() < 1)
- {
- PRINT_ERROR( "No curves specified for splitting\n" );
- return CUBIT_FAILURE;
- }
+ if(edge_list.size() < 1)
+ {
+ PRINT_ERROR( "No curves specified for splitting\n" );
+ return CUBIT_FAILURE;
+ }
- DLIList<Curve*> offset_curves;
- DLIList<DLIList<Curve*>*> imprint_list;
+ // clear the preview graphics
+ GfxPreview::clear();
+
+ DLIList<Curve*> offset_curves;
+ DLIList<DLIList<Curve*>*> imprint_list;
for(int seg = 1;seg<num_segs+1;seg++)
{
// set the current distance
@@ -201,9 +204,6 @@
united_body_list = body_list;
else
{
-#ifdef BOYD17
- BodySM* return_body = 0;
-#endif
if(!gme->unite(body_list,united_body_list))//united_body_list))
{
if(body_list.size() == 1)
@@ -241,9 +241,9 @@
// remove any very small curves from the intersection graph
// for some reason ACIS seems to return zero length curves
- for(int k=0;k<intersection_curves.size();k++)
+ for(int k = intersection_curves.size();k--;)
{
- Curve* cur_curve = intersection_curves.get_and_step();
+ Curve* cur_curve = intersection_curves[k];
double len = cur_curve->
length_from_u(cur_curve->start_param(),cur_curve->end_param());
@@ -323,7 +323,7 @@
Body *new_body_ptr;
if( GeometryModifyTool::instance()->imprint( surface_list,
- imprint_list, new_body_ptr ) == CUBIT_FAILURE )
+ imprint_list, new_body_ptr, false, false ) == CUBIT_FAILURE )
{
//Delete the Curve entities
for(i= offset_curves.size();i--;)
@@ -370,7 +370,7 @@
draw_preview( curve_ptr, CUBIT_FALSE, color );
}
- GfxDebug::flush();
+ GfxPreview::flush();
return CUBIT_SUCCESS;
}
@@ -380,23 +380,26 @@
CubitBoolean flush,
int color )
{
- int num_points;
CubitStatus result;
GMem g_mem;
// get the graphics
result = curve_ptr->get_geometry_query_engine()->
- get_graphics( curve_ptr, num_points, &g_mem );
+ get_graphics( curve_ptr, &g_mem );
- if (result==CUBIT_FAILURE || num_points == 0)
+ if (result==CUBIT_FAILURE || g_mem.pointListCount == 0)
{
- PRINT_WARNING("Unable to preview a curve\n" );
+ PRINT_WARNING("Unable to preview a curve\n" );;
+ double len = curve_ptr->
+ length_from_u(curve_ptr->start_param(),curve_ptr->end_param());
+
+ PRINT_WARNING("Curve len: %f\n",len);
}
// Draw the polyline
- GfxDebug::draw_polyline( g_mem.point_list(), g_mem.pointListCount, color );
+ GfxPreview::draw_polyline( g_mem.point_list(), g_mem.pointListCount, color );
if( flush )
- GfxDebug::flush();
+ GfxPreview::flush();
return CUBIT_SUCCESS;
}
Added: cgm/branches/cubit/geom/PeriodicParamTool.cpp
===================================================================
--- cgm/branches/cubit/geom/PeriodicParamTool.cpp (rev 0)
+++ cgm/branches/cubit/geom/PeriodicParamTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,153 @@
+//- Class: PeriodicParamTool
+//-------------------------------------------------------------------------
+// Filename : PeriodicParamTool.cpp
+//
+// Purpose : Handles surfaces that have a periodic parameterization
+// Uses, but modifies, the underlying engine parameterization
+//
+//
+// Creator : Ray J. Meyers
+//
+// Creation Date : 12/15/2008
+//
+// Owner : Ray J. Meyers
+//-------------------------------------------------------------------------
+
+#include "PeriodicParamTool.hpp"
+//#include "CastTo.hpp"
+#include "Surface.hpp"
+//#include "DLIList.hpp"
+
+//-------------------------------------------------------------------------
+// Function: PeriodicParamTool
+// Description: constructor
+// Author: chynes
+// Date: 7/10/2002
+//-------------------------------------------------------------------------
+PeriodicParamTool::PeriodicParamTool(Surface *surf)
+{
+ //- update private variables
+ refSurf = surf;
+ uOffset = 0.0;
+ vOffset = 0.0;
+ uPeriod = 0.0;
+ vPeriod = 0.0;
+ mirrorSurface = false;
+
+}
+
+//-------------------------------------------------------------------------
+// Function: PeriodicParamTool
+// Description: deconstructor
+// Author: chynes
+// Date: 7/10/2002
+//-------------------------------------------------------------------------
+PeriodicParamTool::~PeriodicParamTool() {}
+
+//===================================================================================
+// Function: set_up_space (Public)
+// Description: sets up space of flattening
+// Author: chynes
+// Date: 7/10/02
+//===================================================================================
+CubitStatus PeriodicParamTool::set_up_space(double u_period, double v_period, double u_offset, double v_offset)
+{
+ // store the u and periods
+
+ uPeriod = u_period;
+ vPeriod = v_period;
+ uOffset = u_offset;
+ vOffset = v_offset;
+
+
+ CubitStatus rv = CUBIT_SUCCESS;
+
+ return rv;
+}
+
+//===================================================================================
+// Function: transform_to_uv (Public)
+// Description: same as title, the local sizing will be returned in the z coord
+// Author: chynes
+// Date: 7/10/02
+//===================================================================================
+CubitStatus PeriodicParamTool::transform_to_uv(const CubitVector &xyz_location, CubitVector &uv_location)
+{
+
+ double u,v;
+
+ CubitStatus rv = refSurf->u_v_from_position(xyz_location, u, v);
+
+ // offset values to avoid parameter discontinuity
+
+ if (uPeriod && u < uOffset)
+ {
+ u += uPeriod;
+ }
+
+ // mirror surface if required to get correct loop orientation
+ if (mirrorSurface)
+ {
+ u = -u;
+ }
+
+ if (vPeriod && v < vOffset)
+ {
+ v += vPeriod;
+ }
+
+ uv_location.set(u,v,1.0);
+
+
+ return rv;
+}
+
+//===================================================================================
+// Function: transform_to_xyz (Public)
+// Description: same as title
+// Author: chynes
+// Date: 7/10/02
+//===================================================================================
+CubitStatus PeriodicParamTool::transform_to_xyz(CubitVector &xyz_location, const CubitVector &uv_location)
+{
+ double u = uv_location.x();
+ if (mirrorSurface)
+ {
+ u = -u;
+ }
+ if (u > uPeriod)
+ {
+ u = u - uPeriod;
+ }
+ double v = uv_location.y();
+ if (v > vPeriod)
+ {
+ v = v - vPeriod;
+ }
+ xyz_location = refSurf->position_from_u_v(u,v);
+
+
+ return CUBIT_SUCCESS;
+}
+
+void PeriodicParamTool::mirror_surface(bool true_false)
+{
+ mirrorSurface = true_false;
+ if (mirrorSurface)
+ PRINT_INFO("Loops appear backwards, mirroring surface...\n");
+
+}
+
+CubitStatus PeriodicParamTool::uv_derivitives(double u_param, double v_param,
+ CubitVector &du, CubitVector &dv)
+{
+ if (mirrorSurface)
+ u_param = -u_param;
+ if (u_param > uPeriod)
+ u_param = u_param-uPeriod;
+ if (v_param > vPeriod)
+ v_param = v_param-vPeriod;
+ refSurf->uv_derivitives(u_param, v_param, du, dv);
+ return CUBIT_SUCCESS;
+}
+//EOF
Added: cgm/branches/cubit/geom/PeriodicParamTool.hpp
===================================================================
--- cgm/branches/cubit/geom/PeriodicParamTool.hpp (rev 0)
+++ cgm/branches/cubit/geom/PeriodicParamTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,60 @@
+//- Class: PeriodicParamTool
+//-------------------------------------------------------------------------
+// Filename : PeriodicParamTool.cpp
+//
+// Purpose : Handles surfaces that have a periodic parameterization
+// Uses, but modifies, the underlying engine parameterization
+//
+// Creator : Ray J. Meyers
+//
+// Creation Date : 12/15/2008
+//
+// Owner : Ray J. Meyers
+//-------------------------------------------------------------------------
+
+#ifndef PERIODIC_PARAM_TOOL_HPP
+#define PERIODIC_PARAM_TOOL_HPP
+
+#include "ParamTool.hpp"
+#include "CubitGeomConfigure.h"
+
+class Surface;
+class CubitVector;
+class CubitNode;
+template <class X> class DLIList;
+
+class CUBIT_GEOM_EXPORT PeriodicParamTool : public ParamTool
+{
+public:
+
+ //- constructor
+ PeriodicParamTool(Surface *surf);
+
+ //- destructor
+ ~PeriodicParamTool();
+
+ CubitStatus set_up_space(double u_period, double v_period, double u_offset, double v_offset);
+
+ CubitStatus transform_to_uv(const CubitVector &xyz_location, CubitVector &uv_location);
+
+ CubitStatus transform_to_xyz(CubitVector &xyz_location, const CubitVector &uv_location);
+
+ void mirror_surface( bool true_false);
+
+ CubitStatus uv_derivitives( double u_param, double v_param,
+ CubitVector &du, CubitVector &dv );
+
+private:
+
+ Surface *refSurf;
+ double uPeriod;
+ double vPeriod;
+ double uOffset;
+ double vOffset;
+ bool mirrorSurface;
+
+ //- reference surface
+};
+
+#endif // ACIS_PARAM_TOOL_HPP
+
Modified: cgm/branches/cubit/geom/RefEdge.cpp
===================================================================
--- cgm/branches/cubit/geom/RefEdge.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/RefEdge.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -202,7 +202,7 @@
// Move the point to the Curve (the following call modifes the values
// of the input "vector", if necessary)
CubitVector closest_point;
- curvePtr->closest_point(vector, closest_point);
+ curvePtr->closest_point_trimmed(vector, closest_point);
vector.set( closest_point.x(),
closest_point.y(),
closest_point.z() );
@@ -309,7 +309,12 @@
DLIList<CoEdge*> co_edge_list;
get_co_edges( co_edge_list, ref_face_ptr );
- assert( co_edge_list.size() == 1 );
+ if( co_edge_list.size() != 1 )
+ {
+ PRINT_ERROR( "Ambiguous case in tangent calculation.\n" );
+ return CUBIT_FAILURE;
+ }
+// assert( co_edge_list.size() == 1 );
if ( co_edge_list.get()->get_sense() == CUBIT_REVERSED )
tangent_vec = -tangent_vec;
@@ -1278,18 +1283,16 @@
{
CubitVector start_pt = start_vertex()->coordinates();
CubitVector end_pt = end_vertex()->coordinates();
- PRINT_WARNING (
- "WARNING (RefEdge::initialize): Edge has zero arclength.\n"
- " Start vertex location is (%9.2f, %9.2f, %9.2f ).\n"
- " End vertex location is (%9.2f, %9.2f, %9.2f ).\n",
+ PRINT_WARNING ( "(RefEdge::initialize): Edge has zero arclength.\n"
+ " Start vertex location is (%9.2f, %9.2f, %9.2f ).\n"
+ " End vertex location is (%9.2f, %9.2f, %9.2f ).\n",
start_pt.x(), start_pt.y(), start_pt.z(),
end_pt.x(), end_pt.y(), end_pt.z() );
}
else if (!mSuppressEdgeLengthWarning)
{
- PRINT_WARNING(
- "WARNING: Edge found with zero arclength\n"
- " For cones, this may be normal.\n");
+ PRINT_WARNING( "Edge found with zero arclength\n"
+ " For cones, this may be normal.\n");
}
}
@@ -1444,8 +1447,7 @@
return CUBIT_FAILURE;
}
- int junk;
- return curve_ptr->get_geometry_query_engine()->get_graphics(curve_ptr,junk,
+ return curve_ptr->get_geometry_query_engine()->get_graphics(curve_ptr,
&polyline, tolerance);
}
@@ -1469,3 +1471,70 @@
mSuppressEdgeLengthWarning = flag;
}
+CubitStatus RefEdge::evaluate_exterior_angle(double *exterior_angle)
+{
+ //- Get the center point of this curve
+ CubitVector center = this->center_point();
+ CubitVector surf_norm[2];
+ CubitVector tangent;
+ RefFace* ref_face = NULL;
+ RefEdge* next_curve = NULL;
+
+ int i, j, k;
+
+ //- Get surfaces on this curve
+ DLIList<RefFace*> surf_list;
+ this->ref_faces(surf_list);
+ if(surf_list.size() == 2)
+ {
+ for( i = 0; i < surf_list.size(); i++)
+ {
+ RefFace* this_surf = surf_list.get_and_step();
+ surf_norm[i] = this_surf->normal_at(center);
+ if( i == 1)
+ {
+ //- Get the referance surface and curve to get exterior angle
+ ref_face = this_surf;
+ DLIList<DLIList<RefEdge*>*> loop_lists;
+ ref_face->ref_edge_loops(loop_lists);
+ for( j = 0; j < loop_lists.size(); j++ )
+ {
+ DLIList<RefEdge*>* current_list = loop_lists.get_and_step();
+ for( k = 0; k < current_list->size(); k++ )
+ {
+ RefEdge* current_curve = current_list->get_and_step();
+ if( current_curve == this )
+ {
+ next_curve = current_list->get();
+ break;
+ }
+ }
+ if(next_curve != NULL)
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ *exterior_angle = 0.0;
+ PRINT_ERROR("There aren't 2 surfaces on curve %d. Can't compute angle.\n", this->id());
+ return CUBIT_FAILURE;
+ }
+
+ this->tangent(center, tangent, next_curve, ref_face);
+
+ //Find the angle from normal 1 to normal 0.
+ double rad_angle = tangent.vector_angle_quick(surf_norm[1], surf_norm[0]); //angle in radians
+ double angle = rad_angle * (180.0 / 3.14159); //angle in degrees
+
+ //Now convert to the exterior angle between the two surfaces.
+ angle += 180.0;
+ if( angle > 360.0 )
+ angle -= 360.0;
+
+ //- Return the exterior angle for this curve in degrees.
+ *exterior_angle = angle;
+ return CUBIT_SUCCESS;
+}
+
Modified: cgm/branches/cubit/geom/RefEdge.hpp
===================================================================
--- cgm/branches/cubit/geom/RefEdge.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/RefEdge.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -116,7 +116,7 @@
CubitSense sense( RefFace *face );
//- Sense of this edge wrt the given face.
- //- Return CUBIT_FORWARD or CUBIT_REVERSE.
+ //- Return CUBIT_FORWARD or CUBIT_REVERSED.
//- Returns CUBIT_UNKNOWN if there is more than one coedge, and
//- senses don't agree, or if there are no coedges.
@@ -444,6 +444,26 @@
double length_from_u( double parameter1,
double parameter2 );
+ //R double arc length
+ //I double parameter1, parameter value of one end of arc
+ //I double parameter2, parameter value of the other end of arc
+ //
+ //Calculates, the distance along the curve between parameters
+ // parameter1 and parameter2.
+ //
+ // The order of the paramters does not affect the result.
+ // That is, switching parameter1 and parameter2 will
+ // result in the same arc length.
+ //
+ // The resulting length is always non-negative.
+ //
+ // For periodic curves, the length is calculated along
+ // the curve in the diretion of increasing parameter value.
+ // Therefore, if the caller wants the length calculation
+ // to be in a direction that crosses the periodic break,
+ // the interval [parameter1, parameter2] should span a
+ // break point in the period.
+
CubitBoolean is_periodic();
//R CubitBoolean
@@ -502,6 +522,12 @@
virtual int validate();
//- Check that entity is valid. Returns number of problems detected.
+ CubitStatus evaluate_exterior_angle(double *exterior_angle);
+ //- Calculate the exterior angle between this curve and the
+ //- attached surfaces. This function assumes that the curve is
+ //- only attached to two (2) surfaces, otherwise it returns CUBIT_FAILURE;
+
+
//========= Add Code by SRS of Cat, 3/3/99 2:28:31 PM =========
CubitBoolean is_tolerant();
//- Returns CUBIT_TRUE if refedge is a tolerant edge. Tolerant
Modified: cgm/branches/cubit/geom/RefEntity.cpp
===================================================================
--- cgm/branches/cubit/geom/RefEntity.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/RefEntity.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -69,10 +69,16 @@
markedFlag = CUBIT_FALSE;
listFlag = CUBIT_FALSE;
mColor = CUBIT_DEFAULT_COLOR;
+
+ CGMHistory::Event evt(CGMHistory::ENTITY_CREATED, this);
+ GeometryQueryTool::instance()->history().add_event(evt);
}
RefEntity::~RefEntity()
{
+ CGMHistory::Event evt(CGMHistory::ENTITY_DELETED, this);
+ GeometryQueryTool::instance()->history().add_event(evt);
+
// Remove the name of this entity from the entity name map
RefEntityName::instance()->remove_refentity_name(this, CUBIT_FALSE);
@@ -627,8 +633,8 @@
}
if ( all_same )
{
- ref_entities.get()->get_child_ref_entities(join_set);
- return join_set.get();
+ join_set.append(ref_entities.get());
+ return ref_entities.get();
}
// they aren't all the same; get all the children, intersect the lists,
@@ -932,13 +938,22 @@
// Check that measure is positive
int error = 0;
- double this_measure = measure();
- if (this_measure <= 0.0) {
- PRINT_WARNING("\tWARNING: non-positive %s (%f) for %s, (%s %d)\n",
- measure_label().c_str(), this_measure,
- entity_name().c_str(), class_name(), id());
- error++;
- }
+
+ Body *tmp_body = CAST_TO( this, Body);
+ bool is_sheet_body = false;
+ if( tmp_body )
+ is_sheet_body = tmp_body->is_sheet_body();
+
+ if( false == is_sheet_body )
+ {
+ double this_measure = measure();
+ if (this_measure <= 0.0) {
+ PRINT_WARNING("\tWARNING: non-positive %s (%f) for %s, (%s %d)\n",
+ measure_label().c_str(), this_measure,
+ entity_name().c_str(), class_name(), id());
+ error++;
+ }
+ }
return error;
}
Modified: cgm/branches/cubit/geom/RefEntity.hpp
===================================================================
--- cgm/branches/cubit/geom/RefEntity.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/RefEntity.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -58,7 +58,7 @@
// ********** END ENUM DEFINITIONS **********
-
+//! Base class for all geometry entities, body, volume, surface...
class CUBIT_GEOM_EXPORT RefEntity: public CubitEntity,
public CubitObservable,
public ToolDataUser,
@@ -73,117 +73,146 @@
//- A pure virtual destructor - this ensures that the class is
//- non-instantiable.
- // Class name related functions
+ //! \brief Gets the class name of a RefEntity type.
static const char* get_ref_class_name(const type_info& ref_type);
- // Name-related functions
+ //! \brief Gets the RefEntity with the passed in name.
static RefEntity* get_by_name(const CubitString& name);
+
+ //! \brief Gets the name of this RefEntity.
CubitString entity_name() const;
+
+ //! \brief Sets the name of this RefEntity.
CubitStatus entity_name (CubitString name);
+
+ //! \brief Gets the names of this RefEntity.
void entity_names(DLIList<CubitString*> &names) const;
+
+ //! \brief Get the number of names this RefEntity has.
int num_names() const;
+
+ //! \brief Generates a default name for this RefEntity. 'name' is prepended
+ //! to the default name.
CubitStatus generate_default_name ( CubitString &name );
+
+ //! \brief Assigns a default name to the entity.
CubitStatus assign_default_name( CubitBoolean user_setting = CUBIT_FALSE );
+
CubitStatus remove_entity_name(CubitString const & name);
CubitStatus remove_entity_names();
void merge_entity_names(RefEntity* dead_entity);
void switch_entity_names(RefEntity *other_entity);
- //- Functions related to naming of RefEntity objects
-
+
+ //@{
+ //- Generic flag for temporary use by algorithms.
+ //- Value is volatile and may change unexpectedly.
virtual void marked(int value);
virtual int marked ();
- //- Generic flag for temporary use by algorithms.
- //- Value is volatile and may change unexpectedly.
+ //@}
+
+ //! \brief Setting auto merge status flag.
+ virtual void is_mergeable(AutoMergeStatus val);
- virtual void is_mergeable(AutoMergeStatus val);
+ //! \brief Gets auto merge status flag.
AutoMergeStatus merge_status() const;
+
+ //! \brief Query to see if entity is free to merge.
bool is_mergeable();
+
+ //! \brief Query to see if entity is merged.
CubitBoolean is_merged();
// return true if this RefEntity has multiple TopologyBridges.
+ //! Updates the auto merge state of the entity.
void update_auto_merge_state();
- //- Set/Get the mergeable status for this entity.
+ //! \brief Get whether all child entities are mergeable.
virtual bool children_mergeable();
- //- Get whether all child entities are mergeable.
+ //! Allow unmerging and other operations. Default in
+ //! RefEntity always returns true. Provided for
+ //! derived classes to override.
virtual int can_modify();
- //- Allow unmerging and other operations. Default in
- //- RefEntity always returns true. Provided for
- //- derived classes to override.
+ //! Returns the geometric dimension of the entity.
+ //! vertex == 0, edge == 1, etc.
virtual int dimension() const;
- // Returns the geometric dimension of the entity.
- // vertex == 0, edge == 1, etc.
+ //! Appends all immediate (child) RefEntities owned by this RefEntity to
+ //! entity_list. (The query goes down just one dimension.)
virtual void get_child_ref_entities(DLIList<RefEntity*>& entity_list);
- //- Appends all immediate (child) RefEntities owned by this RefEntity to
- //- entity_list. (The query goes down just one dimension.)
+ //! Appends all child RefEntities owned by this entity to entity_list.
+ //! (The query recurses all the way down to RefEntities of dimension 0).
void get_all_child_ref_entities(DLIList<RefEntity*>& entity_list);
- //- Appends all child RefEntities owned by this entity to entity_list.
- //- (The query recurses all the way down to RefEntities of dimension 0).
+ //! Appends all child RefEntities owned by entities in input_list to output_list
static void get_all_child_ref_entities(DLIList<RefEntity*>& input_list,
DLIList<RefEntity*>& output_list );
- //- Appends all child RefEntities owned by entities in input_list to output_list
+ //! Gather the boundary entities of the entity_list into the bdy_list.
+ //! Entities appear once in bdy_list, and will not appear in bdy_list
+ //! if they are already in the entity_list.
+ //! Uses listMark.
static void gather_bdy_entities( DLIList<RefEntity*> &entity_list,
DLIList<RefEntity*> &bdy_list );
- // Gather the boundary entities of the entity_list into the bdy_list.
- // Entities appear once in bdy_list, and will not appear in bdy_list
- // if they are already in the entity_list.
- // Uses listMark.
+ //! Appends all RefEntities that own this (parent RefEntities) to
+ //! entity_list.
+ //! (The query goes up just one dimension. For example, if this is a
+ //! vertex, the resulting list contains only RefEdges).
virtual void get_parent_ref_entities(DLIList<RefEntity*>& entity_list);
- //- Appends all RefEntities that own this (parent RefEntities) to
- //- entity_list.
- //- (The query goes up just one dimension. For example, if this is a
- //- vertex, the resulting list contains only RefEdges).
+ //! Appends all parent RefEntities owned by this entity to entity_list.
+ //! Recurses up to RefVolumes, or RefBodies if get_bodies is true.
void get_all_parent_ref_entities(DLIList<RefEntity*>& entity_list,
const int get_bodies = CUBIT_FALSE );
- //- Appends all parent RefEntities owned by this entity to entity_list.
- //- Recurses up to RefVolumes, or RefBodies if get_bodies is true.
+ //! Modify the input list to contain the list of RefEntities that are
+ //! the parents of each of the RefEntities in the original list.
static void change_to_parent_ref_entities( DLIList<RefEntity*>& ancestors );
- //- Modify the input list to contain the list of RefEntities that are
- //- the parents of each of the RefEntities in the original list.
-
+
+ //@{
+ //! RefEntity* join( RefEntity* ref_entity_2 );
+ //! Computes the geometric "join" of elements (elements on the list or
+ //! this and ref_entity_2).
+ //! Definition "Join" = The lowest dimensional entitity that
+ //! is a higher dimensional ancestor of them all.
+ //! Note join could be one of the entities itself, NULL,
+ //! or multiple elements.
+ //! E.g. The join of a vertex and a curve containing the vertex is
+ //! the curve. The join of two curves of a split cylinder is
+ //! both containing surfaces.
+ //! The join of two entities in separate, unmerged volumes is null.
+ //! Returns the first element of the join_set, or NULL if set is empty.
RefEntity *join( RefEntity* ref_entity_2, DLIList<RefEntity*> &join_set );
static RefEntity *join( DLIList<RefEntity*> &ref_entities,
DLIList<RefEntity*> &join_set );
- // RefEntity* join( RefEntity* ref_entity_2 );
- //- Computes the geometric "join" of elements (elements on the list or
- //- this and ref_entity_2).
- //- Definition "Join" = The lowest dimensional entitity that
- //- is a higher dimensional ancestor of them all.
- //- Note join could be one of the entities itself, NULL,
- //- or multiple elements.
- //- E.g. The join of a vertex and a curve containing the vertex is
- //- the curve. The join of two curves of a split cylinder is
- //- both containing surfaces.
- //- The join of two entities in separate, unmerged volumes is null.
- //- Returns the first element of the join_set, or NULL if set is empty.
+ //@}
+ //@{
+ //- like join, except returns the lower order entities common to the input
+ //- entities
RefEntity *meet( RefEntity* ref_entity_2, DLIList<RefEntity*> &join_set );
static RefEntity *meet( DLIList<RefEntity*> &ref_entities,
DLIList<RefEntity*> &join_set );
- //- like join, except returns the lower order entities common to the input
- //- entities
+ //@}
+ //! the valence of this entity with respect to parent (absolute
+ //! valence if parent is null)
int valence(RefEntity *parent = NULL);
- //- the valence of this entity with respect to parent (absolute
- //- valence if parent is null)
+
+ //@{
+ //- Return TRUE if this is entity, or a direct child (parent) of entity.
virtual CubitBoolean is_child(RefEntity *entity);
virtual CubitBoolean is_parent(RefEntity *entity);
- //- Return TRUE if this is entity, or a direct child (parent) of entity.
+ //@}
+ //! returns the number of parent entities of this; also useful for determining
+ //! whether an entity is free or not; returns -1 on error
int num_parent_ref_entities();
- //- returns the number of parent entities of this; also useful for determining
- //- whether an entity is free or not; returns -1 on error
// void common_draw_label(int color, const int label_style);
// //- Common code used for drawing labels. Actually, the entire
@@ -193,85 +222,102 @@
//CubitBoolean is_free_ref_entity();
//- return CUBIT_TRUE if this ref entity has no non-virtual parents
+ //! Return the approximate (spatial) center of this RefEntity
virtual CubitVector center_point();
- //- Return the approximate (spatial) center of this RefEntity
+ //! A generic geometric extent function.
+ //! Returns volume for RefVolumes, area for RefFaces, length for RefEdge,
+ //! and 1.0 for RefVertices
+ //! A RefGroup calculates the maximum dimension of its contained
+ //! entities and returns the sum of the measures() of all entities
+ //! of that dimension.
+ //! Default return value is 0.0 for all other entities.
virtual double measure();
- //- A generic geometric extent function.
- //- Returns volume for RefVolumes, area for RefFaces, length for RefEdge,
- //- and 1.0 for RefVertices
- //- A RefGroup calculates the maximum dimension of its contained
- //- entities and returns the sum of the measures() of all entities
- //- of that dimension.
- //- Default return value is 0.0 for all other entities.
+ //! Returns the type of measure: (volume, area, length, or N/A)
virtual CubitString measure_label();
- //- Returns the type of measure: (volume, area, length, or N/A)
+ //! Perform checks to see if entity valid.
virtual int validate();
- //- Perform checks to see if entity valid.
+ //! Returns the dag type of this enity.
virtual DagType dag_type() const = 0;
+
+ //! Returns the type info of this enity.
virtual const type_info& entity_type_info() const = 0;
+
+ //! Translates the type info into dag type.
static DagType dag_type( const type_info& );
- //- Return the type of the entity
-
+
+ //! Gets the parent RefEntity type.
DagType get_parent_ref_entity_type() const;
+
+ //! Gets the child RefEntity type.
DagType get_child_ref_entity_type() const;
+
+ //! Given a child dag type, returns the parent dag type.
static DagType get_parent_ref_entity_type( DagType child_type );
+
+ //! Given a parent dag type, returns the child dag type.
static DagType get_child_ref_entity_type( DagType parent_type );
- // send event to all observers (static and non-static) for
- // this entity and all children
+ //! send event to all observers (static and non-static) for
+ //! this entity and all children
void notify_sub_all_observers(const CubitEvent& event);
-
+ //!R void
+ //!I partner
+ //!I- The merge partner for this object
+ //!I event
+ //!I- The type of event
+ //! This function takes actions depending on the type of event it
+ //! is notified of.
+ //! COMPARISON_FOUND:
+ //! Make temporary TDCompare objects and attach to "this" and
+ //! the "partner" object.
void notify(RefEntity* partner, CubitEventType event);
- //R void
- //I partner
- //I- The merge partner for this object
- //I event
- //I- The type of event
- //- This function takes actions depending on the type of event it
- //- is notified of.
- //- COMPARISON_FOUND:
- //- Make temporary TDCompare objects and attach to "this" and
- //- the "partner" object.
+ //!R void
+ //!I partner
+ //!I- The compare partner for this object
+ //! This function makes the connection between the two RefEntities,
+ //! this and partner. At the end of this function the two entities
+ //! would know who they compare with.
void add_compare_data(RefEntity* partner) ;
- //R void
- //I partner
- //I- The compare partner for this object
- //- This function makes the connection between the two RefEntities,
- //- this and partner. At the end of this function the two entities
- //- would know who they compare with.
+ //!- This function clears the compare related temporary data.
void remove_compare_data() ;
- //R void
- //- This function clears the compare related temporary data.
+ //!R RefEntity*
+ //!R- The partner set in add_compare_data(), or NULL if none
+ //!R- has been set.
RefEntity* get_compare_partner() ;
- //R RefEntity*
- //R- The partner set in add_compare_data(), or NULL if none
- //R- has been set.
+ //! Premodify function called after CGM has been modified
+ virtual void geometry_premodify() { return; };
+
//======== Change Code by RY of Cat, 5/7/99 11:08:12 AM ========
void get_related_entity_list(const type_info& related_entity_type,
DLIList<RefEntity*>& entity_list);
//- to parse group in <ref_entity> commands
//======== Change End by RY of Cat, 5/7/99 11:08:12 AM ========
+ //! Set the id of this RefEntity to i
virtual void set_id(int i );
- //- set the id of this entity to i
-
+
+ //! Sets the id of this RefEntity and emits specified event static observers.
void set_id(int i, CubitBoolean emit_event );
+ //! Returns the type of a class given the class name.
static const type_info& get_entity_type_info(const char* entity_type);
- //- Returns the type of a class given the class name.
-
+
+ //! Returns a dag type based on name passed in, i.e., body, volume, surface..
static DagType dag_type( const char* cli_type_name );
+
+ //! Sets the color of this RefEntity.
+ virtual void color(int value);
- virtual void color(int value);
+ //! Gets the color of this RefEntity.
virtual int color() const;
protected :
Modified: cgm/branches/cubit/geom/RefEntityFactory.cpp
===================================================================
--- cgm/branches/cubit/geom/RefEntityFactory.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/RefEntityFactory.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -8,6 +8,62 @@
#include "GeometryQueryTool.hpp"
#include "DLIList.hpp"
+static int sort_by_ascending_ids(CubitEntity*& a, CubitEntity*& b)
+{
+ if( a->id() < b->id() )
+ return -1;
+ else
+ return 1;
+}
+
+static int sort_by_ascending_ids(RefVertex*& a, RefVertex*& b)
+{
+ if( a->id() < b->id() )
+ return -1;
+ else
+ return 1;
+}
+
+static int sort_by_ascending_ids(RefVolume*& a, RefVolume*& b)
+{
+ if( a->id() < b->id() )
+ return -1;
+ else
+ return 1;
+}
+
+static int sort_by_ascending_ids(RefEdge*& a, RefEdge*& b)
+{
+ if( a->id() < b->id() )
+ return -1;
+ else
+ return 1;
+}
+
+static int sort_by_ascending_ids(RefFace*& a, RefFace*& b)
+{
+ if( a->id() < b->id() )
+ return -1;
+ else
+ return 1;
+}
+
+static int sort_by_ascending_ids(Body*& a, Body*& b)
+{
+ if( a->id() < b->id() )
+ return -1;
+ else
+ return 1;
+}
+
+static int sort_by_ascending_ids(RefGroup*& a, RefGroup*& b)
+{
+ if( a->id() < b->id() )
+ return -1;
+ else
+ return 1;
+}
+
RefEntityFactory *RefEntityFactory::instance_ = NULL;
RefEntityFactory::RefEntityFactory(RefEntityFactory *factory)
@@ -31,10 +87,26 @@
refVolumeList = NULL;
bodyList = NULL;
}
+
+ refVertexListIsSorted = true;
+ refEdgeListIsSorted = true;
+ refFaceListIsSorted = true;
+ refVolumeListIsSorted = true;
+ bodyListIsSorted = true;
+ refGroupListIsSorted = true;
reset_ids();
}
+void RefEntityFactory::delete_instance()
+{
+ if( NULL != instance_ )
+ {
+ delete instance_;
+ instance_ = NULL;
+ }
+}
+
RefEntityFactory::~RefEntityFactory()
{
if (refVertexList != NULL) delete refVertexList;
@@ -163,6 +235,12 @@
void RefEntityFactory::add(RefGroup* refGPtr)
{
assert(!refGroupList->is_in_list(refGPtr));
+ if(refGroupList->size() > 0)
+ {
+ refGroupList->last();
+ if(refGPtr->id() < refGroupList->get()->id())
+ refGroupListIsSorted = false;
+ }
refGroupList->append(refGPtr);
if (refGPtr->id() > maxRefGroupId) maxRefGroupId = refGPtr->id();
}
@@ -170,6 +248,12 @@
void RefEntityFactory::add(Body* bodyPtr)
{
assert(!bodyList->is_in_list(bodyPtr));
+ if(bodyList->size() > 0)
+ {
+ bodyList->last();
+ if(bodyPtr->id() < bodyList->get()->id())
+ bodyListIsSorted = false;
+ }
bodyList->append(bodyPtr);
if (bodyPtr->id() > maxBodyId) maxBodyId = bodyPtr->id();
}
@@ -177,6 +261,12 @@
void RefEntityFactory::add(RefVolume* refVPtr)
{
assert(!refVolumeList->is_in_list(refVPtr));
+ if(refVolumeList->size() > 0)
+ {
+ refVolumeList->last();
+ if(refVPtr->id() < refVolumeList->get()->id())
+ refVolumeListIsSorted = false;
+ }
refVolumeList->append(refVPtr);
if (refVPtr->id() > maxRefVolumeId)
maxRefVolumeId = refVPtr->id();
@@ -185,6 +275,12 @@
void RefEntityFactory::add(RefFace* refFPtr)
{
assert(!refFaceList->is_in_list(refFPtr));
+ if(refFaceList->size() > 0)
+ {
+ refFaceList->last();
+ if(refFPtr->id() < refFaceList->get()->id())
+ refFaceListIsSorted = false;
+ }
refFaceList->append(refFPtr);
if (refFPtr->entityId > maxRefFaceId)
maxRefFaceId = refFPtr->entityId;
@@ -193,6 +289,12 @@
void RefEntityFactory::add(RefEdge* refEPtr)
{
assert(!refEdgeList->is_in_list(refEPtr));
+ if(refEdgeList->size() > 0)
+ {
+ refEdgeList->last();
+ if(refEPtr->id() < refEdgeList->get()->id())
+ refEdgeListIsSorted = false;
+ }
refEdgeList->append(refEPtr);
if (refEPtr->id() > maxRefEdgeId)
maxRefEdgeId = refEPtr->id();
@@ -201,6 +303,12 @@
void RefEntityFactory::add(RefVertex* refVPtr)
{
assert(!refVertexList->is_in_list(refVPtr));
+ if(refVertexList->size() > 0)
+ {
+ refVertexList->last();
+ if(refVPtr->id() < refVertexList->get()->id())
+ refVertexListIsSorted = false;
+ }
refVertexList->append(refVPtr);
if (refVPtr->id() > maxRefVertexId)
maxRefVertexId = refVPtr->id();
@@ -340,6 +448,18 @@
ref_vertices = *refVertexList;
}
+#ifdef PROE
+void RefEntityFactory::ref_parts(DLIList<RefPart*> &ref_parts)
+{
+ ref_parts = *refPartList;
+}
+
+void RefEntityFactory::ref_assemblies(DLIList<RefAssembly*> &ref_assemblies)
+{
+ ref_assemblies = *refAssemblyList;
+}
+#endif
+
int RefEntityFactory::num_bodies() const {return bodyList->size();}
int RefEntityFactory::num_ref_volumes() const {return refVolumeList->size();}
int RefEntityFactory::num_ref_groups() const {return refGroupList->size();}
@@ -406,18 +526,46 @@
if (!bodyList->size())
return NULL;
- // If the desired ID is less than the current list item's ID,
- // it is 'probably' before current spot in list, so reset.
- Body* body_ptr = bodyList->get();
- if (body_ptr->id() > id)
- bodyList->reset();
-
- for (int i = bodyList->size(); i--; )
+ // Make sure the list is sorted for the binary search.
+ if(!bodyListIsSorted)
{
- body_ptr = bodyList->get_and_step();
- if (body_ptr->id() == id)
- return body_ptr ;
+ bodyList->sort(sort_by_ascending_ids);
+ bodyListIsSorted = true;
}
+
+ // Do a binary search on the sorted list. We are making the assumption
+ // here that there are no NULL entries in the list.
+ bool found = false;
+ int left_index = 0;
+ int right_index = bodyList->size()-1;
+ int mid_index = (left_index + right_index)/2;
+ int mid_id = ((*bodyList)[mid_index])->id();
+
+ while(!found && (right_index-left_index) > 1)
+ {
+ if(mid_id == id)
+ found = true;
+ else
+ {
+ if(mid_id > id)
+ right_index = mid_index;
+ else
+ left_index = mid_index;
+ mid_index = (left_index + right_index)/2;
+ mid_id = ((*bodyList)[mid_index])->id();
+ }
+ }
+
+ if(!found)
+ {
+ if(((*bodyList)[left_index])->id() == id)
+ return ((*bodyList)[left_index]);
+ else if(((*bodyList)[right_index])->id() == id)
+ return ((*bodyList)[right_index]);
+ }
+ else
+ return ((*bodyList)[mid_index]);
+
return NULL ;
}
@@ -426,18 +574,46 @@
if (!refGroupList->size())
return NULL;
- // If the desired ID is less than the current list item's ID,
- // it is 'probably' before current spot in list, so reset.
- RefGroup* ref_group_ptr = refGroupList->get();
- if (ref_group_ptr->id() > id)
- refGroupList->reset();
-
- for (int i = refGroupList->size(); i--; )
+ // Make sure the list is sorted for the binary search.
+ if(!refGroupListIsSorted)
{
- ref_group_ptr = refGroupList->get_and_step();
- if (ref_group_ptr->id() == id)
- return ref_group_ptr ;
+ refGroupList->sort(sort_by_ascending_ids);
+ refGroupListIsSorted = true;
}
+
+ // Do a binary search on the sorted list. We are making the assumption
+ // here that there are no NULL entries in the list.
+ bool found = false;
+ int left_index = 0;
+ int right_index = refGroupList->size()-1;
+ int mid_index = (left_index + right_index)/2;
+ int mid_id = ((*refGroupList)[mid_index])->id();
+
+ while(!found && (right_index-left_index) > 1)
+ {
+ if(mid_id == id)
+ found = true;
+ else
+ {
+ if(mid_id > id)
+ right_index = mid_index;
+ else
+ left_index = mid_index;
+ mid_index = (left_index + right_index)/2;
+ mid_id = ((*refGroupList)[mid_index])->id();
+ }
+ }
+
+ if(!found)
+ {
+ if(((*refGroupList)[left_index])->id() == id)
+ return ((*refGroupList)[left_index]);
+ else if(((*refGroupList)[right_index])->id() == id)
+ return ((*refGroupList)[right_index]);
+ }
+ else
+ return ((*refGroupList)[mid_index]);
+
return NULL ;
}
@@ -446,18 +622,46 @@
if (!refVolumeList->size())
return NULL;
- // If the desired ID is less than the current list item's ID,
- // it is 'probably' before current spot in list, so reset.
- RefVolume* ref_volume_ptr = refVolumeList->get();
- if (ref_volume_ptr->id() > id)
- refVolumeList->reset();
-
- for (int i = refVolumeList->size(); i--; )
+ // Make sure the list is sorted for the binary search.
+ if(!refVolumeListIsSorted)
{
- ref_volume_ptr = refVolumeList->get_and_step() ;
- if (ref_volume_ptr->id() == id)
- return ref_volume_ptr ;
+ refVolumeList->sort(sort_by_ascending_ids);
+ refVolumeListIsSorted = true;
}
+
+ // Do a binary search on the sorted list. We are making the assumption
+ // here that there are no NULL entries in the list.
+ bool found = false;
+ int left_index = 0;
+ int right_index = refVolumeList->size()-1;
+ int mid_index = (left_index + right_index)/2;
+ int mid_id = ((*refVolumeList)[mid_index])->id();
+
+ while(!found && (right_index-left_index) > 1)
+ {
+ if(mid_id == id)
+ found = true;
+ else
+ {
+ if(mid_id > id)
+ right_index = mid_index;
+ else
+ left_index = mid_index;
+ mid_index = (left_index + right_index)/2;
+ mid_id = ((*refVolumeList)[mid_index])->id();
+ }
+ }
+
+ if(!found)
+ {
+ if(((*refVolumeList)[left_index])->id() == id)
+ return ((*refVolumeList)[left_index]);
+ else if(((*refVolumeList)[right_index])->id() == id)
+ return ((*refVolumeList)[right_index]);
+ }
+ else
+ return ((*refVolumeList)[mid_index]);
+
return NULL ;
}
@@ -466,18 +670,46 @@
if (!refFaceList->size())
return NULL;
- // If the desired ID is less than the current list item's ID,
- // it is 'probably' before current spot in list, so reset.
- RefFace* ref_face_ptr = refFaceList->get();
- if (ref_face_ptr->id() > id)
- refFaceList->reset();
-
- for (int i = refFaceList->size(); i--; )
+ // Make sure the list is sorted for the binary search.
+ if(!refFaceListIsSorted)
{
- ref_face_ptr = refFaceList->get_and_step() ;
- if (ref_face_ptr->id() == id)
- return ref_face_ptr ;
+ refFaceList->sort(sort_by_ascending_ids);
+ refFaceListIsSorted = true;
}
+
+ // Do a binary search on the sorted list. We are making the assumption
+ // here that there are no NULL entries in the list.
+ bool found = false;
+ int left_index = 0;
+ int right_index = refFaceList->size()-1;
+ int mid_index = (left_index + right_index)/2;
+ int mid_id = ((*refFaceList)[mid_index])->id();
+
+ while(!found && (right_index-left_index) > 1)
+ {
+ if(mid_id == id)
+ found = true;
+ else
+ {
+ if(mid_id > id)
+ right_index = mid_index;
+ else
+ left_index = mid_index;
+ mid_index = (left_index + right_index)/2;
+ mid_id = ((*refFaceList)[mid_index])->id();
+ }
+ }
+
+ if(!found)
+ {
+ if(((*refFaceList)[left_index])->id() == id)
+ return ((*refFaceList)[left_index]);
+ else if(((*refFaceList)[right_index])->id() == id)
+ return ((*refFaceList)[right_index]);
+ }
+ else
+ return ((*refFaceList)[mid_index]);
+
return NULL ;
}
@@ -486,18 +718,46 @@
if (!refEdgeList->size())
return NULL;
- // If the desired ID is less than the current list item's ID,
- // it is 'probably' before current spot in list, so reset.
- RefEdge* ref_edge_ptr = refEdgeList->get();
- if (ref_edge_ptr->id() > id)
- refEdgeList->reset();
-
- for (int i = refEdgeList->size(); i--; )
+ // Make sure the list is sorted for the binary search.
+ if(!refEdgeListIsSorted)
{
- ref_edge_ptr = refEdgeList->get_and_step() ;
- if (ref_edge_ptr->id() == id)
- return ref_edge_ptr ;
+ refEdgeList->sort(sort_by_ascending_ids);
+ refEdgeListIsSorted = true;
}
+
+ // Do a binary search on the sorted list. We are making the assumption
+ // here that there are no NULL entries in the list.
+ bool found = false;
+ int left_index = 0;
+ int right_index = refEdgeList->size()-1;
+ int mid_index = (left_index + right_index)/2;
+ int mid_id = ((*refEdgeList)[mid_index])->id();
+
+ while(!found && (right_index-left_index) > 1)
+ {
+ if(mid_id == id)
+ found = true;
+ else
+ {
+ if(mid_id > id)
+ right_index = mid_index;
+ else
+ left_index = mid_index;
+ mid_index = (left_index + right_index)/2;
+ mid_id = ((*refEdgeList)[mid_index])->id();
+ }
+ }
+
+ if(!found)
+ {
+ if(((*refEdgeList)[left_index])->id() == id)
+ return ((*refEdgeList)[left_index]);
+ else if(((*refEdgeList)[right_index])->id() == id)
+ return ((*refEdgeList)[right_index]);
+ }
+ else
+ return ((*refEdgeList)[mid_index]);
+
return NULL ;
}
@@ -506,18 +766,46 @@
if (!refVertexList->size())
return NULL;
- // If the desired ID is less than the current list item's ID,
- // it is 'probably' before current spot in list, so reset.
- RefVertex* ref_vertex_ptr = refVertexList->get();
- if (ref_vertex_ptr->id() > id)
- refVertexList->reset();
-
- for (int i = refVertexList->size(); i--; )
+ // Make sure the list is sorted for the binary search.
+ if(!refVertexListIsSorted)
{
- ref_vertex_ptr = refVertexList->get_and_step() ;
- if (ref_vertex_ptr->id() == id)
- return ref_vertex_ptr ;
+ refVertexList->sort(sort_by_ascending_ids);
+ refVertexListIsSorted = true;
}
+
+ // Do a binary search on the sorted list. We are making the assumption
+ // here that there are no NULL entries in the list.
+ bool found = false;
+ int left_index = 0;
+ int right_index = refVertexList->size()-1;
+ int mid_index = (left_index + right_index)/2;
+ int mid_id = ((*refVertexList)[mid_index])->id();
+
+ while(!found && (right_index-left_index) > 1)
+ {
+ if(mid_id == id)
+ found = true;
+ else
+ {
+ if(mid_id > id)
+ right_index = mid_index;
+ else
+ left_index = mid_index;
+ mid_index = (left_index + right_index)/2;
+ mid_id = ((*refVertexList)[mid_index])->id();
+ }
+ }
+
+ if(!found)
+ {
+ if(((*refVertexList)[left_index])->id() == id)
+ return ((*refVertexList)[left_index]);
+ else if(((*refVertexList)[right_index])->id() == id)
+ return ((*refVertexList)[right_index]);
+ }
+ else
+ return ((*refVertexList)[mid_index]);
+
return NULL ;
}
@@ -554,6 +842,18 @@
return ++maxRefVertexId;
}
+#ifdef PROE
+int RefEntityFactory::next_ref_assembly_id ()
+{
+ return ++maxRefAssemblyId;
+}
+
+int RefEntityFactory::next_ref_part_id ()
+{
+ return ++maxRefPartId;
+}
+#endif
+
Body *RefEntityFactory::get_first_body()
{
bodyList->reset();
@@ -792,15 +1092,6 @@
}
}
-//used to sort list below
-static int sort_by_ascending_ids(CubitEntity*& a, CubitEntity*& b)
-{
- if( a->id() < b->id() )
- return -1;
- else
- return 1;
-}
-
void RefEntityFactory::compress_ids(DLIList<CubitEntity*> &list)
{
int id = 1;
@@ -841,6 +1132,10 @@
maxSurfSubDomainId = 0;
maxCurveSubDomainId = 0;
maxRefCoordSysId = 0;
+#ifdef PROE
+ maxRefAssemblyId = 0;
+ maxRefPartId = 0;
+#endif
}
#if 0
@@ -874,9 +1169,26 @@
if (!entity) return CUBIT_FAILURE;
//- handle MODEL_ENTITY_DESTRUCTED/MODEL_ENTITY_CONSTRUCTED events
- if (observer_event.get_event_type() == MODEL_ENTITY_CONSTRUCTED) add(entity);
-
- else if (observer_event.get_event_type() == MODEL_ENTITY_DESTRUCTED) remove(entity);
+ int event = observer_event.get_event_type();
+ if (event == MODEL_ENTITY_CONSTRUCTED)
+ add(entity);
+ else if (event == MODEL_ENTITY_DESTRUCTED)
+ remove(entity);
+ else if (event == ID_SET)
+ {
+ if(CAST_TO(entity, RefEdge))
+ refEdgeListIsSorted = false;
+ else if(CAST_TO(entity, RefFace))
+ refFaceListIsSorted = false;
+ else if(CAST_TO(entity, RefVertex))
+ refVertexListIsSorted = false;
+ else if(CAST_TO(entity, RefVolume))
+ refVolumeListIsSorted = false;
+ else if(CAST_TO(entity, RefGroup))
+ refGroupListIsSorted = false;
+ else if(CAST_TO(entity, Body))
+ bodyListIsSorted = false;
+ }
return CUBIT_SUCCESS;
}
Modified: cgm/branches/cubit/geom/RefEntityFactory.hpp
===================================================================
--- cgm/branches/cubit/geom/RefEntityFactory.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/RefEntityFactory.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -25,7 +25,10 @@
class RefGroup;
class Body;
class RefEntity;
-
+#ifdef PROE
+class RefAssembly;
+class RefPart;
+#endif
class Point;
class Curve;
class Surface;
@@ -44,10 +47,11 @@
{
public:
-
static RefEntityFactory *instance();
//- the function used to access the singleton instance
+ static void delete_instance();
+
virtual RefVertex *construct_RefVertex(Point *point = NULL);
virtual RefEdge *construct_RefEdge(Curve *curve = NULL);
@@ -73,6 +77,10 @@
virtual void ref_faces (DLIList<RefFace*> &ref_faces);
virtual void ref_edges (DLIList<RefEdge*> &ref_edges);
virtual void ref_vertices (DLIList<RefVertex*> &ref_vertices);
+#ifdef PROE
+ virtual void ref_parts (DLIList<RefPart*> &ref_parts);
+ virtual void ref_assemblies (DLIList<RefAssembly*> &ref_assemblies);
+#endif
virtual int num_bodies() const;
virtual int num_ref_volumes() const;
@@ -135,6 +143,10 @@
int next_ref_vertex_id ();
int next_surf_sub_domain_id ();
int next_curve_sub_domain_id();
+#ifdef PROE
+ int next_ref_assembly_id();
+ int next_ref_part_id();
+#endif
int current_body_id() {return maxBodyId;};
int current_volume_id() {return maxRefVolumeId;};
@@ -193,6 +205,10 @@
int maxRefCoordSysId;
int maxSurfSubDomainId;
int maxCurveSubDomainId;
+#ifdef PROE
+ int maxRefAssemblyId;
+ int maxRefPartId;
+#endif
#ifdef BOYD17
DLIList<RefEntity*> refEntityList;
@@ -201,12 +217,23 @@
private:
+ bool refVertexListIsSorted;
+ bool refEdgeListIsSorted;
+ bool refFaceListIsSorted;
+ bool refVolumeListIsSorted;
+ bool bodyListIsSorted;
+ bool refGroupListIsSorted;
+
DLIList<RefVertex*> *refVertexList;
DLIList<RefEdge*> *refEdgeList;
DLIList<RefFace*> *refFaceList;
DLIList<RefGroup*> *refGroupList;
DLIList<RefVolume*> *refVolumeList;
DLIList<Body*> *bodyList;
+#ifdef PROE
+ DLIList<RefAssembly*> *refAssemblyList;
+ DLIList<RefPart*> *refPartList;
+#endif
};
Modified: cgm/branches/cubit/geom/RefEntityName.cpp
===================================================================
--- cgm/branches/cubit/geom/RefEntityName.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/RefEntityName.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -64,6 +64,8 @@
CubitAttrib *attrib = entity->get_cubit_attrib(CA_ENTITY_NAME);
attrib->has_updated(CUBIT_FALSE);
attrib->update();
+ if( attrib->delete_attrib() )
+ entity->remove_cubit_attrib( attrib );
}
delete name_map;
@@ -73,6 +75,25 @@
void RefEntityName::remove_refentity_name(RefEntity *entity,
CubitBoolean update_attribs)
{
+ //update the attribute so the names are put into the entity list
+ if (update_attribs)
+ {
+ CubitAttrib *attrib = entity->get_cubit_attrib(CA_ENTITY_NAME,
+ CUBIT_FALSE);
+ if (attrib)
+ {
+ //update the attribute so that the names are on it.
+ attrib->has_written( CUBIT_FALSE );
+ attrib->has_updated(CUBIT_FALSE);
+ attrib->update();
+
+ //remove the attribute from the underlying entity
+ //of the solid modeling kernel
+ RefEntity *attrib_owner = attrib->attrib_owner();
+ attrib_owner->remove_attrib_geometry_entity( attrib );
+ }
+ }
+
// NOTE: There may be multiple names for one RefEntity. Make sure to
// remove all of them.
@@ -90,26 +111,28 @@
nameEntityList.step();
}
nameEntityList.compress();
-
+
// now tell the entity to update its name attribute
if (update_attribs)
{
CubitAttrib *attrib = entity->get_cubit_attrib(CA_ENTITY_NAME,
CUBIT_FALSE);
- if (attrib) {
+ if (attrib)
+ {
attrib->has_updated(CUBIT_FALSE);
attrib->update();
+ entity->remove_cubit_attrib( attrib );
}
}
for (i = old_maps.size(); i > 0; i--)
delete old_maps.get_and_step();
-
}
CubitStatus RefEntityName::add_refentity_name(RefEntity *entity,
- DLIList<CubitString*> &names,
- CubitBoolean update_attribs)
+ DLIList<CubitString*> &names,
+ bool update_attribs,
+ bool check_name_validity)
{
names.reset();
//int num_new_names = names.size();
@@ -124,13 +147,16 @@
CubitBoolean warn_name_change = CUBIT_FALSE;
// first, clean the name
- if (clean(name))
+ if (check_name_validity)
{
-// PRINT_WARNING("Entity name '%s' is invalid. Changed to '%s'\n",
-// in_name.c_str(), name.c_str());
- warn_name_change = CUBIT_TRUE;
+ if (clean(name))
+ {
+ // assign original name anyway, then
+ // continue on and assign modified name.
+ add_refentity_name(entity, in_name, false, false);
+ warn_name_change = CUBIT_TRUE;
+ }
}
-
// now, check for valid name
CubitBoolean name_valid = CUBIT_FALSE;
@@ -175,8 +201,9 @@
entity->class_name(), entity->id(), name.c_str());
if(warn_name_change)
{
- PRINT_WARNING("Entity name '%s' is invalid. Changed to '%s'\n",
- in_name.c_str(), name.c_str());
+ PRINT_WARNING("Entity name '%s' can't be used in commands.\n"
+ " Additional name '%s' assigned.\n",
+ in_name.c_str(), name.c_str());
}
name_valid = CUBIT_TRUE;
@@ -187,8 +214,9 @@
{
if(warn_name_change)
{
- PRINT_WARNING("Entity name '%s' is invalid. Changed to '%s'\n",
- in_name.c_str(), name.c_str());
+ PRINT_WARNING("Entity name '%s' can't be used in commands.\n"
+ " Additional name '%s' assigned.\n",
+ in_name.c_str(), name.c_str());
}
// else the name must be valid
@@ -244,8 +272,9 @@
}
CubitStatus RefEntityName::add_refentity_name(RefEntity *entity,
- CubitString &name,
- CubitBoolean update_attribs)
+ CubitString &name,
+ bool update_attribs,
+ bool check_name_validity)
{
if (name == "")
return CUBIT_FAILURE;
@@ -253,9 +282,15 @@
CubitString in_name = name;
bool warn_name_change = false;
- if (clean(name))
+ if (check_name_validity)
{
- warn_name_change = true;
+ if (clean(name))
+ {
+ // Assign the invalid name anyway, then continue on and
+ // assign the modified name.
+ add_refentity_name(entity, in_name, false, false);
+ warn_name_change = true;
+ }
}
if (nameEntityList.move_to(name))
@@ -287,13 +322,14 @@
{
if (warn_name_change)
{
- PRINT_WARNING("Entity name '%s' is invalid. Changed to '%s'\n",
+ PRINT_WARNING("Entity name '%s' can't be used in commands.\n"
+ " Additional name '%s' assigned.\n",
in_name.c_str(), name.c_str());
}
if ( DEBUG_FLAG(92) )
PRINT_WARNING("\t%s %d name changed to '%s'\n",
entity->class_name(), entity->id(), name.c_str());
- return add_refentity_name(entity, name);
+ return add_refentity_name(entity, name, update_attribs, false);
}
}
return CUBIT_FAILURE;
@@ -302,7 +338,8 @@
if (warn_name_change)
{
- PRINT_WARNING("Entity name '%s' is invalid. Changed to '%s'\n",
+ PRINT_WARNING("Entity name '%s' can't be used in commands.\n"
+ " Additional name '%s' assigned.\n",
in_name.c_str(), name.c_str());
}
@@ -519,8 +556,8 @@
CubitStatus RefEntityName::clean(CubitString &raw_name)
{
-
- if (raw_name == "") return CUBIT_FAILURE;
+ if (raw_name == "")
+ return CUBIT_FAILURE;
// A valid name consists of alphanumeric characters plus '.', '_', '-', or '@'
CubitStatus found_invalid_character = CUBIT_FAILURE;
@@ -828,7 +865,7 @@
for( int i = source_list.size(); i > 0; i-- )
get_refentity_name( source_list.get_and_step(), name_list );
name_list.reset();
- add_refentity_name( target, name_list, update_attribs );
+ add_refentity_name(target, name_list, update_attribs, false);
}
}
Modified: cgm/branches/cubit/geom/RefEntityName.hpp
===================================================================
--- cgm/branches/cubit/geom/RefEntityName.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/RefEntityName.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -33,6 +33,8 @@
static RefEntityName *instance();
~RefEntityName();
+ static void delete_instance() { if(instance_) delete instance_; }
+
void remove_refentity_name(const CubitString &name,
CubitBoolean update_attribs = CUBIT_TRUE);
//- Remove the this name from the map. All other names for this
@@ -44,7 +46,8 @@
CubitStatus add_refentity_name(RefEntity *entity,
CubitString &name,
- CubitBoolean update_attribs = CUBIT_TRUE);
+ bool update_attribs = true,
+ bool check_name_validity = true);
//- Add the map between this RefEntity and the name.
//- If 'name' is invalid or duplicate, it is changed and
//- new name is returned.
@@ -52,7 +55,8 @@
CubitStatus add_refentity_name(RefEntity *entity,
DLIList<CubitString*> &names,
- CubitBoolean update_attribs = CUBIT_TRUE);
+ bool update_attribs = true,
+ bool check_name_validity = true);
//- add multiple names to the name map for this entity
int get_refentity_name(const RefEntity *entity,
Modified: cgm/branches/cubit/geom/RefFace.cpp
===================================================================
--- cgm/branches/cubit/geom/RefFace.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/RefFace.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -112,436 +112,112 @@
remove_from_observers();
}
-double RefFace::get_crack_length()
-{
- double length = 0.0;
- if( is_parametric() )
+
+static void dist_between(RefEdge* edge1, RefEdge* edge2, CubitVector& v1, CubitVector& v2, double& dist)
+{
+ // check compatibility first
+ DLIList<TopologyEntity*> entity_list(2);
+ DLIList<TopologyBridge*> bridge_list(2);
+ entity_list.append(edge1);
+ entity_list.append(edge2);
+ GeometryQueryEngine* gqe = GeometryQueryTool::instance()->common_query_engine( entity_list, bridge_list );
+ if(gqe)
{
- double u_period_val, v_period_val;
-//These just give the total period for the surface, I'm assuming that
-//it will usually be 2PI
- double lower, upper;
- CubitBoolean u_period = is_periodic_in_U( u_period_val );
- CubitBoolean v_period = is_periodic_in_V( v_period_val );
- //The Booleans tell us if (duh) it's periodic in that direction
- if( ( u_period ) && ( v_period ) )//Uh-oh, periodic in both
-//directions, now we have to do some magic to find out the crack
-//length.
- {
- // find whether loops differ more in u or v direction.
- // the direction that they differ the most in is the direction
- // that we will step along to determine crack length.
- int m;
- double lowerv[2], upperv[2], loweru[2], upperu[2];
- //the eight variables above keep track of the lowest and
- //highest u- and v-parameter values for both boundaries of the
- //surface
-
- lowerv[0] = lowerv[1] = CUBIT_DBL_MAX;
- upperv[0] = upperv[1] = CUBIT_DBL_MAX;
- loweru[0] = loweru[1] = CUBIT_DBL_MAX;
- upperu[0] = upperu[1] = CUBIT_DBL_MAX;
- DLIList<Loop*> loops;
- this->loops( loops );
- // should be exactly 2 loops
- for( m = 0; m < loops.size() && m < 2; m++ )
- {
- int n;
- Loop* func_loop = loops.get_and_step();
- DLIList<RefEdge*> edges;
- func_loop->ordered_ref_edges( edges );
- for( n = edges.size(); n > 0; n-- )
- {
- // sample edges at 8 locations to approximate maximum and minimum
- // parameter extents of the line
- RefEdge* func_edge = edges.get_and_step();
- const int num_segments = 8;
- CubitVector location[num_segments];
- int i;
- for ( i = num_segments; i--; )
- {
- func_edge->position_from_fraction( ((double) i) / ((double) num_segments),
- location[i] );
-
- }
- CubitVector* closest_location = NULL;
- double temp_u, temp_v;
+ GeometryQueryTool::instance()->entity_entity_distance(edge1, edge2, v1, v2, dist);
+ }
+}
- for ( i = num_segments; i--; )
- {
- //now we fill temp_u and temp_v with the u and v values
- //of the closest point on the surface to the location[i]
- //vector--Note--the closest-point should be right where
- //the vector is, since that's where we got the vector
- //from
- this->u_v_from_position( location[i], temp_u, temp_v, closest_location );
- if( upperv[m] == CUBIT_DBL_MAX )
- upperv[m] = temp_v;
- if( lowerv[m] == CUBIT_DBL_MAX )
- lowerv[m] = temp_v;
-
- if( temp_v > upperv[m] )
- upperv[m] = temp_v;
- if( temp_v < lowerv[m] )
- lowerv[m] = temp_v;
-
- if( upperu[m] == CUBIT_DBL_MAX )
- upperu[m] = temp_u;
- if( loweru[m] == CUBIT_DBL_MAX )
- loweru[m] = temp_u;
-
- if( temp_u > upperu[m] )
- upperu[m] = temp_u;
- if( temp_u < loweru[m] )
- loweru[m] = temp_u;
- }
- }
- }
- if(DEBUG_FLAG(99))
- {
- int debug_int;
-
- for(debug_int = 0; debug_int <2; debug_int ++)
- {
- PRINT_INFO("Loweru[%d] = %f Upperu[%d] = %f\n",
- debug_int,loweru[debug_int],debug_int,upperu[debug_int]);
- }
-
- for(debug_int = 0; debug_int <2; debug_int ++)
- {
- PRINT_INFO("Lowerv[%d] = %f Upperv[%d] = %f\n",
- debug_int,lowerv[debug_int],debug_int,upperv[debug_int]);
- }
- }
-
-//Okay, we look at our u-params. The upperu of one loop should be
-//lower than the loweru of the other loop. If they cross, then we're
-//most likely looking at the direction parallel to the loop, and the
-//lower[1] and lower[0] values are probably very close to each other
- double u_start, u_end, v_start, v_end;
- u_start = u_end = v_start = v_end = 0.;
-//u_diff is the gap between the loops.
- //u_start is the midpoint of the lower loop's u_space
- //u_end is the midpoint of the upper loop's u_space
- double u_diff = 0.;
-
- if ( upperu[1] < loweru[0] )
- {
- u_diff = loweru[0] - upperu[1];
- u_start = (loweru[1] + upperu[1]) / 2.;
- u_end = (loweru[0] + upperu[0]) / 2.;
- }
- else if ( upperu[0] < loweru[1] )
- {
- u_diff = loweru[1] - upperu[0];
- u_start = (loweru[0] + upperu[0]) / 2.;
- u_end = (loweru[1] + upperu[1]) / 2.;
- }
+double RefFace::get_crack_length()
+{
+ // find two loops to check the shortest distance between as that's where Cubit is most
+ // likely to crack surfaces
- //Okay, we have u_start and u_end. We have to decide how to
- //get from one to the other. This comes up because u_start
- //might be smaller than u_end, but the trimmed surface might
- //not exist in between. If this is the case, then we need to
- //go around the other way to get to u_end
- double low_u, mid_u, high_u;
- double low_v, mid_v, high_v;
-
- mid_u = (u_start + u_end )/2.0;
-
- get_param_range_V( low_v, high_v );
- PRINT_DEBUG_99("low_v = %f high_v = %f\n",low_v, high_v);
- PRINT_DEBUG_99("u_start = %f u_end = %f\n",u_start, u_end);
- mid_v = (low_v + high_v) / 2.;
- double delta_u = fabs(u_end - u_start);
-
- switch(point_containment(mid_u, mid_v))
- {
- case CUBIT_PNT_OUTSIDE:
- PRINT_DEBUG_99("Point outside\n");
- delta_u = -(u_period_val - delta_u);
- break;
- case CUBIT_PNT_INSIDE:
- PRINT_DEBUG_99("Point inside\n");
- break;
- case CUBIT_PNT_BOUNDARY:
- PRINT_DEBUG_99("Point on boundary\n");
- break;
- case CUBIT_PNT_UNKNOWN:
- default:
- PRINT_DEBUG_99("Point Unknown\n");
- break;
- }
-
- delta_u = delta_u / 10.;
-
+ DLIList<Loop*> crack_loops;
- double v_diff = 0.;
- if ( upperv[1] < lowerv[0] )
- {
- v_diff = lowerv[0] - upperv[1];
- v_start = (lowerv[1] + upperv[1]) / 2.;
- v_end = (lowerv[0] + upperv[0]) / 2.;
- }
-
- else if ( upperv[0] < lowerv[1] )
- {
- v_diff = lowerv[1] - upperv[0];
- v_start = (lowerv[0] + upperv[0]) / 2.;
- v_end = (lowerv[1] + upperv[1]) / 2.;
- }
+ DLIList<Loop*> loops;
+ this->loops(loops);
- mid_v = (v_start + v_end )/2.0;
-
- get_param_range_U( low_u, high_u );
- PRINT_DEBUG_99("low_u = %f high_u = %f\n",low_u, high_u);
- PRINT_DEBUG_99("v_start = %f v_end = %f\n",v_start, v_end);
- mid_u = (low_u + high_u) / 2.;
- double delta_v = fabs(v_end - v_start);
-
- switch(point_containment(mid_u, mid_v))
- {
- case CUBIT_PNT_OUTSIDE:
- PRINT_DEBUG_99("Point outside\n");
- delta_v = -(v_period_val - delta_v);
- break;
- case CUBIT_PNT_INSIDE:
- PRINT_DEBUG_99("Point inside\n");
- break;
- case CUBIT_PNT_BOUNDARY:
- PRINT_DEBUG_99("Point on boundary\n");
- break;
- case CUBIT_PNT_UNKNOWN:
- default:
- PRINT_DEBUG_99("Point Unknown\n");
- break;
- }
- delta_v = delta_v / 10.;
-
- //Okay, by now we have the delta_u and delta_v values.
- //Theoretically they are the distance between the two
- //parameters' midpoints, divided by 10
+ int i, j;
+ for(i=0; i<loops.size(); i++)
+ {
+ Loop* l = loops.get_and_step();
+ LoopType loop_type = l->loop_type();
+ if(loop_type == LOOP_TYPE_U_PERIODIC || loop_type == LOOP_TYPE_V_PERIODIC)
+ crack_loops.append(l);
+ }
- //u_diff and v_diff are the gap between the lowest point on
- //the high one and the highest point on the low loop, they
- //will always be positive or zero
+ if(crack_loops.size() >= 2)
+ {
+ Loop* loop1 = crack_loops.get_and_step();
+ Loop* loop2 = crack_loops.get_and_step();
- //Note, if a loop is a complete circle, then the parameter
- //value going around that way will yield a delta_? and ?_diff
- //of zero
- int i;
- CubitVector start1, end1;
- CubitVector start2, end2;
- double length1 = 0, length2 = 0;
- PRINT_DEBUG_99("delta_v %e, delta_u %e\n",delta_v, delta_u); //zzyk
- PRINT_DEBUG_99("v_diff %e, u_diff %e\n",v_diff, u_diff); //zzyk
+ DLIList<RefEdge*> loop1_edges;
+ loop1->ref_edges(loop1_edges);
+ DLIList<RefEdge*> loop2_edges;
+ loop2->ref_edges(loop2_edges);
- //We want to get the longest crack length in the surface, so
- //if v_diff is smaller than u_diff, we'll step around the
- //u_direction, and vice versa
- if( v_diff < u_diff )
- {
- get_param_range_V( low_v, high_v );
- PRINT_DEBUG_99("low_v = %f high_v = %f\n",low_v, high_v);
- PRINT_DEBUG_99("u_start = %f u_end = %f\n",u_start, u_end);
- mid_v = (low_v + high_v) / 2.;
+ CubitVector p1, p2;
+ double min_dist = -1.0;
- for( i = 0; i < 10; i++ )
- {
- start1 = this->position_from_u_v( (u_start+(delta_u*i)), low_v );
- end1 = this->position_from_u_v( (u_start+(delta_u*(i+1))), low_v );
- if(DEBUG_FLAG(99))
- {
- GfxDebug::draw_vector(start1,end1, CUBIT_RED);
- GfxDebug::flush();
- PRINT_INFO("At position %f in u\n",u_start + (delta_u*i));
- }
- length1 += start1.distance_between( end1 );
- }
- for( i = 0; i < 10; i++ )
- {
- start2 = this->position_from_u_v( (u_start+(delta_u*i)), mid_v );
- end2 = this->position_from_u_v( (u_start+(delta_u*(i+1))), mid_v );
- if(DEBUG_FLAG(99))
- {
- GfxDebug::draw_vector(start2,end2, CUBIT_BLUE);
- GfxDebug::flush();
- PRINT_INFO("At position %f in u\n",u_start + (delta_u*i));
- }
- length2 += start2.distance_between( end2 );
- }
- }
- else //u_diff is less than v_diff
+ for(i=0; i<loop1_edges.size(); i++)
+ {
+ RefEdge* edge1 = loop1_edges.get_and_step();
+ for(j=0; j<loop2_edges.size(); j++)
{
- get_param_range_U( low_u, high_u );
- PRINT_DEBUG_99("low_u = %f high_u = %f\n",low_u, high_u);
- PRINT_DEBUG_99("v_start = %f v_end = %f\n",v_start, v_end);
- //Remember, v_start is halfway between the low and high
- //points of the lower loop, v_end is halfway between the low
- //and high points of the upper loop
- mid_u = (low_u + high_u) / 2.;
- mid_v = (v_start + v_end )/2.0;
- //Now we step aroung the loop of edges in ten places, and
- //add up the chord lengths of those 10 chords to get our
- //crack length. We do it twice and average just to make
- //sure everything is kosher.
- for( i = 0; i < 10; i++ )
+ RefEdge* edge2 = loop2_edges.get_and_step();
+ if(edge2 != edge1)
{
- start1 = this->position_from_u_v( low_u, (v_start+(delta_v*i)) );
- end1 = this->position_from_u_v( low_u, (v_start+(delta_v*(i+1))) );
- if(DEBUG_FLAG(99))
+ CubitVector v1, v2;
+ double dist = -1;
+ dist_between(edge1, edge2, v1, v2, dist);
+ if(min_dist < 0 || (dist < min_dist && dist > 0))
{
- GfxDebug::draw_vector(start1,end1, CUBIT_RED);
- GfxDebug::flush();
- PRINT_INFO("At position %f in v\n",v_start + (delta_v*i));
+ min_dist = dist;
+ p1 = v1;
+ p2 = v2;
}
- length1 += start1.distance_between( end1 );
}
- for( i = 0; i < 10; i++ )
- {
- start2 = this->position_from_u_v( mid_u, (v_start+(delta_v*i)) );
- end2 = this->position_from_u_v( mid_u, (v_start+(delta_v*(i+1))) );
- if(DEBUG_FLAG(99))
- {
- GfxDebug::draw_vector(start2,end2, CUBIT_BLUE);
- GfxDebug::flush();
- PRINT_INFO("At position %f in v\n",v_start + (delta_v*i));
- }
- length2 += start2.distance_between( end2 );
- }
}
-
- length = ( (length1 + length2) / 2.0 );
}
- else if( v_period )
+
+ // estimate distance along the surface in case of curvature
+ if(min_dist > 0)
{
- int i;
- get_param_range_U( lower, upper );
- double low_v, high_v, mid_v;
- get_param_range_V( low_v, high_v );
- mid_v = (low_v + high_v) / 2.;
- double delta = ( ( upper - lower ) / 10.0 );
- CubitVector start, end;
- for( i = 0; i < 10; i++ )
+ double new_min_dist = 0;
+ double start_uv[2];
+ double end_uv[2];
+ this->u_v_from_position(p1, start_uv[0], start_uv[1]);
+ this->u_v_from_position(p2, end_uv[0], end_uv[1]);
+ double delta_uv[2];
+ delta_uv[0] = (end_uv[0] - start_uv[0]) / 10.0;
+ delta_uv[1] = (end_uv[1] - start_uv[1]) / 10.0;
+
+ CubitVector start = p1;
+ CubitVector next;
+ for(i=0; i<10; i++)
{
- start = this->position_from_u_v( (lower+(delta*i)), mid_v );
- end = this->position_from_u_v( (lower+(delta*(i+1))), mid_v );
- // GfxDebug::draw_vector(start, end, CUBIT_RED);
- // GfxDebug::flush();
- length += start.distance_between( end );
+ start_uv[0] += delta_uv[0];
+ start_uv[1] += delta_uv[1];
+ next = this->position_from_u_v( start_uv[0], start_uv[1] );
+ new_min_dist += start.distance_between(next);
+ start = next;
}
+ min_dist = new_min_dist;
}
- else if( u_period )
+
+ if(min_dist < 0)
{
- int i;
- get_param_range_V( lower, upper );
- double low_u, high_u, mid_u;
- get_param_range_U( low_u, high_u );
- mid_u = (low_u + high_u) / 2.;
- double delta = ( ( upper - lower ) / 10.0 );
- CubitVector start, end;
- for( i = 0; i < 10; i++ )
- {
- start = this->position_from_u_v( mid_u, (lower+(delta*i)) );
- end = this->position_from_u_v( mid_u, (lower+(delta*(i+1))) );
- length += start.distance_between( end );
- }
+ min_dist = 0;
}
- else
- {
- PRINT_WARNING( "Surface %d is_periodic, but has neither a "
- "u_period or v_period.\n", id() );
- }
- }
- if ( length == 0.0 )
- {
- PRINT_DEBUG_99("Crack length from uv was zero. Trying geometric method.\n");
- //This basically means that this function failed. Lets try another
- //method that may be less generic but will work for map/submap type
- //surfaces where getting this crack length is more important.
- length = find_crack_length_no_uv();
+ PRINT_DEBUG_99("Crack_length is %f\n", min_dist);
+ return min_dist;
}
- PRINT_DEBUG_99("Crack_length is %f\n",length);
- return length;
-}
-double RefFace::find_crack_length_no_uv()
-{
- double length = 0.0;
- //assume that this surface has exactly 2 loops, again this is for
- //map/submap. This function also assumes the surface is periodic.
- //ie, this basically assumes some sort of cylinder wall, torus wall or
- //something that looks like that.
- if ( this->num_loops() != 2 || !this->is_periodic() )
- return length;
- //Pick a point on one of the loops, find the closest point to that on the other
- //loops. Then find the closest point to that point on the first loop. Keep iterating
- //till we have the two closest points between the loops (may not be closest, but they
- //are mutually the closest to each other.).
- DLIList<Loop*> loops;
- this->loops(loops);
- Loop *first_loop = loops.get();
- Loop *other_loop = loops.next();
- RefEdge *tmp_edge = first_loop->co_edge()->get_ref_edge_ptr();
- CubitVector this_point, closest_point;
- // use the mid point of the first curve as the start point.
- if ( tmp_edge->mid_point(this_point) != CUBIT_SUCCESS )
- return length;
- CoEdge *other_co_edge = NULL;
- GeometryUtil *gu = GeometryUtil::instance();
- CoEdge *closest_co_edge = gu->closest_loop_coedge(other_loop, this_point,
- other_co_edge, &closest_point);
- if ( closest_co_edge == NULL )
- return length;
- CubitVector this_closest;
- int counter = 0;
- const int MAX_LOOP_ITR = 6;
- for(;;)
- {
- if ( counter >= MAX_LOOP_ITR )
- break;
- counter++;
- //find a new this_closest from closest_point.
- closest_co_edge = gu->closest_loop_coedge(first_loop, closest_point,
- other_co_edge, &this_closest);
- if ( closest_co_edge == NULL )
- return length;
- if ( (this_point-this_closest).length_squared() <= GEOMETRY_RESABS*GEOMETRY_RESABS )
- break;
- //make this_closest our point.
- this_point = this_closest;
- //get a new closest_point.
- closest_co_edge = gu->closest_loop_coedge(other_loop, this_point,
- other_co_edge, &closest_point);
- if ( closest_co_edge == NULL )
- return length;
- }
- //if we are here we succeeded. Our points are, this_point and closest_point.
- //Now, find some linear steps between these points, move them to the surface,
- //and calculate the length.
- int num_steps = 10;
- //Find the num_steps positions by treating this_point and closest_point as the
- //end points of a curve and parameterizing it...
- int ii;
- double param_step = 1/(double)num_steps;
- double curr_param = param_step;
- CubitVector start_point = this_point;
- CubitVector next_point;
- CubitVector diff_vec = closest_point - this_point;
- for ( ii = 0; ii < num_steps; ii++ )
- {
- next_point = this_point + curr_param*(diff_vec);
- this->move_to_surface(next_point);
- length += (next_point-start_point).length();
- start_point = next_point;
- curr_param += param_step;
- }
- PRINT_INFO("Crack length (no u-v) is = %f\n", length);
-
- return length;
+ PRINT_DEBUG_99("No valid crack length for surface %i\n", this->id());
+ return 0.0;
}
-
CubitVector RefFace::normal_at ( const CubitVector& location,
RefVolume* volume,
double* u_guess, double* v_guess)
@@ -579,7 +255,7 @@
location.x(), location.y(), location.z(),
this->entity_name().c_str(),
this->id());
- assert ( result == CUBIT_SUCCESS );
+ //assert ( result == CUBIT_SUCCESS );
return CubitVector(0.0, 0.0, 0.0);
}
@@ -693,7 +369,6 @@
if ( ref_volume_ptr ) {
CubitSense s = sense( ref_volume_ptr );
- assert( s == CUBIT_FORWARD || s == CUBIT_REVERSED );
if ( s == CUBIT_REVERSED ) {
curvature1 = -curvature1;
curvature2 = -curvature2;
@@ -943,8 +618,11 @@
return CUBIT_FALSE;
}
}
-
- if ( test_internal != 0 )
+
+ //if both lists of edges are zero, this is the concentric sphere or torus case.
+ //must look for a point on the surface then.
+ if ( (ref_edge_list_1.size() == 0 && ref_edge_list_2.size() == 0 ) ||
+ test_internal != 0 )
{
//test a point in the middle.
CubitVector center_1, center_2;
@@ -1442,7 +1120,10 @@
//-------------------------------------------------------------------------
Surface* RefFace::get_surface_ptr()
{
- return CAST_TO(get_geometry_entity_ptr(), Surface);
+ // Just do one cast instead of two -- KGM
+ TopologyBridge* bridge = bridge_manager()->topology_bridge();
+ return CAST_TO(bridge, Surface);
+ //return CAST_TO(get_geometry_entity_ptr(), Surface);
}
const Surface* RefFace::get_surface_ptr() const
@@ -1484,6 +1165,40 @@
}
}
+
+//-------------------------------------------------------------------------
+// Purpose : This function returns CUBIT_TRUE if the underlying
+// geometry of the face is cylindrical. CUBIT_FALSE otherwise.
+//
+// Special Notes :
+//
+// Creator : KGM
+//
+// Creation Date : 03/22/07
+//-------------------------------------------------------------------------
+CubitBoolean RefFace::is_cylindrical()
+{
+ // Cast the generic GeometryEntity pointer to Surface pointer
+ Surface* surfacePtr = this->get_surface_ptr() ;
+
+ // Check if we have a valid Surface. If so, return the result of
+ // querying the Surface if it is planar.
+ if ( surfacePtr != NULL )
+ {
+ GeometryType geo_type;
+ geo_type = surfacePtr->is_cylindrical();
+ return geo_type == CYLINDER_SURFACE_TYPE ? CUBIT_TRUE : CUBIT_FALSE;
+ }
+ else
+ {
+ PRINT_WARNING("In RefFace::is_cylindrical\n"
+ " %s (surface %d) is not associated with a valid\n"
+ " underlying geoemtric Surface\n",
+ entity_name().c_str(), id()) ;
+ return CUBIT_FALSE ;
+ }
+}
+
CubitStatus RefFace::get_point_normal( CubitVector& origin, CubitVector& normal )
{
if( is_planar() == CUBIT_FALSE)
@@ -1626,7 +1341,6 @@
double distance_tolerance,
double longest_edge )
{
- int junk1, junk2, junk3;
Surface* surf_ptr = get_surface_ptr();
if (!surf_ptr)
{
@@ -1635,7 +1349,7 @@
}
return surf_ptr->get_geometry_query_engine()->
- get_graphics(surf_ptr, junk1, junk2, junk3, &facets,
+ get_graphics(surf_ptr, &facets,
normal_tolerance, distance_tolerance, longest_edge );
}
Modified: cgm/branches/cubit/geom/RefFace.hpp
===================================================================
--- cgm/branches/cubit/geom/RefFace.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/RefFace.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -450,6 +450,13 @@
//R CUBIT_TRUE/CUBIT_FALSE
//- This function returns CUBIT_TRUE if the underlying geometry
//- of the face is planar. CUBIT_FALSE otherwise.
+
+ CubitBoolean is_cylindrical();
+ //R CubitBoolean
+ //R CUBIT_TRUE/CUBIT_FALSE
+ //- This function returns CUBIT_TRUE if the underlying geometry
+ //- of the face is conical (cylinders are subsets of cones).
+ //- CUBIT_FALSE otherwise.
CubitStatus get_point_normal( CubitVector& origin, CubitVector& normal );
//- Only valid for planar surfaces
@@ -516,10 +523,6 @@
#endif
int hardPointColor;
- double find_crack_length_no_uv();
- //- returns the crack length of the periodic surface (which can only have
- //- two loops, if there is some problem with the uv space.
-
};
#endif
Modified: cgm/branches/cubit/geom/RefGroup.cpp
===================================================================
--- cgm/branches/cubit/geom/RefGroup.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/RefGroup.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -138,11 +138,7 @@
void RefGroup::get_child_entities(DLIList<CubitEntity*>& cub_entity_list)
{
- entityList.reset();
- DLIList<CubitEntity*> temp_list;
- CAST_LIST_TO_PARENT( entityList, temp_list );
- cub_entity_list.merge_unique(temp_list, CUBIT_TRUE);
-// cub_entity_list.merge_unique(entityList, CUBIT_TRUE);
+ cub_entity_list.casting_merge_unique(entityList, CUBIT_TRUE);
}
void RefGroup::expand_group( DLIList<RefEntity*> & entity_list )
Modified: cgm/branches/cubit/geom/RefVertex.cpp
===================================================================
--- cgm/branches/cubit/geom/RefVertex.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/RefVertex.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -179,6 +179,10 @@
int i;
for (i = temp_list.size(); i > 0; i--) {
RefEdge *common_edge = CAST_TO(temp_list.get(), RefEdge);
+
+ if( NULL == common_edge )
+ continue;
+
//This extra 'if' block is needed in case other_vertex == this
if ( ( common_edge->start_vertex() == other_vertex &&
common_edge->end_vertex() == this) ||
@@ -187,6 +191,8 @@
{
if (common_edge && (!owning_face || common_edge->is_child(owning_face)))
return common_edge;
+ else
+ temp_list.step();
}
else
temp_list.step();
Modified: cgm/branches/cubit/geom/RefVolume.cpp
===================================================================
--- cgm/branches/cubit/geom/RefVolume.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/RefVolume.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -173,6 +173,26 @@
}
}
+CubitStatus RefVolume::mass_properties( CubitVector principal_axes[3],
+ CubitVector &principal_moments,
+ CubitVector ¢roid,
+ double &volume )
+{
+ DLIList<Body*> bodies;
+ this->bodies( bodies );
+ if( bodies.get()->is_sheet_body() )
+ {
+ centroid.set(0,0,0);
+ volume = 0;
+ return CUBIT_SUCCESS;
+ }
+ else
+ {
+ Lump *lump = get_lump_ptr();
+ return lump->mass_properties( principal_axes, principal_moments, centroid, volume );
+ }
+}
+
CubitString RefVolume::measure_label()
{
return "volume";
@@ -367,3 +387,28 @@
return CUBIT_TRUE;
}
+int RefVolume::validate()
+{
+ //- This function determines whether the entity is valid.
+ //- Several types of checks can be done,
+ int error = 0;
+
+ // Perform general RefEntity checks (measure > 0)
+ error += RefEntity::validate();
+
+ // Pass through to surface and add in its validation
+ Lump *lump = this->get_lump_ptr();
+
+ // check surface ptr
+ if (lump != NULL) {
+ // Check underlying surface
+ DLIList <TopologyEntity*> bad_entities;
+ error += lump->validate(entity_name(), bad_entities);
+ } else {
+ PRINT_WARNING("\tWARNING: Null underlying volume for %s, (%s %d)\n",
+ entity_name().c_str(), class_name(), id());
+ error++;
+ }
+ return error;
+}
+
Modified: cgm/branches/cubit/geom/RefVolume.hpp
===================================================================
--- cgm/branches/cubit/geom/RefVolume.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/RefVolume.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -47,6 +47,7 @@
// ********** END FORWARD DECLARATIONS **********
+//! RefVolume class.
class CUBIT_GEOM_EXPORT RefVolume : public BasicTopologyEntity
{
public :
@@ -60,70 +61,89 @@
//- The destructor
/* topology */
-
+
+ //! Gets the dag type.
DagType dag_type() const { return DagType::ref_volume_type(); }
+
+ //! Gets the type info of this RefVolume.
const type_info& entity_type_info() const { return typeid(RefVolume); }
+ //! Gets the class name for a volume: "Volume".
static const char* get_class_name()
- {
- return "Volume";
- }
+ {
+ return "Volume";
+ }
+ //! Gets the class name for a volume: "Volume".
virtual const char* class_name() const
- {
- return get_class_name();
- }
+ {
+ return get_class_name();
+ }
+ //! Gets the lump pointer.
Lump* get_lump_ptr() ;
+
+ //!R Lump*
+ //!R- A pointer to the Lump to which the current
+ //!R- volume points.
+ //! This function returns a pointer to the Lump
+ //! to which the current volume points.
Lump const* get_lump_ptr() const ;
- //R Lump*
- //R- A pointer to the Lump to which the current
- //R- volume points.
- //- This function returns a pointer to the Lump
- //- to which the current volume points.
+ //! Gets the owning Body of this RefVolume.
Body* get_body_ptr() ;
+ //! Return the number of connected components bounding this volume.
+ //! Note: this counts the number of ref_edge-connected ref_face
+ //! components, which may not be the same as the number of acis shells.
int num_boundary_components();
- //- Return the number of connected components bounding this volume.
- //- Note: this counts the number of ref_edge-connected ref_face
- //- components, which may not be the same as the number of acis shells.
+ //!R CubitBoolean
+ //!R-CUBIT_TRUE/CUBIT_FALSE
+ //!I RefVolume*
+ //!O CubitBoolean
+ //!O- If the two RefVolumes are spatially equal within the GEOMETRY_RESABS*
+ //! the tolerance_factor, then CUBIT_TRUE will be returned. Otherwise
+ //! CUBIT_FALSE is returned.
+ //! The comparison is done by checking the bounding boxes of the
+ //! RefVolumes.
CubitBoolean about_spatially_equal ( RefVolume* ref_vol_ptr_2,
double tolerance_factor);
- //R CubitBoolean
- //R-CUBIT_TRUE/CUBIT_FALSE
- //I RefVolume*
- //O CubitBoolean
- //O- If the two RefVolumes are spatially equal within the GEOMETRY_RESABS*
- //- the tolerance_factor, then CUBIT_TRUE will be returned. Otherwise
- //- CUBIT_FALSE is returned.
- //- The comparison is done by checking the bounding boxes of the
- //- RefVolumes.
+ //! returns the genus of the volume, where
+ //! g = 1 - .5(v - e + f - gs), and v,e,f = # vertices, edges, faces,
+ //! and gs = summed genus of surfaces
int genus();
- //- returns the genus of the volume, where
- //- g = 1 - .5(v - e + f - gs), and v,e,f = # vertices, edges, faces,
- //- and gs = summed genus of surfaces
/* geometry */
+ //! Returns centroid of the RefVolume
virtual CubitVector center_point();
- //- Returns centroid of the RefVolume
+ //! Returns true if all Shells of RefVolume are sheets.
CubitBoolean is_sheet();
- //- Returns true if all Shells of RefVolume are sheets.
//**********Graphics Related Functions**********//
+
+ //! returns dimension of the actual entity.
virtual int dimension() const;
- //- returns dimension of the actual entity.
/* other functions */
virtual CubitString measure_label();
+ //@{
+ //! Get the mass properties from the underlying lump
CubitStatus mass_properties( CubitVector ¢roid, double &volume );
+ CubitStatus mass_properties( CubitVector principal_axes[3],
+ CubitVector &principal_moments,
+ CubitVector ¢roid,
+ double &volume );
+ //@}
+ //! Do a an api entity check.
+ int validate();
+
protected:
RefVolume(Lump* lumpPtr) ;
Modified: cgm/branches/cubit/geom/SenseEntity.hpp
===================================================================
--- cgm/branches/cubit/geom/SenseEntity.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/SenseEntity.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -192,7 +192,7 @@
CubitStatus SenseEntity::gpe_insert_before(SenseEntity* next_ptr)
{
- prevInParent = prevInParent;
+ prevInParent = next_ptr->prevInParent;
if (prevInParent)
prevInParent->nextInParent = this;
nextInParent = next_ptr;
Modified: cgm/branches/cubit/geom/SplitSurfaceTool.cpp
===================================================================
--- cgm/branches/cubit/geom/SplitSurfaceTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/SplitSurfaceTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -1,14 +1,15 @@
//-------------------------------------------------------------------------
// Filename : SplitSurfaceTool.cpp
//
-// Purpose : Split a single or chain of surfaces (ie., split a fillet
-// down the middle so that a mesh sweep can occur). Used by
-// the "split surface" commands.
+// Purpose : Split a single or chain of surfaces (e.g., split a fillet
+// down the middle so that a mesh sweep can occur, or split
+// across a surface). Used by the "split surface" commands.
//
// Split Surface <id> Across [Pair] Location <options multiple locs>
// [Preview [Create]]
// Split Surface <id> Across Location <multiple locs> Onto Curve <id>
// [Preview [Create]]
+// Split Surface <id_list> Extend [Vertex <id_list> | Auto] [Preview [Create]]
//
// Split Surface <id_list> [Corner Vertex <id_list>] [Direction Curve <id>]
// [Segment <val> | Fraction|Distance <val> [From Curve <id>]]
@@ -38,6 +39,7 @@
#include "DLIList.hpp"
#include "TDSplitSurface.hpp"
#include "GfxDebug.hpp"
+#include "GfxPreview.hpp"
#include "Cubit2DPoint.hpp"
#include "GMem.hpp"
#include "SettingHandler.hpp"
@@ -55,6 +57,9 @@
CubitBoolean SplitSurfaceTool::autoDetectTriangles = CUBIT_TRUE;
double SplitSurfaceTool::sideAngleThreshold = 27.0; // From 180
double SplitSurfaceTool::pointAngleThreshold = 45.0; // Below is a point
+double SplitSurfaceTool::extendGapThreshold = CUBIT_DBL_MAX;
+CubitBoolean SplitSurfaceTool::extendNormalFlg = CUBIT_FALSE;
+double SplitSurfaceTool::extendTolerance = .1;
SplitSurfaceTool::SplitSurfaceTool()
{
@@ -90,23 +95,54 @@
SettingHandler::instance()->add_setting("Split Surface Point Angle Threshold",
SplitSurfaceTool::set_point_angle_threshold,
SplitSurfaceTool::get_point_angle_threshold);
+
+ SettingHandler::instance()->add_setting("Split Surface Extend Gap Threshold",
+ SplitSurfaceTool::set_extend_gap_threshold,
+ SplitSurfaceTool::get_extend_gap_threshold);
+
+ SettingHandler::instance()->add_setting("Split Surface Extend Tolerance",
+ SplitSurfaceTool::set_extend_tolerance,
+ SplitSurfaceTool::get_extend_tolerance);
+
+ SettingHandler::instance()->add_setting("Split Surface Extend Normal",
+ SplitSurfaceTool::set_extend_normal_flg,
+ SplitSurfaceTool::get_extend_normal_flg);
}
CubitStatus
SplitSurfaceTool::preview( RefFace *ref_face_ptr,
DLIList<CubitVector*> &locations,
DLIList<DLIList<CubitVector*>*> &vec_lists,
- CubitBoolean create_ref_edges_flg )
+ CubitBoolean create_ref_edges_flg,
+ CubitBoolean clear_previous_previews )
{
// Create curves from the input vec_lists (locations are just the original
// locations the user specified - these need to be drawn)
- int i;
+ int i, j;
Curve *curve_ptr;
DLIList<CubitVector*> *vec_list_ptr;
vec_lists.reset();
+ DLIList<Surface*> surfs;
Surface *surf_ptr = ref_face_ptr->get_surface_ptr();
+ // Support composite surfaces by getting the surfaces underlying
+ // the composite and creating split curves for them individually.
+ GeometryQueryEngine *gqe = surf_ptr->get_geometry_query_engine();
+ DLIList<TopologyBridge*> tbs;
+ gqe->get_underlying_surfaces(surf_ptr, tbs);
+ if(tbs.size() > 0)
+ {
+ for(j=tbs.size(); j>0; j--)
+ surfs.append(dynamic_cast<Surface*>(tbs.get_and_step()));
+ }
+ else
+ surfs.append(surf_ptr);
+
+ // Clear previous previews if necessary
+ if( clear_previous_previews == CUBIT_TRUE )
+ GfxPreview::clear();
+
for( i=vec_lists.size(); i--; )
{
vec_list_ptr = vec_lists.get_and_step();
@@ -118,21 +154,112 @@
continue;
}
- curve_ptr = create_curve( *vec_list_ptr, surf_ptr );
+ for(j=surfs.size(); j>0; j--)
+ {
+ Surface *cur_surf = surfs.get_and_step();
+ curve_ptr = create_curve( *vec_list_ptr, cur_surf );
- if( curve_ptr )
- {
- if( create_ref_edges_flg == CUBIT_TRUE )
+ if( curve_ptr )
{
- GeometryQueryTool::instance()->make_free_RefEdge(curve_ptr);
+ if( create_ref_edges_flg == CUBIT_TRUE )
+ {
+ RefEdge *ref_edge_ptr;
+ ref_edge_ptr = GeometryQueryTool::instance()->make_free_RefEdge(curve_ptr);
+ if( ref_edge_ptr )
+ PRINT_INFO( "Created new curve %d\n", ref_edge_ptr->id() );
+ }
+ else
+ {
+ draw_preview( curve_ptr, CUBIT_FALSE );
+ curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
+ }
}
+ }
+ }
+
+ // Draw locations too
+ draw_points( locations, CUBIT_BLUE );
+
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus
+SplitSurfaceTool::preview( DLIList<RefFace*> &ref_face_list,
+ DLIList<CubitVector*> &locations,
+ DLIList<DLIList<DLIList<CubitVector*>*>*> &list_of_vec_lists,
+ CubitBoolean create_ref_edges_flg,
+ CubitBoolean clear_previous_previews )
+{
+ //Reset ref_face_list and list_of_vec_lists (just in case)
+ ref_face_list.reset();
+ list_of_vec_lists.reset();
+
+ // Clear previous previews if necessary
+ if( clear_previous_previews == CUBIT_TRUE )
+ GfxPreview::clear();
+
+ int qq;
+ for( qq = ref_face_list.size(); qq > 0 ; qq--)
+ {
+ //Initialize the values to be used upon each iteration
+ RefFace* ref_face_ptr = ref_face_list.get_and_step();
+ DLIList<DLIList<CubitVector*>*> vec_lists = *( list_of_vec_lists.get_and_step() );
+
+ int i, j;
+ Curve *curve_ptr;
+ DLIList<CubitVector*> *vec_list_ptr;
+ vec_lists.reset();
+ DLIList<Surface*> surfs;
+
+ Surface *surf_ptr = ref_face_ptr->get_surface_ptr();
+
+ // Support composite surfaces by getting the surfaces underlying
+ // the composite and creating split curves for them individually.
+ GeometryQueryEngine *gqe = surf_ptr->get_geometry_query_engine();
+ DLIList<TopologyBridge*> tbs;
+ gqe->get_underlying_surfaces(surf_ptr, tbs);
+ if(tbs.size() > 0)
+ {
+ for(j=tbs.size(); j>0; j--)
+ surfs.append(dynamic_cast<Surface*>(tbs.get_and_step()));
+ }
else
+ surfs.append(surf_ptr);
+
+ for( i=vec_lists.size(); i--; )
{
- draw_preview( curve_ptr, CUBIT_FALSE );
- curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
+ vec_list_ptr = vec_lists.get_and_step();
+
+ vec_list_ptr->reset();
+ if( vec_list_ptr->size() < 2 )
+ {
+ PRINT_ERROR( "Unable to create a curve from less than two locations.\n" );
+ continue;
+ }
+
+ for(j=surfs.size(); j>0; j--)
+ {
+ Surface *cur_surf = surfs.get_and_step();
+ curve_ptr = create_curve( *vec_list_ptr, cur_surf );
+
+ if( curve_ptr )
+ {
+ if( create_ref_edges_flg == CUBIT_TRUE )
+ {
+ RefEdge *ref_edge_ptr;
+ ref_edge_ptr = GeometryQueryTool::instance()->make_free_RefEdge(curve_ptr);
+ if( ref_edge_ptr )
+ PRINT_INFO( "Created new curve %d\n", ref_edge_ptr->id() );
+ }
+ else
+ {
+ draw_preview( curve_ptr, CUBIT_FALSE );
+ curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
+ }
+ }
+ }
}
- }
- }
+ }
// Draw locations too
draw_points( locations, CUBIT_BLUE );
@@ -145,20 +272,24 @@
// created curves when it is done with them.
CubitStatus
SplitSurfaceTool::calculate_split_curves( RefFace *ref_face_ptr,
- DLIList<CubitVector*> &locations,
DLIList<DLIList<CubitVector*>*> &vec_lists,
DLIList<Curve*>& curve_list )
{
- // Create curves from the input vec_lists (locations are just the original
- // locations the user specified - these need to be drawn). NOTE: drawing
- // the locations was removed 6/16/05 per Sandia request.
+ Surface *surf_ptr = ref_face_ptr->get_surface_ptr();
+
+ return calculate_split_curves(surf_ptr, vec_lists, curve_list);
+}
+
+CubitStatus
+SplitSurfaceTool::calculate_split_curves( Surface *surf_ptr,
+ DLIList<DLIList<CubitVector*>*> &vec_lists,
+ DLIList<Curve*>& curve_list )
+{
int i;
Curve *curve_ptr;
DLIList<CubitVector*> *vec_list_ptr;
vec_lists.reset();
- Surface *surf_ptr = ref_face_ptr->get_surface_ptr();
-
for( i=vec_lists.size(); i--; )
{
vec_list_ptr = vec_lists.get_and_step();
@@ -206,6 +337,9 @@
return CUBIT_FAILURE;
}
+ // Clear any previews
+ GfxPreview::clear();
+
// Perform the split on the real (e.g. ACIS) geometry.
Surface *surf_ptr = ref_face_ptr->get_surface_ptr();
@@ -226,10 +360,6 @@
while( curve_list.size() )
delete curve_list.pop();
-
- // TODO: Need to find a better place to do the drawing. Should not be
- // using debug graphics to do previews or highlights from within CGM.
- // This could create unwanted dependencies between CGM and the graphics.
// Draw locations too
// draw_points( locations, CUBIT_BLUE );
@@ -251,14 +381,12 @@
CubitStatus
SplitSurfaceTool::split_surface( RefFace *ref_face_ptr,
- DLIList<CubitVector*> &locations,
DLIList<DLIList<CubitVector*>*> &vec_lists )
{
// Count number of surfaces in owning body prior to split - this is used to
// determine if split is actually successful.
Body *body_ptr;
int num_surfaces_prior = count_surfaces_in_owning_body( ref_face_ptr, body_ptr );
- int num_curves_prior = count_curves_in_body( body_ptr );
if( num_surfaces_prior == -1 )
{
PRINT_ERROR( "Cannot split a surface that is not part of a volume\n" );
@@ -269,39 +397,89 @@
PRINT_ERROR( "Cannot split a surface that is contained by multiple volumes\n" );
return CUBIT_FAILURE;
}
+ int num_curves_prior = count_curves_in_body( body_ptr );
+ int original_id = ref_face_ptr->id();
+ Surface *surf_ptr = ref_face_ptr->get_surface_ptr();
+
+ // Clear any previews
+ GfxPreview::clear();
+
// Find the splitting curves
- DLIList<Curve*> curve_list;
- CubitStatus err = calculate_split_curves( ref_face_ptr, locations,
- vec_lists, curve_list );
+ DLIList<DLIList<Curve*>*> curve_lists_list;
+
+ // Support composite surfaces by getting the surfaces underlying
+ // the composite and creating split curves for them individually.
+ GeometryQueryEngine *gqe = surf_ptr->get_geometry_query_engine();
+ DLIList<TopologyBridge*> tbs;
+ gqe->get_underlying_surfaces(surf_ptr, tbs);
+ CubitStatus err = CUBIT_SUCCESS;
+ if(tbs.size() > 0)
+ {
+ err = CUBIT_FAILURE;
+ for(int k=tbs.size(); k>0; k--)
+ {
+ Surface *srf = dynamic_cast<Surface*>(tbs.get_and_step());
+ if(srf)
+ {
+ DLIList<Curve*> *curve_list = new DLIList<Curve*>;
+ CubitStatus tmp_status = calculate_split_curves( srf, vec_lists, *curve_list );
+ // If at least one split is successful return success. We anticipate that some curves
+ // won't imprint on some of the underlying surfaces of the composite surface. Because
+ // we are allowing success this way there are sometimes errors that get printed even
+ // though we are calling it a success. Need to find a good way to fix this.
+ if(tmp_status)
+ err = CUBIT_SUCCESS;
+ curve_lists_list.append(curve_list);
+ }
+ }
+ }
+ else
+ {
+ DLIList<Curve*> *curve_list = new DLIList<Curve*>;
+ err = calculate_split_curves( ref_face_ptr, vec_lists, *curve_list );
+ curve_lists_list.append(curve_list);
+ }
+
if( err == CUBIT_FAILURE )
+ {
+ while(curve_lists_list.size())
+ {
+ DLIList<Curve*> *cur_list = curve_lists_list.pop();
+ while(cur_list->size())
+ delete cur_list->pop();
+ delete cur_list;
+ }
return CUBIT_FAILURE;
+ }
// Perform the split on the real (e.g. ACIS) geometry.
- Surface *surf_ptr = ref_face_ptr->get_surface_ptr();
-
DLIList<Surface*> surface_list;
surface_list.append( surf_ptr );
- DLIList<DLIList<Curve*>*> curve_lists_list;
- curve_lists_list.append( &curve_list );
Body *new_body_ptr;
if( GeometryModifyTool::instance()->imprint( surface_list,
curve_lists_list, new_body_ptr ) == CUBIT_FAILURE )
{
- while( curve_list.size() )
- delete curve_list.pop();
+ while(curve_lists_list.size())
+ {
+ DLIList<Curve*> *cur_list = curve_lists_list.pop();
+ while(cur_list->size())
+ delete cur_list->pop();
+ delete cur_list;
+ }
return CUBIT_FAILURE;
}
- while( curve_list.size() )
- delete curve_list.pop();
+ while(curve_lists_list.size())
+ {
+ DLIList<Curve*> *cur_list = curve_lists_list.pop();
+ while(cur_list->size())
+ delete cur_list->pop();
+ delete cur_list;
+ }
- // TODO: Need to find a better place to do the drawing. Should not be
- // using debug graphics to do previews or highlights from within CGM.
- // This could create unwanted dependencies between CGM and the graphics.
-
// Draw locations too
//draw_points( locations, CUBIT_BLUE );
@@ -316,10 +494,144 @@
return CUBIT_SUCCESS;
}
- PRINT_ERROR( "Split failed - surface %d was not split\n", ref_face_ptr->id() );
+ PRINT_ERROR( "Split failed - surface %d was not split\n", original_id );
return CUBIT_FAILURE;
}
+//ADDED BY GJS (CAT) 6/26/08 @ 11:00am
+CubitStatus
+SplitSurfaceTool::split_surface( DLIList<RefFace*> &ref_face_list,
+ DLIList<DLIList<DLIList<CubitVector*>*>*> &list_of_vec_lists )
+{
+ //Initialize inputs to imprint function call
+ DLIList<Surface*> surface_list;
+ DLIList<DLIList<Curve*>*> curve_lists_list;
+ // Clear any previews
+ GfxPreview::clear();
+
+ //Reset all lists
+ ref_face_list.reset();
+ list_of_vec_lists.reset();
+
+ int hh;
+ for( hh = ref_face_list.size() ; hh > 0 ; hh--)
+ {
+ // Count number of surfaces in owning body prior to split - this is used to
+ // determine if split is actually successful. 0
+ RefFace* ref_face_ptr = ref_face_list.get_and_step();
+ Body* body_ptr;
+
+ int num_surfaces_prior = count_surfaces_in_owning_body( ref_face_ptr, body_ptr );
+ if( num_surfaces_prior == -1 )
+ {
+ PRINT_ERROR( "Cannot split a surface that is not part of a volume\n" );
+ return CUBIT_FAILURE;
+ }
+ else if( num_surfaces_prior == -2 )
+ {
+ PRINT_ERROR( "Cannot split a surface that is contained by multiple volumes\n" );
+ return CUBIT_FAILURE;
+ }
+ int num_curves_prior = count_curves_in_body( body_ptr );
+
+ int original_id = ref_face_ptr->id();
+ Surface *surf_ptr = ref_face_ptr->get_surface_ptr();
+
+
+
+ // Support composite surfaces by getting the surfaces underlying
+ // the composite and creating split curves for them individually.
+ GeometryQueryEngine *gqe = surf_ptr->get_geometry_query_engine();
+ DLIList<TopologyBridge*> tbs;
+ gqe->get_underlying_surfaces(surf_ptr, tbs);
+ CubitStatus err = CUBIT_SUCCESS;
+ if(tbs.size() > 0)
+ {
+ err = CUBIT_FAILURE;
+ for(int k=tbs.size(); k>0; k--)
+ {
+ Surface *srf = dynamic_cast<Surface*>(tbs.get_and_step());
+ if(srf)
+ {
+ DLIList<Curve*> *curve_list = new DLIList<Curve*>;
+ DLIList<DLIList<CubitVector*>*> temp_vec_lists = *( list_of_vec_lists.get_and_step() );
+ CubitStatus tmp_status = calculate_split_curves( srf, temp_vec_lists, *curve_list );
+ // If at least one split is successful return success. We anticipate that some curves
+ // won't imprint on some of the underlying surfaces of the composite surface. Because
+ // we are allowing success this way there are sometimes errors that get printed even
+ // though we are calling it a success. Need to find a good way to fix this.
+ if(tmp_status)
+ err = CUBIT_SUCCESS;
+ curve_lists_list.append(curve_list);
+ }
+ }
+ }
+ else
+ {
+ DLIList<Curve*> *curve_list = new DLIList<Curve*>;
+ DLIList<DLIList<CubitVector*>*> temp_vec_lists = *( list_of_vec_lists.get_and_step() );
+ err = calculate_split_curves( ref_face_ptr, temp_vec_lists, *curve_list );
+ curve_lists_list.append(curve_list);
+ }
+
+ if( err == CUBIT_FAILURE )
+ {
+ while(curve_lists_list.size())
+ {
+ DLIList<Curve*> *cur_list = curve_lists_list.pop();
+ while(cur_list->size())
+ delete cur_list->pop();
+ delete cur_list;
+ }
+ return CUBIT_FAILURE;
+ }
+
+ surface_list.append( surf_ptr );
+ }
+
+ // Perform the split on the real (e.g. ACIS) geometry.
+ Body *new_body_ptr;
+
+ if( GeometryModifyTool::instance()->imprint( surface_list,
+ curve_lists_list, new_body_ptr ) == CUBIT_FAILURE )
+ {
+ while(curve_lists_list.size())
+ {
+ DLIList<Curve*> *cur_list = curve_lists_list.pop();
+ while(cur_list->size())
+ delete cur_list->pop();
+ delete cur_list;
+ }
+ return CUBIT_FAILURE;
+ }
+
+ while(curve_lists_list.size())
+ {
+ DLIList<Curve*> *cur_list = curve_lists_list.pop();
+ while(cur_list->size())
+ delete cur_list->pop();
+ delete cur_list;
+ }
+
+ //NOTE: current assumption is failure will not occur since user does not
+ // control input parameters to this function (may need to fix).
+ //int num_surfaces_after = count_surfaces_in_body( body_ptr );
+
+ //if( num_surfaces_after > num_surfaces_prior )
+ // return CUBIT_SUCCESS;
+ //else
+ //{
+ // int num_curves_after = count_curves_in_body( body_ptr );
+ // if( num_curves_after > num_curves_prior )
+ // return CUBIT_SUCCESS;
+ //}
+
+ //PRINT_ERROR( "Split failed - surface %d was not split\n", original_id );
+ //return CUBIT_FAILURE;
+
+ return CUBIT_SUCCESS;
+}
+
CubitStatus
SplitSurfaceTool::draw_points( DLIList<CubitVector*> &pnt_list, int color,
int flush )
@@ -333,7 +645,7 @@
if( flush )
{
- GfxDebug::flush();
+ GfxPreview::flush();
}
return CUBIT_SUCCESS;
@@ -342,10 +654,10 @@
CubitStatus
SplitSurfaceTool::draw_point( CubitVector &pnt, int color, int flush )
{
- GfxDebug::draw_point( pnt, color );
+ GfxPreview::draw_point( pnt, color );
if( flush )
{
- GfxDebug::flush();
+ GfxPreview::flush();
}
return CUBIT_SUCCESS;
}
@@ -367,6 +679,9 @@
CubitBoolean just_curves_flg = CUBIT_FALSE;
DLIList<DLIList<Curve*>*> curve_lists_list;
+ // Clear any previous previews
+ GfxPreview::clear();
+
// Call the primary function
status = split_surfaces( ref_face_list, num_segs, fraction, distance,
from_curve_ptr, corner_vertex_list,
@@ -643,6 +958,9 @@
// Now build up the coordinates and get the curve(s) for each surface
// curve_lists_list will contain a list of curve lists for each surface
+ // Keep track of new RefEdges created
+ DLIList<RefEdge*> new_ref_edge_list;
+
TDSplitSurface *tdss;
refFaceChain.reset();
for(i=refFaceChain.size(); i--; )
@@ -690,14 +1008,23 @@
draw_preview( *curve_list_ptr );
else
{
- create_ref_edges( *curve_list_ptr );
+ create_ref_edges( *curve_list_ptr, new_ref_edge_list );
// This just draws each curve as we go, same as preview does
- GfxDebug::flush();
+ GfxPreview::flush();
}
}
}
+ // Let the user know if new curves were created
+ if( preview_flg == CUBIT_TRUE && create_ref_edges_flg == CUBIT_TRUE
+ && new_ref_edge_list.size() )
+ {
+ DLIList<CubitEntity*> cubit_entity_list;
+ CAST_LIST( new_ref_edge_list, cubit_entity_list, CubitEntity );
+ CubitUtil::list_entity_ids( "Created new curves: ", cubit_entity_list );
+ }
+
// Determine if all of the 'through' vertices were used - if not give a warning
if( throughVertexList.size() )
{
@@ -3802,7 +4129,7 @@
}
CubitStatus
-SplitSurfaceTool::check_through_vertices( char *type )
+SplitSurfaceTool::check_through_vertices( const char *type )
{
if( throughVertexList.size() )
{
@@ -4483,8 +4810,9 @@
// Free matrix memory
for( i=0; i<nr; i++ )
- delete coords[i];
- delete coords;
+ delete []coords[i];
+ delete []coords;
+ coords = NULL;
}
else
{
@@ -4558,8 +4886,9 @@
// Free matrix memory
for( i=0; i<nr; i++ )
- delete coords[i];
- delete coords;
+ delete []coords[i];
+ delete []coords;
+ coords = NULL;
}
return CUBIT_SUCCESS;
@@ -5020,8 +5349,9 @@
delete frac_coords[r][c];
}
for( r=0; r<nr; r++ )
- delete frac_coords[r];
- delete frac_coords;
+ delete []frac_coords[r];
+ delete []frac_coords;
+ frac_coords = NULL;
return CUBIT_FAILURE;
}
@@ -5058,8 +5388,9 @@
delete frac_coords[r][c];
}
for( r=0; r<nr; r++ )
- delete frac_coords[r];
- delete frac_coords;
+ delete []frac_coords[r];
+ delete []frac_coords;
+ frac_coords = NULL;
return CUBIT_FAILURE;
}
@@ -5107,9 +5438,10 @@
// Free matrix memory
for( r=0; r<nr; r++ )
- delete frac_coords[r];
- delete frac_coords;
-
+ delete []frac_coords[r];
+ delete []frac_coords;
+ frac_coords = NULL;
+
// Free spline
curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
return CUBIT_FAILURE;
@@ -5131,9 +5463,10 @@
// Free matrix memory
for( r=0; r<nr; r++ )
- delete frac_coords[r];
- delete frac_coords;
-
+ delete []frac_coords[r];
+ delete []frac_coords;
+ frac_coords = NULL;
+
// Free backup coords
while( backup_coords.size() )
delete backup_coords.pop();
@@ -5402,14 +5735,15 @@
{
int i;
Curve *curve_ptr;
- curve_list.reset();
+ curve_list.reset();
+
for( i=curve_list.size(); i--; )
{
curve_ptr = curve_list.get_and_step();
draw_preview( curve_ptr, CUBIT_FALSE, color );
}
- GfxDebug::flush();
+ GfxPreview::flush();
return CUBIT_SUCCESS;
}
@@ -5418,37 +5752,39 @@
SplitSurfaceTool::draw_preview( Curve *curve_ptr, CubitBoolean flush,
int color )
{
- int num_points;
CubitStatus result;
GMem g_mem;
// get the graphics
result = curve_ptr->get_geometry_query_engine()->
- get_graphics( curve_ptr, num_points, &g_mem );
+ get_graphics( curve_ptr, &g_mem );
- if (result==CUBIT_FAILURE || num_points == 0)
+ if (result==CUBIT_FAILURE || g_mem.pointListCount == 0)
{
PRINT_WARNING("Unable to preview a curve\n" );
}
// Draw the polyline
- GfxDebug::draw_polyline( g_mem.point_list(), g_mem.pointListCount, color );
+ GfxPreview::draw_polyline( g_mem.point_list(), g_mem.pointListCount, color );
if( flush )
- GfxDebug::flush();
+ GfxPreview::flush();
return CUBIT_SUCCESS;
}
CubitStatus
-SplitSurfaceTool::create_ref_edges( DLIList<Curve*> &curve_list )
+SplitSurfaceTool::create_ref_edges( DLIList<Curve*> &curve_list,
+ DLIList<RefEdge*> &ref_edge_list )
{
int i;
Curve *curve_ptr;
+ RefEdge *ref_edge_ptr;
curve_list.reset();
for( i=curve_list.size(); i--; )
{
curve_ptr = curve_list.get_and_step();
- GeometryQueryTool::instance()->make_free_RefEdge(curve_ptr);
+ ref_edge_ptr = GeometryQueryTool::instance()->make_free_RefEdge(curve_ptr);
+ if( ref_edge_ptr ) ref_edge_list.append( ref_edge_ptr );
}
return CUBIT_SUCCESS;
}
@@ -5482,7 +5818,7 @@
if (NULL == gme)
{
- PRINT_ERROR("No geometry modify engine available. Unable to create split curve.");
+ PRINT_ERROR("No geometry modify engine available. Unable to create split curve.\n");
return NULL;
}
@@ -5640,26 +5976,22 @@
PRINT_DEBUG_154( "Inserted %d points when creating spline\n", insert_num );
}
- if( surf_ptr->geometry_type() != PLANE_SURFACE_TYPE &&
- project_curve == CUBIT_TRUE )
+ // Project the spline to the surface (if the surface is not planar)
+ DLIList<Surface*> surf_list;
+ surf_list.append( surf_ptr );
+ DLIList<Curve*> curve_list;
+ curve_list.append( curve_ptr );
+ DLIList<Curve*> curve_list_new;
+
+ if( gme->project_edges( surf_list, curve_list, curve_list_new ) == CUBIT_FAILURE )
{
- // Project the spline to the surface (if the surface is not planar)
- DLIList<Surface*> surf_list;
- surf_list.append( surf_ptr );
- DLIList<Curve*> curve_list;
- curve_list.append( curve_ptr );
- DLIList<Curve*> curve_list_new;
-
- if( gme->project_edges( surf_list, curve_list, curve_list_new ) == CUBIT_FAILURE )
- {
- PRINT_WARNING( "Unable to project curve to surface - split may fail\n" );
- }
- else
- {
- curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
- curve_ptr = curve_list_new.get();
- }
+ PRINT_WARNING( "Unable to project curve to surface - split may fail\n" );
}
+ else
+ {
+ curve_ptr->get_geometry_query_engine()->delete_solid_model_entities(curve_ptr );
+ curve_ptr = curve_list_new.get();
+ }
if( curve_ptr && draw_pnts == CUBIT_TRUE )
{
@@ -5700,7 +6032,7 @@
check_pnt.set( start_pnt.x() + .25 * (end_pnt.x() - start_pnt.x()),
start_pnt.y() + .25 * (end_pnt.y() - start_pnt.y()),
start_pnt.z() + .25 * (end_pnt.z() - start_pnt.z()) );
- if( is_point_on_surface( surf_ptr, check_pnt, GEOMETRY_RESABS ) == CUBIT_FALSE )
+ if( is_point_on_surface( surf_ptr, check_pnt, GEOMETRY_RESABS ) == CUBIT_FALSE )
return CUBIT_FALSE;
check_pnt.set( start_pnt.x() + .5 * (end_pnt.x() - start_pnt.x()),
@@ -6319,3 +6651,612 @@
return ref_edge_list.size();
}
+CubitStatus
+SplitSurfaceTool::split_surfaces_extend( DLIList<RefFace*> &ref_face_list,
+ DLIList<RefVertex*> &ref_vertex_list,
+ CubitBoolean preview_flg,
+ CubitBoolean create_ref_edges_flg )
+{
+ // In the below code, "manual" mode refers to when vertices are passed in. In
+ // this mode, an extension must occur from each given vertex for success.
+ // "Auto" mode refers to when no vertices are passed in. In this mode the
+ // vertices (curves to extend) are found automatically - the ends of
+ // hardlines. Only in auto mode are the gap threshold and normal settings
+ // valid.
+ int i, j;
+ RefFace *ref_face_ptr;
+ RefVertex *ref_vertex_ptr;
+ GeometryModifyEngine *gme;
+ TDSplitSurfaceExtend *tdsse = 0;
+
+ // Clear previous graphics previews
+ GfxPreview::clear();
+
+ CubitBoolean auto_flg = CUBIT_TRUE;
+ if( ref_vertex_list.size() )
+ auto_flg = CUBIT_FALSE;
+
+ // Copy input face list since we don't want to modify it
+ DLIList<RefFace*> copied_ref_face_list = ref_face_list;
+
+ // Check for errors
+ copied_ref_face_list.reset();
+ for( i=copied_ref_face_list.size(); i--; )
+ {
+ ref_face_ptr = copied_ref_face_list.get();
+
+ // Check for free and merged surfaces... for both manual and auto cases.
+ // (we make this fatal for the auto case too since the user can correct
+ // these and may not even know about them)
+ DLIList<Body*> body_list;
+ ref_face_ptr->bodies( body_list );
+ if( body_list.size()==0 )
+ {
+ PRINT_ERROR( "Surface %d is not contained within a parent body.\n"
+ " It cannot be split.\n", ref_face_ptr->id() );
+ return CUBIT_FAILURE;
+ }
+ else if( body_list.size() > 1 )
+ {
+ PRINT_ERROR( "Surface %d is merged and cannot be split.\n",
+ ref_face_ptr->id() );
+ return CUBIT_FAILURE;
+ }
+
+ // Check for nonplanar surface. For auto case, just remove these, but
+ // for manual case, give a fatal error.
+ if( ref_face_ptr->is_planar() == CUBIT_FALSE )
+ {
+ if( auto_flg == CUBIT_TRUE )
+ {
+ copied_ref_face_list.change_to( NULL );
+ copied_ref_face_list.step();
+ continue;
+ }
+ else
+ {
+ // Error out
+ PRINT_ERROR( "The 'split across extend' command only works on planar surfaces.\n"
+ " Surface %d is nonplanar\n", ref_face_ptr->id() );
+ return CUBIT_FAILURE;
+ }
+ }
+ copied_ref_face_list.step();
+ }
+
+ copied_ref_face_list.remove_all_with_value( NULL );
+
+ // If we don't have any faces left, we exit (could only occur for auto case...
+ // make this a warning instead of an error).
+ if( !copied_ref_face_list.size() )
+ {
+ PRINT_WARNING( "No valid surfaces found to be split. Note to be split, they\n"
+ " must be nonplanar, contained in a body, and not merged.\n" );
+ return CUBIT_SUCCESS;
+ }
+
+ // Mark each of the input vertices with a tooldata
+ ref_vertex_list.reset();
+ for( i=ref_vertex_list.size(); i--; )
+ {
+ ref_vertex_ptr = ref_vertex_list.get_and_step();
+ ref_vertex_ptr->add_TD( new TDSplitSurfaceExtend() );
+ }
+
+ // Store list of faces and new curves sorted by body and face
+ DLIList<DLIList<Surface*>*> body_surf_list_list;
+ DLIList<DLIList<DLIList<Curve*>*>*> curve_lists_lists_list;
+
+ // Store ids of Curves that are extended
+ DLIList<int> ext_curve_ids;
+
+ // Operate by common body - pull faces out of the input face list that are
+ // from a common Body and place them in a separate list (split_face_list).
+ Body *curr_Body_ptr;
+ while( copied_ref_face_list.size() )
+ {
+ DLIList<RefFace*> split_face_list; // Holds faces from common body
+
+ // Store new curves for this body, sorted by face
+ DLIList<DLIList<Curve*>*> *curve_lists_list_ptr;
+ curve_lists_list_ptr = new DLIList<DLIList<Curve*>*>;
+ curve_lists_lists_list.append( curve_lists_list_ptr );
+
+ curr_Body_ptr = NULL;
+
+ copied_ref_face_list.reset();
+ for( i=copied_ref_face_list.size(); i--; )
+ {
+ ref_face_ptr = copied_ref_face_list.get();
+
+ DLIList<Body*> body_list;
+ ref_face_ptr->bodies( body_list );
+
+ if( curr_Body_ptr == NULL )
+ curr_Body_ptr = body_list.get();
+
+ if( curr_Body_ptr == body_list.get() )
+ {
+ split_face_list.append( ref_face_ptr );
+ copied_ref_face_list.change_to( NULL );
+ }
+
+ copied_ref_face_list.step();
+ }
+
+ copied_ref_face_list.remove_all_with_value( NULL );
+
+ DLIList<Surface*> *body_surf_list_ptr;
+ body_surf_list_ptr = new DLIList<Surface*>;
+ body_surf_list_list.append( body_surf_list_ptr );
+
+ // Loop through each face on the common body
+ RefFace *split_face_ptr;
+ DLIList<Curve*> *curve_list_ptr;
+ split_face_list.reset();
+ for( i=split_face_list.size(); i--; )
+ {
+ split_face_ptr = split_face_list.get_and_step();
+ body_surf_list_ptr->append( split_face_ptr->get_surface_ptr() );
+
+ curve_list_ptr = new DLIList<Curve*>;
+ curve_lists_list_ptr->append( curve_list_ptr );
+
+ // Get the RefEdges to fire a ray at (from surface)
+ DLIList<RefEdge*> ref_edge_list;
+ split_face_ptr->ref_edges( ref_edge_list );
+ DLIList<RefEntity*> at_entity_list;
+ CAST_LIST( ref_edge_list, at_entity_list, RefEntity );
+
+ // Fire a ray from each vertex in an outward direction from the tangent
+ // of the owning curve at the at_entity_list
+ DLIList<RefVertex*> tmp_vertex_list;
+ split_face_ptr->ref_vertices( tmp_vertex_list );
+
+ tmp_vertex_list.reset();
+ for( j=tmp_vertex_list.size(); j--; )
+ {
+ ref_vertex_ptr = tmp_vertex_list.get_and_step();
+
+ // The vertex must be part of the surface being considered, plus
+ // the attached curve must be on the surface. We must have one and
+ // only one attached curve. This curve must be linear.
+
+ // For manual case, only consider vertices that are in the input list
+ if( auto_flg == CUBIT_FALSE )
+ {
+ tdsse = (TDSplitSurfaceExtend *)ref_vertex_ptr->
+ get_TD(&TDSplitSurfaceExtend::is_split_surface_extend);
+ if( !tdsse ) continue;
+ }
+
+ // Get attached RefEdges to this vertex
+ DLIList<RefEdge*> att_ref_edge_list;
+ ref_vertex_ptr->ref_edges( att_ref_edge_list );
+
+ RefEdge *extend_edge_ptr = 0;
+ RefEdge *ref_edge_ptr;
+ int k;
+ for( k=att_ref_edge_list.size(); k--; )
+ {
+ ref_edge_ptr = att_ref_edge_list.get_and_step();
+ if( ref_edge_ptr->is_directly_related( split_face_ptr ) )
+ if( !extend_edge_ptr )
+ extend_edge_ptr = ref_edge_ptr;
+ else
+ {
+ extend_edge_ptr = 0;
+ break;
+ }
+ }
+
+ if( !extend_edge_ptr )
+ continue;
+
+ // For now, limit this to linear curves. Technically, we should be able
+ // to extend non-linear curves though.
+ Curve *curve_ptr = extend_edge_ptr->get_curve_ptr();
+ if( curve_ptr->geometry_type() != STRAIGHT_CURVE_TYPE )
+ continue;
+
+ RefVertex *start_vertex_ptr, *end_vertex_ptr;
+
+ start_vertex_ptr = extend_edge_ptr->start_vertex();
+ end_vertex_ptr = extend_edge_ptr->end_vertex();
+
+ DLIList<double> ray_params;
+ CubitVector start_loc = ref_vertex_ptr->coordinates();
+
+ // Find direction to fire ray
+ CubitVector ray_dir;
+
+ if( ref_vertex_ptr == start_vertex_ptr )
+ ray_dir = start_vertex_ptr->coordinates() -
+ end_vertex_ptr->coordinates();
+ else
+ ray_dir = end_vertex_ptr->coordinates() -
+ start_vertex_ptr->coordinates();
+
+ ray_dir.normalize();
+
+ // Remove the curve being extended from the at_entity_list
+ DLIList<RefEntity*> tmp_at_entity_list = at_entity_list;
+ tmp_at_entity_list.remove_all_with_value( extend_edge_ptr );
+
+ // Fire the ray, asking for only one hit
+ DLIList<RefEntity*> hit_entity_list;
+ if( GeometryQueryTool::instance()->fire_ray( start_loc, ray_dir,
+ tmp_at_entity_list, ray_params, 1, 0.0, &hit_entity_list )
+ == CUBIT_FAILURE ||
+ ray_params.size() == 0 || ray_params.get() == 0.0 )
+ continue;
+
+ //PRINT_INFO( "Got hit from vertex %d on surface %d at distance %lf\n",
+ // ref_vertex_ptr->id(), split_face_ptr->id(), ray_params.get() )
+
+ CubitVector end_loc;
+ double ray_param = ray_params.get();
+
+ // Note the hit entity could be a curve or a vertex
+ RefEntity *hit_entity_ptr = 0;
+ RefEdge *hit_edge_ptr = 0;
+ if( hit_entity_list.size() ) // In case fire_ray didn't return hit ents
+ {
+ hit_entity_ptr = hit_entity_list.get();
+ hit_edge_ptr = CAST_TO( hit_entity_ptr, RefEdge );
+ }
+
+ if( extendNormalFlg == CUBIT_TRUE )
+ {
+ // Try going normal to the curve hit.
+ double norm_dist = CUBIT_DBL_MAX;
+
+ if( hit_edge_ptr )
+ {
+ hit_edge_ptr->closest_point( start_loc, end_loc );
+
+ // Only valid if end_loc is ON the curve
+ CubitPointContainment contain = hit_edge_ptr->
+ point_containment( end_loc );
+
+ if( contain != CUBIT_PNT_ON )
+ {
+ // find the nearest curve which the vertex can be extended to and normal
+ RefEdge* new_edge_ptr = NULL;
+ CubitVector new_end_loc;
+ find_nearest_curve_for_normal_projection(
+ hit_edge_ptr, start_loc, split_face_ptr, ray_dir, new_edge_ptr, new_end_loc);
+
+ if (new_edge_ptr)
+ {
+ hit_edge_ptr = new_edge_ptr;
+ end_loc = new_end_loc;
+ }
+ }
+
+ norm_dist = start_loc.distance_between( end_loc );
+ }
+
+ // Use shortest distance between closest normal and ray_param
+ if( ray_param < norm_dist )
+ start_loc.next_point( ray_dir, ray_param, end_loc );
+ }
+ else
+ // Use ray_dir along ray
+ start_loc.next_point( ray_dir, ray_param, end_loc );
+
+ // For auto mode, check to see if we are out of the extendGapThreshold
+ if( auto_flg &&
+ ( start_loc.distance_between( end_loc ) > extendGapThreshold ) )
+ continue;
+
+ // Check for close vertex
+ if( hit_edge_ptr )
+ {
+ double arc_length;
+
+ // Check distance to start of curve
+ arc_length = hit_edge_ptr->get_arc_length( end_loc, 0 );
+
+ if( arc_length <= extendTolerance )
+ {
+ end_loc = hit_edge_ptr->start_coordinates();
+ PRINT_INFO( "Snapping to close vertex for curve %d extended from vertex %d\n",
+ extend_edge_ptr->id(), ref_vertex_ptr->id() );
+ }
+ else
+ {
+ // Check distance to end of curve
+ arc_length = hit_edge_ptr->get_arc_length( end_loc, 1 );
+
+ if( arc_length <= extendTolerance )
+ {
+ end_loc = hit_edge_ptr->end_coordinates();
+ PRINT_INFO( "Snapping to close vertex for curve %d extended from vertex %d\n",
+ extend_edge_ptr->id(), ref_vertex_ptr->id() );
+ }
+ }
+ }
+
+ curve_ptr = NULL;
+
+ // Create curve (from start_vec to end_vec)
+ Surface *surf_ptr = split_face_ptr->get_surface_ptr();
+
+ gme = GeometryModifyTool::instance()->get_engine( surf_ptr );
+ if( gme == NULL )
+ {
+ PRINT_ERROR("No geometry modify engine available for surface %d\n"
+ " Unable to create split curve.\n", split_face_ptr->id());
+ // Remove tooldatas and free memory
+ cleanup_for_extend_op( ref_vertex_list, body_surf_list_list,
+ curve_lists_lists_list );
+ return CUBIT_FAILURE;
+ }
+
+ // Create a straight line on the surface
+ Point *start_Point = gme->make_Point( start_loc );
+ Point *end_Point = gme->make_Point( end_loc );
+ if( start_Point == NULL || end_Point == NULL )
+ {
+ PRINT_ERROR("Unable to create points for curve on surface %d\n",
+ split_face_ptr->id() );
+ // Remove tooldatas and free memory
+ cleanup_for_extend_op( ref_vertex_list, body_surf_list_list,
+ curve_lists_lists_list );
+ return CUBIT_FAILURE;
+ }
+ curve_ptr = gme->make_Curve( start_Point, end_Point, surf_ptr );
+ if( !curve_ptr )
+ {
+ PRINT_ERROR( "Unable to create split curve from vertex %d on surface %d\n",
+ ref_vertex_ptr->id(), split_face_ptr->id() );
+ // Remove tooldatas and free memory
+ cleanup_for_extend_op( ref_vertex_list, body_surf_list_list,
+ curve_lists_lists_list );
+ return CUBIT_FAILURE;
+ }
+
+ curve_list_ptr->append( curve_ptr );
+
+ // Keep track of which curves are extended
+ ext_curve_ids.append( extend_edge_ptr->id() );
+
+ if( tdsse )
+ tdsse->set_success();
+ }
+
+ }
+
+ curr_Body_ptr = 0;
+ }
+
+ // For manual mode, check to make sure that all vertices had success,
+ // otherwise, this is an error. Note... vertices seem to live through
+ // these operations.
+ DLIList<int> vertex_id_list;
+ for( i=ref_vertex_list.size(); i--; )
+ {
+ ref_vertex_ptr = ref_vertex_list.get_and_step();
+
+ tdsse = (TDSplitSurfaceExtend *)ref_vertex_ptr->
+ get_TD(&TDSplitSurfaceExtend::is_split_surface_extend);
+
+ if( !tdsse ) continue;
+
+ if( !tdsse->is_success() )
+ vertex_id_list.append( ref_vertex_ptr->id() );
+ }
+ if( vertex_id_list.size() )
+ {
+ if( vertex_id_list.size() == 1 )
+ PRINT_ERROR( "Unable to extend from vertex %d\n", ref_vertex_ptr->id() );
+ else
+ {
+ PRINT_ERROR( "Unable to extend from vertices\n" );
+ CubitUtil::list_entity_ids( " Problem vertices: ", vertex_id_list );
+ }
+ PRINT_INFO( " Vertices must be at the end of only one curve on the surface to split,\n"
+ " extended curves must be linear, and surfaces to split must be planar.\n" );
+
+ // Remove tooldatas and free memory
+ cleanup_for_extend_op( ref_vertex_list, body_surf_list_list,
+ curve_lists_lists_list );
+ return CUBIT_FAILURE;
+ }
+
+ // Give message as to which curves were extended
+ char msg[50];
+ if( ext_curve_ids.size() )
+ {
+ // Remove duplicates (curves extended from both ends)
+ ext_curve_ids.uniquify_ordered();
+
+ // Give a nice message
+ if( ext_curve_ids.size() == 1 )
+ CubitUtil::list_entity_ids( "1 curve extended: ", ext_curve_ids );
+ else
+ {
+ sprintf( msg, "%d curves extended: ", ext_curve_ids.size() );
+ CubitUtil::list_entity_ids( msg, ext_curve_ids );
+ }
+ }
+ else
+ {
+ // Might as well exit
+ PRINT_INFO( "No curves found to extend\n" );
+ // Remove tooldatas and free memory
+ cleanup_for_extend_op( ref_vertex_list, body_surf_list_list,
+ curve_lists_lists_list );
+ return CUBIT_SUCCESS;
+ }
+
+ // Do the splitting
+ DLIList<Surface*> *surf_list_ptr;
+ DLIList<DLIList<Curve*>*> *curve_lists_list_ptr;
+ body_surf_list_list.reset();
+ curve_lists_lists_list.reset();
+ if( preview_flg==CUBIT_FALSE && create_ref_edges_flg==CUBIT_FALSE )
+ {
+ for( i=body_surf_list_list.size(); i--; )
+ {
+ surf_list_ptr = body_surf_list_list.get_and_step();
+ curve_lists_list_ptr = curve_lists_lists_list.get_and_step();
+
+ Body *new_body_ptr;
+ if( GeometryModifyTool::instance()->imprint( *surf_list_ptr,
+ *curve_lists_list_ptr, new_body_ptr ) == CUBIT_FAILURE )
+ {
+ // Remove tooldatas and free memory
+ cleanup_for_extend_op( ref_vertex_list, body_surf_list_list,
+ curve_lists_lists_list );
+ return CUBIT_FAILURE;
+ }
+ }
+ }
+ else if( preview_flg==CUBIT_TRUE && create_ref_edges_flg==CUBIT_TRUE )
+ {
+ // Just create the RefEdges
+ DLIList<RefEdge*> new_ref_edge_list;
+ curve_lists_lists_list.reset();
+
+ for( i=curve_lists_lists_list.size(); i--; )
+ {
+ curve_lists_list_ptr = curve_lists_lists_list.get_and_step();
+
+ curve_lists_list_ptr->reset();
+ for( j=curve_lists_list_ptr->size(); j--; )
+ {
+ DLIList<Curve*> *curve_list_ptr = curve_lists_list_ptr->get_and_step();
+ curve_list_ptr->reset();
+
+ create_ref_edges( *curve_list_ptr, new_ref_edge_list );
+ }
+ }
+ // Let the user know about the new curves created
+ if( new_ref_edge_list.size() )
+ {
+ DLIList<CubitEntity*> cubit_entity_list;
+ CAST_LIST( new_ref_edge_list, cubit_entity_list, CubitEntity );
+ CubitUtil::list_entity_ids( "Created new curves: ", cubit_entity_list );
+ }
+ }
+ else
+ {
+ // Just preview
+ for( i=body_surf_list_list.size(); i--; )
+ {
+ curve_lists_list_ptr = curve_lists_lists_list.get_and_step();
+
+ curve_lists_list_ptr->reset();
+ for( j=curve_lists_list_ptr->size(); j--; )
+ {
+ DLIList<Curve*> *curve_list_ptr = curve_lists_list_ptr->get_and_step();
+
+ // Draw the curves
+ draw_preview( *curve_list_ptr );
+ }
+ }
+ }
+
+ // Flush the graphics
+ GfxPreview::flush();
+
+ // Remove tooldatas and free memory
+ cleanup_for_extend_op( ref_vertex_list, body_surf_list_list,
+ curve_lists_lists_list );
+
+ return CUBIT_SUCCESS;
+}
+
+void
+SplitSurfaceTool::cleanup_for_extend_op( DLIList<RefVertex*> &ref_vertex_list,
+ DLIList<DLIList<Surface*>*> &body_surf_list_list,
+ DLIList<DLIList<DLIList<Curve*>*>*> &curve_lists_lists_list,
+ CubitBoolean free_curves_flg )
+{
+ int i;
+ RefVertex *ref_vertex_ptr;
+
+ // Remove tooldatas from vertices
+ ref_vertex_list.reset();
+ for( i=ref_vertex_list.size(); i--; )
+ {
+ ref_vertex_ptr = ref_vertex_list.get_and_step();
+ ref_vertex_ptr->delete_TD( &TDSplitSurfaceExtend::is_split_surface_extend );
+ }
+
+ // Free allocated lists in body_surf_list_list
+ while( body_surf_list_list.size() ) delete body_surf_list_list.pop();
+
+ // Free allocated lists in curve_list_lists_list, as well as Curves (if not
+ // attached to RefEdges).
+ DLIList<DLIList<Curve*>*> *curve_list_lists_ptr;
+ for( i=curve_lists_lists_list.size(); i--; )
+ {
+ curve_list_lists_ptr = curve_lists_lists_list.get();
+
+ free_curves_lists( *curve_list_lists_ptr );
+ delete curve_list_lists_ptr;
+
+ curve_lists_lists_list.step();
+ }
+
+ return;
+}
+
+void SplitSurfaceTool::find_nearest_curve_for_normal_projection(
+ RefEdge* hit_edge_ptr, CubitVector& start_loc,
+ RefFace* face, CubitVector& ray_dir, RefEdge*& new_edge_ptr,
+ CubitVector& new_end_loc)
+{
+ // traverse the curves in the surface and find the closest curve to the hardline
+ // which the hardline can extend normal to
+
+ DLIList<RefEdge*> edge_list;
+ face->ref_edges(edge_list);
+
+ std::map<double, std::pair<RefEdge*, CubitVector> > potential_curves_map;
+
+ // maybe traverse all curves all of the time, and use the one closest to the point
+ int i;
+ for (i=edge_list.size(); i--;)
+ {
+ RefEdge* edge = edge_list.get_and_step();
+
+ if (edge == hit_edge_ptr)
+ continue;
+
+ CubitVector closest_point;
+ edge->closest_point(start_loc, closest_point);
+
+ // Only valid if location is ON the curve
+ CubitPointContainment contain = edge->point_containment( closest_point );
+ if( contain == CUBIT_PNT_ON )
+ {
+ // check to make sure angle isn't too bad
+ // have a user setting for this in the future
+ // but for now, use 90 degrees
+ CubitVector split_direction = closest_point - start_loc;
+ if (split_direction.length_squared() <= GEOMETRY_RESABS) //ignore self
+ continue;
+
+ double angle = ray_dir.interior_angle(split_direction);
+ if (fabs(angle) <= 90.0)
+ {
+ double dist = start_loc.distance_between(closest_point);
+ potential_curves_map.insert(std::map<double, std::pair<RefEdge*, CubitVector> >::value_type(
+ dist, std::make_pair<RefEdge*, CubitVector>(edge, closest_point)));
+ }
+ }
+ }
+
+ if (potential_curves_map.size())
+ {
+ std::map<double, std::pair<RefEdge*, CubitVector> >::iterator iter = potential_curves_map.begin();
+ new_edge_ptr = (iter->second).first;
+ new_end_loc = (iter->second).second;
+ }
+
+ return;
+}
Modified: cgm/branches/cubit/geom/SplitSurfaceTool.hpp
===================================================================
--- cgm/branches/cubit/geom/SplitSurfaceTool.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/SplitSurfaceTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -1,13 +1,15 @@
//-------------------------------------------------------------------------
// Filename : SplitSurfaceTool.hpp
//
-// Purpose :
+// Purpose : Split a single or chain of surfaces (e.g., split a fillet
+// down the middle so that a mesh sweep can occur, or split
+// across a surface). Used by the "split surface" commands.
//
// Special Notes :
//
-// Creator :
+// Creator : Steve Storm
//
-// Creation Date :
+// Creation Date : 10/06/2002
//-------------------------------------------------------------------------
#ifndef SPLITSURFACETOOL_HPP
@@ -27,6 +29,7 @@
template <class X> class DLIList;
+//! Tool class for splitting surfaces.
class CUBIT_GEOM_EXPORT SplitSurfaceTool
{
@@ -35,25 +38,74 @@
SplitSurfaceTool();
~SplitSurfaceTool(){}
+ //! Preview function for simple surface splitting. Temporary Curves are
+ //! created on the RefFace and displayed. The curves are created from
+ //! the input vec_lists (straight lines, arcs or splines). The input
+ //! locations are the original input locations from the user, which are
+ //! displayed as well as the Curves. The clear_previous_previews flag
+ //! controls whether previous previews are cleared from the graphics
+ //! window.
CubitStatus preview( RefFace *ref_face_ptr,
DLIList<CubitVector*> &locations,
DLIList<DLIList<CubitVector*>*> &vec_lists,
- CubitBoolean create_ref_edges_flg );
- //- Preview function for simple surface splitting. Temporary Curves are
- //- created on the RefFace and displayed. The curves are created from
- //- the input vec_lists (straight lines, arcs or splines). The input
- //- locations are the original input locations from the user, which are
- //- displayed as well as the Curves.
+ CubitBoolean create_ref_edges_flg,
+ CubitBoolean clear_previous_previews = CUBIT_TRUE );
+ //! Overloaded preview function to handle multiple surfaces (see above).
+ CubitStatus preview( DLIList<RefFace*> &ref_face_list,
+ DLIList<CubitVector*> &locations,
+ DLIList<DLIList<DLIList<CubitVector*>*>*> &list_of_vec_lists,
+ CubitBoolean create_ref_edges_flg,
+ CubitBoolean clear_previous_previews = CUBIT_TRUE );
+
+ //@{
+ //! Calculate the split curves based on the surface and user parameters.
+ //! The curves are created from the input vec_lists (straight lines,
+ //! arcs or splines). The input locations are the original input locations
+ //! from the user.
CubitStatus calculate_split_curves( RefFace *ref_face_ptr,
- DLIList<CubitVector*> &locations,
DLIList<DLIList<CubitVector*>*> &vec_lists,
- DLIList<Curve*>& curve_list );
- //- Calculate the split curves based on the surface and user parameters.
- //- The curves are created from the input vec_lists (straight lines,
- //- arcs or splines). The input locations are the original input locations
- //- from the user.
+ DLIList<Curve*> &curve_list );
+ CubitStatus calculate_split_curves( Surface *surf_ptr,
+ DLIList<DLIList<CubitVector*>*> &vec_lists,
+ DLIList<Curve*> &curve_list );
+ //@}
+ //! Calculates the curves to split a chain of surfaces.
+ //! ref_face_list - chain of surfaces to split. Can be given in any order
+ //! as long as they are connected. Can be a continuous
+ //! loop of surfaces. If a single surface is given, by
+ //! default it will be split along the narrowest aspect
+ //! ratio of the surface (i.e., along a fillet). Periodic
+ //! surfaces are not handled.
+ //! num_segs - the number of segments to create (must be >= 2 );
+ //! fraction - the fraction along the surfaces to split, not valid if
+ //! num_segs > 2. This value is not used if a distance is
+ //! specified instead.
+ //! distance - if 2 segments, allow the split to be at a user specified
+ //! distance across the surface. Specify -1.0 to use the
+ //! fraction instead.
+ //! from_curve_ptr - (OPTIONAL) if user specified a fraction or distance,
+ //! orient from this curve. If not specified, a default
+ //! is chosen automatically.
+ //! corner_vertex_list - (OPTIONAL) the user can specify the corners of the,
+ //! chain, typically if the detected corners are incorrect.
+ //! The split direction is from corners 0-1 to
+ //! corners 2-3 (for single surfaces, if not overridden
+ //! by curve_dir_ptr).
+ //! through_vertex_list - (OPTIONAL) user specifies forced vertices for the split
+ //! to run through (on curves). Not valid with
+ //! more than 2 segments.
+ //! curve_dir_ptr - (OPTIONAL) for single surfaces, the direction of split can be
+ //! specified by picking a curve on the surface.
+ //! preview_flg - if CUBIT_TRUE, just draw the curves that will be used to split
+ //! instead of actually splitting.
+ //! create_ref_edges_flg - valid only if preview_flg=CUBIT_TRUE. If CUBIT_TRUE,
+ //! create RefEdges *instead* of splitting.
+ //! Note this function also utilizes five additional settings which are
+ //! supplied through the set_tolerance, set_parametric_flg,
+ //! set_auto_detect_triangles_flg, set_side_angle_threshold,
+ //! and set_point_angle_threshold functions.
CubitStatus calculate_split_curves( DLIList<RefFace*> &ref_face_list,
int num_segs, double fraction,
double distance, RefEdge *from_curve_ptr,
@@ -64,52 +116,57 @@
CubitBoolean create_ref_edges_flg,
CubitBoolean just_curves_flg,
DLIList<DLIList<Curve*>*> &curve_lists_list );
- //- Calculates the curves to split a chain of surfaces.
- //- ref_face_list - chain of surfaces to split. Can be given in any order
- //- as long as they are connected. Can be a continuous
- //- loop of surfaces. If a single surface is given, by
- //- default it will be split along the narrowest aspect
- //- ratio of the surface (i.e., along a fillet). Periodic
- //- surfaces are not handled.
- //- num_segs - the number of segments to create (must be >= 2 );
- //- fraction - the fraction along the surfaces to split, not valid if
- //- num_segs > 2. This value is not used if a distance is
- //- specified instead.
- //- distance - if 2 segments, allow the split to be at a user specified
- //- distance across the surface. Specify -1.0 to use the
- //- fraction instead.
- //- from_curve_ptr - (OPTIONAL) if user specified a fraction or distance,
- //- orient from this curve. If not specified, a default
- //- is chosen automatically.
- //- corner_vertex_list - (OPTIONAL) the user can specify the corners of the,
- //- chain, typically if the detected corners are incorrect.
- //- The split direction is from corners 0-1 to
- //- corners 2-3 (for single surfaces, if not overridden
- //- by curve_dir_ptr).
- //- through_vertex_list - (OPTIONAL) user specifies forced vertices for the split
- //- to run through (on curves). Not valid with
- //- more than 2 segments.
- //- curve_dir_ptr - (OPTIONAL) for single surfaces, the direction of split can be
- //- specified by picking a curve on the surface.
- //- preview_flg - if CUBIT_TRUE, just draw the curves that will be used to split
- //- instead of actually splitting.
- //- create_ref_edges_flg - valid only if preview_flg=CUBIT_TRUE. If CUBIT_TRUE,
- //- create RefEdges *instead* of splitting.
- //- Note this function also utilizes two additional settings which are
- //- supplied through the set_tolerance and set_parametric_flg functions.
+ //! Split function for simple surface splitting. Temporary Curves are
+ //! created on the RefFace and used to split the RefFace. The curves are
+ //! created from the input vec_lists (straight lines, arcs or splines).
+ //! The input locations are the original input locations from the user,
+ //! which are displayed for user reference.
CubitStatus split_surface( RefFace *ref_face_ptr,
- DLIList<CubitVector*> &locations,
DLIList<DLIList<CubitVector*>*> &vec_lists );
- //- Split function for simple surface splitting. Temporary Curves are
- //- created on the RefFace and used to split the RefFace. The curves are
- //- created from the input vec_lists (straight lines, arcs or splines).
- //- The input locations are the original input locations from the user,
- //- which are displayed for user reference.
+ //! Overloaded split function to allow multiple surfaces to be split (see above).
+ CubitStatus split_surface( DLIList<RefFace*> &ref_face_list,
+ DLIList<DLIList<DLIList<CubitVector*>*>*> &list_of_vec_lists );
+
+ //! Split function for simple surface splitting using a list of predefined curves
CubitStatus split_surface( RefFace *ref_face_ptr, DLIList<Curve*> &curve_list);
- //- Split function for simple surface splitting using a list of predefined curves
+ //! Splits the chain of surfaces.
+ //! ref_face_list - chain of surfaces to split. Can be given in any order
+ //! as long as they are connected. Can be a continuous
+ //! loop of surfaces. If a single surface is given, by
+ //! default it will be split along the narrowest aspect
+ //! ratio of the surface (i.e., along a fillet). Periodic
+ //! surfaces are not handled.
+ //! num_segs - the number of segments to create (must be >= 2 );
+ //! fraction - the fraction along the surfaces to split, not valid if
+ //! num_segs > 2. This value is not used if a distance is
+ //! specified instead.
+ //! distance - if 2 segments, allow the split to be at a user specified
+ //! distance across the surface. Specify -1.0 to use the
+ //! fraction instead.
+ //! from_curve_ptr - (OPTIONAL) if user specified a fraction or distance,
+ //! orient from this curve. If not specified, a default
+ //! is chosen automatically.
+ //! corner_vertex_list - (OPTIONAL) the user can specify the corners of the,
+ //! chain, typically if the detected corners are incorrect.
+ //! The split direction is from corners 0-1 to
+ //! corners 2-3 (for single surfaces, if not overridden
+ //! by curve_dir_ptr).
+ //! through_vertex_list - (OPTIONAL) user specifies forced vertices for the split
+ //! to run through (on curves). Not valid with
+ //! more than 2 segments.
+ //! curve_dir_ptr - (OPTIONAL) for single surfaces, the direction of split can be
+ //! specified by picking a curve on the surface.
+ //! preview_flg - if CUBIT_TRUE, just draw the curves that will be used to split
+ //! instead of actually splitting.
+ //! create_ref_edges_flg - valid only if preview_flg=CUBIT_TRUE. If CUBIT_TRUE,
+ //! create RefEdges *instead* of splitting.
+ //! Note this function also utilizes five additional settings which are
+ //! supplied through the set_tolerance, set_parametric_flg,
+ //! set_auto_detect_triangles_flg, set_side_angle_threshold,
+ //! and set_point_angle_threshold functions.
CubitStatus split_surfaces( DLIList<RefFace*> &ref_face_list,
int num_segs,
double fraction,
@@ -120,40 +177,13 @@
RefEdge *curve_dir_ptr = NULL,
CubitBoolean preview_flg = CUBIT_FALSE,
CubitBoolean create_ref_edges_flg = CUBIT_FALSE );
- //- Splits the chain of surfaces.
- //- ref_face_list - chain of surfaces to split. Can be given in any order
- //- as long as they are connected. Can be a continuous
- //- loop of surfaces. If a single surface is given, by
- //- default it will be split along the narrowest aspect
- //- ratio of the surface (i.e., along a fillet). Periodic
- //- surfaces are not handled.
- //- num_segs - the number of segments to create (must be >= 2 );
- //- fraction - the fraction along the surfaces to split, not valid if
- //- num_segs > 2. This value is not used if a distance is
- //- specified instead.
- //- distance - if 2 segments, allow the split to be at a user specified
- //- distance across the surface. Specify -1.0 to use the
- //- fraction instead.
- //- from_curve_ptr - (OPTIONAL) if user specified a fraction or distance,
- //- orient from this curve. If not specified, a default
- //- is chosen automatically.
- //- corner_vertex_list - (OPTIONAL) the user can specify the corners of the,
- //- chain, typically if the detected corners are incorrect.
- //- The split direction is from corners 0-1 to
- //- corners 2-3 (for single surfaces, if not overridden
- //- by curve_dir_ptr).
- //- through_vertex_list - (OPTIONAL) user specifies forced vertices for the split
- //- to run through (on curves). Not valid with
- //- more than 2 segments.
- //- curve_dir_ptr - (OPTIONAL) for single surfaces, the direction of split can be
- //- specified by picking a curve on the surface.
- //- preview_flg - if CUBIT_TRUE, just draw the curves that will be used to split
- //- instead of actually splitting.
- //- create_ref_edges_flg - valid only if preview_flg=CUBIT_TRUE. If CUBIT_TRUE,
- //- create RefEdges *instead* of splitting.
- //- Note this function also utilizes two additional settings which are
- //- supplied through the set_tolerance and set_parametric_flg functions.
+ //! Same as above except this method simply returns a list of lists of
+ //! Curves (one list per input RefFace). This method is intended for
+ //! use by a programmer (rather than a user from GeometryCommands).
+ //! Note it is the calling functions responsibility to free the memory
+ //! allocated in curve_lists_list, as well as the Curves (note this can
+ //! be accomplished with the function free_curves_lists).
CubitStatus split_surfaces( DLIList<RefFace*> &ref_face_list,
int num_segs,
double fraction,
@@ -163,13 +193,8 @@
DLIList<RefVertex*> &through_vertex_list,
RefEdge *curve_dir_ptr,
DLIList<DLIList<Curve*>*> &curve_lists_list );
- //- Same as above except this method simply returns a list of lists of
- //- Curves (one list per input RefFace). This method is intended for
- //- use by a programmer (rather than a user from GeometryCommands).
- //- Note it is the calling functions responsibility to free the memory
- //- allocated in curve_lists_list, as well as the Curves (note this can
- //- be accomplished with the function free_curves_lists).
+ //! Same as above except this method simply returns a simple list of Curves.
CubitStatus split_surfaces( DLIList<RefFace*> &ref_face_list,
int num_segs,
double fraction,
@@ -179,65 +204,118 @@
DLIList<RefVertex*> &through_vertex_list,
RefEdge *curve_dir_ptr,
DLIList<Curve*> &curve_list );
- //- Same as above except this method simply returns a simple list of Curves.
+ //! Splits surfaces by extending curves at the end of hardlines across the
+ //! surface. Only works on planar surfaces and by extending linear curves.
+ //! If specified vertex list is provided, only try to extend curves
+ //! attached to those vertices, and error out if unable to perform the
+ //! operation using any vertex. If no vertex list is provided, find
+ //! appropriate vertices automatically, and limit the split to gaps less
+ //! than or equal to the specified "split surface extend gap threshold".
+ //! {ref_face_list} - list of connected surfaces to split
+ //! {ref_vertex_list} - (OPTIONAL) - vertices to extend from. Function will
+ //! error out if unable to extend from any vertex. If
+ //! not supplied, function will automatically find
+ //! valid vertices to extend from on the surfaces, and
+ //! will limit the split to gaps less than or equal to
+ //! the specified extend gap threshold (see setting
+ //! below).
+ //! {preview_flg} - routine only displays graphics preview of splits
+ //! {create_ref_edges_flg} - valid only if preview_flg=CUBIT_TRUE. If
+ //! CUBIT_TRUE, create RefEdges *instead* of
+ //! splitting.
+ //! Note this function also utilizes thress additional settings which are
+ //! supplied through the set_extend_gap_threshold, set_extend_tolerance and
+ //! set_extend_normal functions.
+ CubitStatus split_surfaces_extend( DLIList<RefFace*> &ref_face_list,
+ DLIList<RefVertex*> &ref_vertex_list,
+ CubitBoolean preview_flg = CUBIT_FALSE,
+ CubitBoolean create_ref_edges_flg = CUBIT_FALSE );
+
+ //! Free the curves and lists memory. If free_curves_flg is CUBIT_TRUE,
+ //! free the Curves as well (however, the function checks if a RefEdge is
+ //! attached to the Curve - if a RefEdge is attached the Curve is not freed).
void free_curves_lists( DLIList<DLIList<Curve*>*> &curve_lists_list,
CubitBoolean free_curves_flg = CUBIT_TRUE );
- //- Free the curves and lists memory. If free_curves_flg is CUBIT_TRUE,
- //- free the Curves as well (however, the function checks if a RefEdge is
- //- attached to the Curve - if a RefEdge is attached the Curve is not freed).
+ //! Set the tolerance (function returns previous tolerance)
static void set_tolerance( double tol );
- //- Set the tolerance (function returns previous tolerance)
+
+ //! Get the tolerance. In layman's terms, the tolerance controls how
+ //! closely the split actually follows the center of the surface. In the
+ //! code, it determines how accurately to facet the bounding curves (the
+ //! facets are used to interpolate points on the surface using a mapping
+ //! concept). It is also used in an iterative procedure in fitting splines
+ //! to the line segments generated by the mapping (just fitting a spline
+ //! through the interpolated points was found to give very bad results -
+ //! instead we check the deviation of the spline from the line segments and
+ //! add additional points until the resultant spline is within tolerance to
+ //! the line segments.
static double get_tolerance();
- //- Get the tolerance. In layman's terms, the tolerance controls how
- //- closely the split actually follows the center of the surface. In the
- //- code, it determines how accurately to facet the bounding curves (the
- //- facets are used to interpolate points on the surface using a mapping
- //- concept). It is also used in an iterative procedure in fitting splines
- //- to the line segments generated by the mapping (just fitting a spline
- //- through the interpolated points was found to give very bad results -
- //- instead we check the deviation of the spline from the line segments and
- //- add additional points until the resultant spline is within tolerance to
- //- the line segments.
+ //! Set the auto detect triangles flag
static void set_auto_detect_triangles_flg( CubitBoolean auto_detect_flg );
- //- Set the auto detect triangles flag
+
+ //! Get the auto detect triangles flag
static CubitBoolean get_auto_detect_triangles_flg();
- //- Get the auto detect triangles flag
+ //! Set the side angle threshold
static void set_side_angle_threshold( double angle );
- //- Set the side angle threshold
+
+ //! Get the side angle threshold. If there is a corner angle within this
+ //! threshold to 180 and another corner angle less than the point threshold, a
+ //! triangle is created.
static double get_side_angle_threshold();
- //- Get the side angle threshold. If there is a corner angle within this
- // threshold to 180 and another corner angle less than the point threshold, a
- // triangle is created.
+ //! Set the point angle threshold
static void set_point_angle_threshold( double tol );
- //- Set the point angle threshold
+
+ //! Get the point angle threshold. If there is a corner angle less than
+ //! this value and another corner angle within the side threshold to 180, a
+ //! triangle is created.
static double get_point_angle_threshold();
- //- Get the point angle threshold. If there is a corner angle less than
- // this value and another corner angle within the side threshold to 180, a
- // triangle is created.
+ //! Set the parametric flag
static void set_parametric_flg( CubitBoolean parametric_flg );
- //- Set the parametric flag
+
+ //! Get the parametric flag. If the parametric_flg is CUBIT_TRUE, find
+ //! spline locations in the parametric space of the surface, otherwise
+ //! initially find the spline locations in 3D space then project back to
+ //! the surface. Typically, the parametric space gives better results
+ //! (on curvy surfaces, it will result in a spline that is much closer to
+ //! the middle of the surface). However, sometimes the parameter space
+ //! is bad or the mapping algorigm gets confused (frequently on conic
+ //! surfaces, resulting in points revolved 180 deg away), so the 3D method
+ //! gives a better result. Note the default is thus 3D.
static CubitBoolean get_parametric_flg();
- //- Get the parametric flag. If the parametric_flg is CUBIT_TRUE, find
- //- spline locations in the parametric space of the surface, otherwise
- //- initially find the spline locations in 3D space then project back to
- //- the surface. Typically, the parametric space gives better results
- //- (on curvy surfaces, it will result in a spline that is much closer to
- //- the middle of the surface). However, sometimes the parameter space
- //- is bad or the mapping algorigm gets confused (frequently on conic
- //- surfaces, resulting in points revolved 180 deg away), so the 3D method
- //- gives a better result. Note the default is thus 3D.
+ //! Set the extend gap threshold. Only split if gap is less than this.
+ static void set_extend_gap_threshold( double threshold = CUBIT_DBL_MAX );
+
+ //! Get the extend gap threshold.
+ static double get_extend_gap_threshold();
+
+ //! Set the extend tolerance. Snaps to vertices along curves within this
+ //! tolerance so as to avoid creating short curves when splitting surfaces
+ //! with the extend method.
+ static void set_extend_tolerance( double tol );
+
+ //! Get the extend tolerance.
+ static double get_extend_tolerance();
+
+ //! Set the extend normal flag. If projecting normal to curve is less
+ //! distance, use that instead of extending curve, if this setting is
+ //! true.
+ static void set_extend_normal_flg( CubitBoolean extend_normal_flg );
+
+ //! Return extend normal setting.
+ static CubitBoolean get_extend_normal_flg();
+
+ //! Initialize settings for this class
static void initialize_settings();
- //- Initialize settings for this class
+ //! preview the curves
CubitStatus draw_preview( DLIList<Curve*> &curve_list, int color=CUBIT_BLUE );
- //- preview the curves
private:
@@ -459,7 +537,7 @@
CubitBoolean is_triangle();
//- Determines if a single surface chain is a triangle
- CubitStatus check_through_vertices( char *type );
+ CubitStatus check_through_vertices( const char *type );
//- Determines if the through vertices are on valid sides of the surface.
//- Call this function after adjusting for a Curve direction.
//- This function only checks - it gives an error if through vertices are
@@ -554,8 +632,9 @@
int color=CUBIT_BLUE );
//- Draw the curves
- CubitStatus create_ref_edges( DLIList<Curve*> &curve_list );
- //- Create RefEdges from the given Curves
+ CubitStatus create_ref_edges( DLIList<Curve*> &curve_list,
+ DLIList<RefEdge*> &ref_edge_list );
+ //- Create RefEdges from the given Curves. Appends to the output list.
int number_coedges( RefEdge *ref_edge_ptr, RefFace *ref_face_ptr );
//- Finds the number of coedges for the given edge on the given surface
@@ -674,6 +753,23 @@
int count_curves_in_body( Body *body_ptr );
//- Return number of curves in the body
+ void cleanup_for_extend_op( DLIList<RefVertex*> &ref_vertex_list,
+ DLIList<DLIList<Surface*>*> &body_surf_list_list,
+ DLIList<DLIList<DLIList<Curve*>*>*> &curve_lists_lists_list,
+ CubitBoolean free_curves_flg = CUBIT_TRUE );
+ //- This function cleans up after the split extend operation. It removes
+ //- the tooldatas from the vertices and frees the lists memory. If
+ //- free_curves_flg is CUBIT_TRUE, free the Curves as well (however, the
+ //- function checks if a RefEdge is attached to the Curve - if a RefEdge
+ //- is attached the Curve is not freed).
+
+ void find_nearest_curve_for_normal_projection(
+ RefEdge* hit_edge_ptr, CubitVector& start_loc, RefFace* face,
+ CubitVector& ray_dir, RefEdge*& new_edge_ptr, CubitVector& new_end_loc);
+ //- This function is used when the split extend command is used with normal = TRUE and
+ //- the hardline does not intersect the curve found by fire_ray at a 90 degree angle.
+ //- This function traverses the curve's neighbors to find a curve that can be split normal.
+
static CubitBoolean parametricFlg; // Split parametrically or not (3D)
static double splitTolerance; // Length tolerance for tessellations, etc.
static CubitBoolean autoDetectTriangles; // Detect triangles automatically?
@@ -684,6 +780,14 @@
// the triangle point (if sideAngleThreshold
// criteria also met)
+ static double extendGapThreshold; // Only gaps below this value are split
+ static CubitBoolean extendNormalFlg; // If true, extend normal to curve
+ // instead of in curve direction if
+ // distance is less
+ static double extendTolerance; // If split end is equal or closer than this
+ // to a vertex along a curve snap to the
+ // vertex.
+
DLIList<RefFace*> refFaceChain;
DLIList<RefVertex*> throughVertexList;
DLIList<CoEdge*> outerCoEdgeLoop;
@@ -732,5 +836,29 @@
SplitSurfaceTool::get_parametric_flg()
{ return parametricFlg; }
+inline void
+SplitSurfaceTool::set_extend_gap_threshold( double gap )
+{ extendGapThreshold = gap; }
+
+inline double
+SplitSurfaceTool::get_extend_gap_threshold()
+{ return extendGapThreshold; }
+
+inline void
+SplitSurfaceTool::set_extend_tolerance( double tol )
+{ extendTolerance = tol; }
+
+inline double
+SplitSurfaceTool::get_extend_tolerance()
+{ return extendTolerance; }
+
+inline void
+SplitSurfaceTool::set_extend_normal_flg( CubitBoolean extend_normal_flg )
+{ extendNormalFlg = extend_normal_flg; }
+
+inline CubitBoolean
+SplitSurfaceTool::get_extend_normal_flg()
+{ return extendNormalFlg; }
+
#endif
Modified: cgm/branches/cubit/geom/SurfParamTool.cpp
===================================================================
--- cgm/branches/cubit/geom/SurfParamTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/SurfParamTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -17,7 +17,7 @@
#include "SurfParamTool.hpp"
#include "CastTo.hpp"
#include "Surface.hpp"
-#include "DLIList.hpp"
+#include "DLIList.hpp"
//-------------------------------------------------------------------------
// Function: SurfParamTool
@@ -27,13 +27,9 @@
//-------------------------------------------------------------------------
SurfParamTool::SurfParamTool(Surface *surf)
{
-// FacetEvalTool **surf_eval_tool = NULL;
-// DLIList<CubitFacet *> facet_list;
//- update private variables
refSurf = surf;
-// refSurf->setup_use_facets(facet_list,0,surf_eval_tool);
-// feTool = *surf_eval_tool;
}
@@ -53,111 +49,8 @@
//===================================================================================
CubitStatus SurfParamTool::set_up_space(void) {
- //double u, v, s;
CubitStatus rv = CUBIT_SUCCESS;
- //- calculate uv position for every point
-// TDFacetBoundaryPoint *td_fbp;
-// CubitBoolean on_internal_boundary;
-// DLIList<CubitFacet *> facet_list;
-// DLIList<CubitPoint *> point_list;
-// CubitPoint *pt_ptr;
-// int ii;
-// feTool->get_points(point_list);
-// for(ii = 0; ii < point_list.size() && rv == CUBIT_SUCCESS; ii++) {
-// pt_ptr = point_list.get_and_step();
-// rv = refSurf->u_v_from_position(pt_ptr->coordinates(), u, v);
-// facet_list.clean_out();
-// pt_ptr->facets_on_surf( feTool->tool_id(), facet_list, on_internal_boundary );
-// if (on_internal_boundary)
-// {
-// td_fbp = TDFacetBoundaryPoint::get_facet_boundary_point( pt_ptr );
-// if (!td_fbp)
-// {
-// TDFacetBoundaryPoint::add_facet_boundary_point( pt_ptr );
-// td_fbp = TDFacetBoundaryPoint::get_facet_boundary_point( pt_ptr );
-// td_fbp->add_surf_facets( facet_list );
-// td_fbp->set_uv( facet_list.get(), u, v);
-// }
-// else
-// {
-// if (td_fbp->set_uv( facet_list.get(),
-// u, v ) != CUBIT_SUCCESS)
-// {
-// td_fbp->add_surf_facets( facet_list );
-// td_fbp->set_uv( facet_list.get(), u, v);
-// }
-// }
-// }
-// else
-// {
-// pt_ptr->set_uv( u, v);
-// }
-// }
-//
-// //- calculate distortion [sum(original facet area/uv area)/total facets]
-// CubitFacet *facet_ptr;
-// CubitPoint *p0, *p1, *p2;
-// int jj;
-// double orig_area, uv_area, sum_area, u0, u1, u2, v0, v1, v2;
-// for(ii = 0; ii < point_list.size() && rv == CUBIT_SUCCESS; ii++) {
-// pt_ptr = point_list.get_and_step();
-// facet_list.clean_out();
-// pt_ptr->facets_on_surf(feTool->tool_id(), facet_list, on_internal_boundary);
-//
-// sum_area = 0;
-// for(jj = 0; jj < facet_list.size(); jj++){
-// facet_ptr = facet_list.get_and_step();
-//
-// //- calculate original area
-// orig_area = facet_ptr->area();
-//
-// //- extract uv data
-// facet_ptr->points(p0, p1, p2);
-// p0->get_uv(facet_ptr, u0, v0);
-// p1->get_uv(facet_ptr, u1, v1);
-// p2->get_uv(facet_ptr, u2, v2);
-//
-// //- calculate uv area
-// CubitVector uv0(u0,v0,0.0);
-// CubitVector uv1(u1,v1,0.0);
-// CubitVector uv2(u2,v2,0.0);
-// CubitVector e0(uv0, uv1);
-// CubitVector e1(uv0, uv2);
-// uv_area = (e0*e1).length()*0.5;
-//
-// sum_area += sqrt(uv_area/orig_area);
-// }
-//
-// s = sum_area/facet_list.size();
-// pt_ptr->get_uv(facet_list.get(), u, v);
-//
-// if (on_internal_boundary)
-// {
-// td_fbp = TDFacetBoundaryPoint::get_facet_boundary_point( pt_ptr );
-// if (!td_fbp)
-// {
-// TDFacetBoundaryPoint::add_facet_boundary_point( pt_ptr );
-// td_fbp = TDFacetBoundaryPoint::get_facet_boundary_point( pt_ptr );
-// td_fbp->add_surf_facets( facet_list );
-// td_fbp->set_uvs( facet_list.get(), u, v, s);
-// }
-// else
-// {
-// if (td_fbp->set_uvs( facet_list.get(),
-// u, v, s ) != CUBIT_SUCCESS)
-// {
-// td_fbp->add_surf_facets( facet_list );
-// td_fbp->set_uvs( facet_list.get(), u, v, s);
-// }
-// }
-// }
-// else
-// {
-// pt_ptr->set_uvs( u, v, s);
-// }
-//
-// }
return rv;
}
@@ -168,55 +61,217 @@
// Author: chynes
// Date: 7/10/02
//===================================================================================
-CubitStatus SurfParamTool::transform_to_uv(CubitVector &xyz_location, CubitVector &uv_location)
+CubitStatus SurfParamTool::transform_to_uv(const CubitVector &xyz_location, CubitVector &uv_location)
{
double u,v;
- CubitStatus rv = CUBIT_SUCCESS;
-// DLIList<CubitFacet *> facet_list;
-// CubitFacet *tri_ptr;
-// CubitBoolean *outside = CUBIT_FALSE;
-// CubitVector closest_point;
-// CubitVector area_coord;
-// double compare_tol;
+
+ CubitStatus rv = refSurf->u_v_from_position(xyz_location, u, v);
+ uv_location.set(u,v,1.0);
+
+ CubitVector du, dv;
+ uv_derivitives(u,v,du,dv);
+
+ return rv;
+}
+
+//===================================================================================
+// Function: transform_to_xyz (Public)
+// Description: same as title
+// Author: chynes
+// Date: 7/10/02
+//===================================================================================
+CubitStatus SurfParamTool::transform_to_xyz(CubitVector &xyz_location, const CubitVector &uv_location)
+{
+ xyz_location = refSurf->position_from_u_v(uv_location.x(), uv_location.y());
+
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus SurfParamTool::uv_derivitives( double u_param, double v_param, CubitVector &du, CubitVector &dv )
+{
+ return refSurf->uv_derivitives (u_param, v_param, du, dv);
+}
+
+//void intersect2DLines(double x0, double y0, double x1, double y1,
+// double x2, double y2, double x3, double y3,
+// double &xc, double &yc)
+////
+//// intersect two lines in 2D. First line defined by points 0 and 1, second by points 2 and 3
+////
+//{
+// double u = ( (x3-x2)*(y0-y2) - (y3-y2)*(x0-x2) ) / ( (y3-y2)*(x1-x0) - (x3-x2)*(y1-y0) );
//
-// // find best compare_tol
-// compare_tol = 1e-3*(feTool->bounding_box().diagonal().length());
+// xc = x0 + u * (x1-x0);
+// yc = y0 + u * (y1-y0);
+//}
//
-// // locate point
-// feTool->get_facets(facet_list);
-// rv = FacetEvalTool::project_to_facets(facet_list,
-// tri_ptr,
-// 0,
-// compare_tol,
-// xyz_location,
-// CUBIT_FALSE,
-// outside,
-// &closest_point,
-// NULL);
-// // determine barycentric coordinates for in facet
-// if(rv == CUBIT_SUCCESS)
-// {
-// FacetEvalTool::facet_area_coordinate(tri_ptr, closest_point, area_coord);
+//
//
-// // extract data
-// double u0, u1, u2, v0, v1, v2, s0, s1, s2;
-// CubitPoint *p0, *p1, *p2;
-// tri_ptr->points(p0, p1, p2);
-// p0->get_uvs(tri_ptr, u0, v0, s0);
-// p1->get_uvs(tri_ptr, u1, v1, s1);
-// p2->get_uvs(tri_ptr, u2, v2, s2);
+//CubitStatus SurfParamTool::circumcenter(double u0, double v0,
+// double u1, double v1,
+// double u2, double v2,
+// CubitVector ¢er)
+////
+//// Calculates the center of the center of the circumellipse for the three points in parameter space
+//// this (u,v) should map back to the circumcenter of the circle of the three points in three-space.
+////
+//{
//
-// rv = refSurf->u_v_from_position(xyz_location, u, v);
-// // determine sizing
-// s = (area_coord.x()*s0) + (area_coord.y()*s1) + (area_coord.z()*s2);
+// // first, lets calculate the circumcenter without the gradients to make sure the system works
//
-// uv_location.set(u,v,s);
-// }
+// // our method for finding a circumcenter utilizes the fact that the perpendicalar bisectors of each side
+// // of the triangle intersect at the circumcenter
+//
+// // find the three bisectors of the sides
+//
+// double u3 = u0 + (u1 - u0) * 0.5; // midpoint of side 0-1
+// double v3 = v0 + (v1 - v0) * 0.5;
+//
+// double u4 = u3 + v0 - v1; // point on the perp bisector of side 0-1
+// double v4 = v3 + u1 - u0;
+//
+// double u5 = u1 + (u2 - u1) * 0.5; // midpoint of side 1-2
+// double v5 = v1 + (v2 - v1) * 0.5;
+//
+// double u6 = u5 + v1 - v2; // point on the perp bisector of side 1-2
+// double v6 = v5 + u2 - u1;
+//
+// double u7 = u0 + (u2 - u0) * 0.5; // midpoint of side 0-2
+// double v7 = v0 + (v2 - v0) * 0.5;
+//
+// double u8 = u7 + v0 - v2;
+// double v8 = v7 + u2 - u0;
+//
+// // intersect two bisectors to give a cirumcenter
+//
+// double xc, yc;
+// intersect2DLines(u3,v3,u4,v4,u5,v5,u6,v6,xc,yc);
+// double xc2, yc2;
+// intersect2DLines(u3,v3,u4,v4,u7,v7,u8,v8,xc2,yc2);
+// double xc3, yc3;
+// intersect2DLines(u5,v5,u6,v6,u7,v7,u8,v8,xc3,yc3);
+//
+//
+//
+//
+// //// get derivitives of each point
+//
+// //CubitVector du0, du1, du2, dv0, dv1, dv2, du, dv;
+// //uv_derivitives (u0, v0, du0, dv0);
+// //uv_derivitives (u1, v1, du1, dv1);
+// //uv_derivitives (u2, v2, du2, dv2);
+//
+// //// for now, average derivities first
+//
+// //du = (du0 + du1 + du2) / 3.0; n
+// //dv = (dv0 + dv1 + dv2) / 3.0;
+//
+// //// Calculate the rotation angle to the principal axis
+//
+// //double alpha = atan2( 2.0 * ( du.x()*dv.x() + du.y()*dv.y() ), (du.length_squared() - dv.length_squared())) * 0.5;
+//
+// //// Calculate principal derivitives
+//
+// //double cosa = acos(alpha);
+// //double sina = asin(alpha);
+// //CubitVector dup = cosa * du + sina * dv;
+// //CubitVector dvp = -sina * du + cosa * dv;
+//
+// ////
+//
+//
+// return CUBIT_SUCCESS;
+//}
- rv = refSurf->u_v_from_position(xyz_location, u, v);
+
+
+
+//EOF
+
+//- Class: TestParamTool
+//-------------------------------------------------------------------------
+// Filename : TestParamTool.cpp
+//
+// Purpose : This is the generic version of ParamTool when the
+// geometry engine has a sufficient parameterization.
+// It uses the tool's existing functions to get transform
+// between uv and xyz spaces.
+//
+// Creator : Christopher Hynes
+//
+// Creation Date : 7/10/2002
+//
+// Owner : Christopher Hynes
+//-------------------------------------------------------------------------
+
+#include "CastTo.hpp"
+#include "Surface.hpp"
+#include "DLIList.hpp"
+
+//-------------------------------------------------------------------------
+// Function: TestParamTool
+// Description: constructor
+// Author: chynes
+// Date: 7/10/2002
+//-------------------------------------------------------------------------
+TestParamTool::TestParamTool()
+{
+
+ //- update private variables
+// refSurf = surf;
+
+ uRange = 1.0;
+ vRange = 4.0;
+
+ xMin = -0.5;
+ yMin = -0.5;
+
+ xMax = 0.5;
+ yMax = 0.5;
+
+
+ zDepth = 0.5; // constant z coordinate of test surface
+
+}
+
+//-------------------------------------------------------------------------
+// Function: TestParamTool
+// Description: deconstructor
+// Author: chynes
+// Date: 7/10/2002
+//-------------------------------------------------------------------------
+TestParamTool::~TestParamTool() {}
+
+//===================================================================================
+// Function: set_up_space (Public)
+// Description: sets up space of flattening
+// Author: chynes
+// Date: 7/10/02
+//===================================================================================
+CubitStatus TestParamTool::set_up_space(void)
+{
+
+ CubitStatus rv = CUBIT_SUCCESS;
+
+
+ return rv;
+}
+
+//===================================================================================
+// Function: transform_to_uv (Public)
+// Description: same as title, the local sizing will be returned in the z coord
+// Author: chynes
+// Date: 7/10/02
+//===================================================================================
+CubitStatus TestParamTool::transform_to_uv(const CubitVector &xyz_location, CubitVector &uv_location)
+{
+ // calculate the u,v from the x,y
+
+ double u = (xyz_location.x()-xMin)/(xMax-xMin) * uRange;
+ double v = (xyz_location.y()-yMin)/(yMax-yMin) * vRange;
uv_location.set(u,v,1.0);
- return rv;
+ return CUBIT_SUCCESS;
}
//===================================================================================
@@ -225,13 +280,22 @@
// Author: chynes
// Date: 7/10/02
//===================================================================================
-CubitStatus SurfParamTool::transform_to_xyz(CubitVector &xyz_location, CubitVector &uv_location)
+CubitStatus TestParamTool::transform_to_xyz(CubitVector &xyz_location, const CubitVector &uv_location)
{
- xyz_location = refSurf->position_from_u_v(uv_location.x(), uv_location.y());
+ double u = (xyz_location.x()-xMin)/(xMax-xMin) * uRange;
+ // get x,y from u,v
+ double x = uv_location.x()/uRange + xMin;
+ double y = uv_location.y()/vRange + yMin;
+
+ xyz_location.set(x,y,zDepth);
+
return CUBIT_SUCCESS;
}
-
-
-//EOF
+CubitStatus TestParamTool::uv_derivitives( double u_param, double v_param, CubitVector &du, CubitVector &dv )
+{
+ du.set(1.0/uRange,0,0);
+ dv.set(0,1.0/vRange,0);
+ return CUBIT_SUCCESS;
+}
Modified: cgm/branches/cubit/geom/SurfParamTool.hpp
===================================================================
--- cgm/branches/cubit/geom/SurfParamTool.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/SurfParamTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -24,7 +24,7 @@
class CubitVector;
template <class X> class DLIList;
-
+//! Transforms between a surface's uv parameter and xyz space.
class CUBIT_GEOM_EXPORT SurfParamTool : public ParamTool
{
public:
@@ -37,16 +37,64 @@
CubitStatus set_up_space(void);
- CubitStatus transform_to_uv(CubitVector &xyz_location, CubitVector &uv_location);
+ CubitStatus transform_to_uv(const CubitVector &xyz_location, CubitVector &uv_location);
- CubitStatus transform_to_xyz(CubitVector &xyz_location, CubitVector &uv_location);
+ CubitStatus transform_to_xyz(CubitVector &xyz_location, const CubitVector &uv_location);
+ CubitStatus uv_derivitives( double u_param, double v_param,
+ CubitVector &du, CubitVector &dv );
+ static CubitStatus circumcenter(double u0, double v0,
+ double u1, double v1,
+ double u2, double v2,
+ CubitVector ¢er); // temp function to be moved elsewhere
+
private:
Surface *refSurf;
//- reference surface
};
+class Surface;
+class CubitVector;
+template <class X> class DLIList;
+
+//! Transforms between a surface's uv parameter and xyz space.
+class CUBIT_GEOM_EXPORT TestParamTool : public ParamTool
+{
+public:
+
+ //- constructor
+ TestParamTool();
+
+ //- deconstructor
+ ~TestParamTool();
+
+ CubitStatus set_up_space(void);
+
+ CubitStatus transform_to_uv(const CubitVector &xyz_location, CubitVector &uv_location);
+
+ CubitStatus transform_to_xyz(CubitVector &xyz_location, const CubitVector &uv_location);
+
+ CubitStatus uv_derivitives( double u_param, double v_param,
+ CubitVector &du, CubitVector &dv );
+
+ static CubitStatus circumcenter(double u0, double v0,
+ double u1, double v1,
+ double u2, double v2,
+ CubitVector ¢er); // temp function to be moved elsewhere
+
+private:
+
+// Surface *refSurf;
+ //- reference surface
+
+ double uRange, vRange;
+ double zDepth;
+
+ double xMin, yMin, xMax, yMax;
+
+};
+
#endif // ACIS_PARAM_TOOL_HPP
Modified: cgm/branches/cubit/geom/Surface.hpp
===================================================================
--- cgm/branches/cubit/geom/Surface.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/Surface.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -35,7 +35,6 @@
template <class X> class DLIList;
class ShellSM;
-
class CUBIT_GEOM_EXPORT Surface : public GeometryEntity
{
public :
@@ -68,7 +67,10 @@
//- Only valid for planar surfaces
//- Finds the underlying plane's origin and normal (unit) vector
//- Returns CubitFailure if not a plane.
-
+
+ virtual void param_dir(CubitVector &unit_dir_in_world_space,
+ CubitVector &pos_on_surf, double &du, double &dv){}
+
virtual CubitStatus closest_point_uv_guess(
CubitVector const& location,
double& u_guess, double& v_guess,
@@ -324,6 +326,11 @@
//R GeometryType (enum)
//R- The enumerated type of the geometric representation
+ virtual GeometryType is_cylindrical()
+ {return UNDEFINED_SURFACE_TYPE;};
+ //R GeometryType (enum)
+ //R- CYLINDRICAL_SURFACE_TYPE if true UNDEFINED_SURFACE_TYPE if false
+
// Now handled at RefFace level. -- j.k. Oct, 2003
//virtual void reverse_sense() = 0;
//- Switch the sense of this Surface wrt the RefFace that owns it.
Modified: cgm/branches/cubit/geom/SurfaceOverlapFacet.cpp
===================================================================
--- cgm/branches/cubit/geom/SurfaceOverlapFacet.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/SurfaceOverlapFacet.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -5,7 +5,7 @@
//- Created: January 26, 2003
#include "SurfaceOverlapFacet.hpp"
-#include "GfxDebug.hpp"
+#include "GfxPreview.hpp"
AnalyticGeometryTool* SurfaceOverlapFacet::agt = AnalyticGeometryTool::instance();
@@ -51,6 +51,24 @@
return agt->MinTriangleTriangle( t, other_facet.t, s, t2, u, v );
}
+CubitBoolean
+SurfaceOverlapFacet::facing( SurfaceOverlapFacet &other_facet )
+{
+ double norm1[3];
+ agt->Normal( t, norm1 );
+ double norm2[3];
+ agt->Normal( other_facet.t, norm2 );
+
+ // move to the origin
+ double o1[3];
+ o1[0] = other_facet.t.b.x-t.b.x;
+ o1[1] = other_facet.t.b.y-t.b.y;
+ o1[2] = other_facet.t.b.z-t.b.z;
+
+ double dot_p = agt->dot_vec(norm1,o1);
+ return (CubitBoolean)(dot_p >= 0.0);
+}
+
double
SurfaceOverlapFacet::angle( SurfaceOverlapFacet &other_facet )
{
@@ -58,9 +76,9 @@
}
double
-SurfaceOverlapFacet::projected_overlap( SurfaceOverlapFacet &other_facet )
+SurfaceOverlapFacet::projected_overlap( SurfaceOverlapFacet &other_facet, CubitBoolean draw_overlap )
{
- double tmp_double = agt->ProjectedOverlap( t, other_facet.t );
+ double tmp_double = agt->ProjectedOverlap( t, other_facet.t, draw_overlap );
if( tmp_double > 0.00 )
{
@@ -98,9 +116,10 @@
t.e1.y + t.b.y,
t.e1.z + t.b.z );
- GfxDebug::draw_line( point1, point2, color );
- GfxDebug::draw_line( point2, point3, color );
- GfxDebug::draw_line( point1, point3, color );
+ GfxPreview::draw_line( point1, point2, color );
+ GfxPreview::draw_line( point2, point3, color );
+ GfxPreview::draw_line( point1, point3, color );
+
return;
}
Modified: cgm/branches/cubit/geom/SurfaceOverlapFacet.hpp
===================================================================
--- cgm/branches/cubit/geom/SurfaceOverlapFacet.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/SurfaceOverlapFacet.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -35,8 +35,10 @@
~SurfaceOverlapFacet();
double distance( SurfaceOverlapFacet &other_facet );
+ CubitBoolean facing( SurfaceOverlapFacet &other_facet );
double angle( SurfaceOverlapFacet &other_facet );
- double projected_overlap( SurfaceOverlapFacet &other_facet );
+ double projected_overlap( SurfaceOverlapFacet &other_facet,
+ CubitBoolean draw_overlap = CUBIT_FALSE );
bool bbox_overlap( double tol, SurfaceOverlapFacet &other_facet )
{ return boundingBox.overlap( tol, other_facet.boundingBox ); }
Modified: cgm/branches/cubit/geom/SurfaceOverlapTool.cpp
===================================================================
--- cgm/branches/cubit/geom/SurfaceOverlapTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/SurfaceOverlapTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -6,9 +6,11 @@
#include "RefEntityFactory.hpp"
#include "SurfaceOverlapTool.hpp"
+#include "RefVertex.hpp"
#include "RefEdge.hpp"
#include "RefFace.hpp"
#include "Body.hpp"
+#include "CoEdge.hpp"
#include "BodySM.hpp"
#include "RefGroup.hpp"
#include "GeometryModifyTool.hpp"
@@ -30,9 +32,12 @@
#include "AbstractTree.hpp"
#include "GMem.hpp"
-#include "GfxDebug.hpp"
#include "SettingHandler.hpp"
+#include "GfxPreview.hpp"
+#include "GfxDebug.hpp"
+#include "CpuTimer.hpp"
+
#define NO_FACETS_FOR_ABSTRACTTREE 10
SurfaceOverlapTool* SurfaceOverlapTool::instance_ = 0;
@@ -50,6 +55,7 @@
unsigned short SurfaceOverlapTool::facetAngTol = 15; // Seems to work pretty good
CubitBoolean SurfaceOverlapTool::checkWithinBodies = CUBIT_FALSE;
CubitBoolean SurfaceOverlapTool::checkAcrossBodies = CUBIT_TRUE;
+bool SurfaceOverlapTool::skipFacingSurfaces = CUBIT_FALSE; // skip the pair if the normals pass through eachother (normalType must == 2)
// Constructor
SurfaceOverlapTool* SurfaceOverlapTool::instance()
@@ -75,6 +81,7 @@
imprintResults = CUBIT_FALSE;
checkWithinBodies = CUBIT_FALSE;
checkAcrossBodies = CUBIT_TRUE;
+ skipFacingSurfaces = CUBIT_FALSE;
}
// Destructor
@@ -83,82 +90,108 @@
delete instance_;
}
+CubitBoolean SurfaceOverlapTool::draw_overlapping_surface_pair( RefFace *ref_face_1,
+ RefFace *ref_face_2)
+{
+ CubitBoolean abort = CUBIT_FALSE;
+ CubitBoolean draw_overlap = CUBIT_TRUE;
+ CubitBoolean overlap = check_overlap( ref_face_1, ref_face_2,
+ abort, draw_overlap );
+
+ return overlap;
+}
+
CubitStatus
SurfaceOverlapTool::find_overlapping_surfaces( DLIList<RefFace*> &ref_face_list,
- DLIList<RefEntity*> &faces_to_draw )
+ DLIList<RefEntity*> &faces_to_draw,
+ bool filter_slivers)
{
DLIList<RefFace*> list1, list2;
- return find_overlapping_surfaces( ref_face_list, list1, list2, faces_to_draw, CUBIT_TRUE );
+ return find_overlapping_surfaces( ref_face_list, list1, list2, faces_to_draw, CUBIT_TRUE,
+ filter_slivers);
}
CubitStatus
SurfaceOverlapTool::find_overlapping_surfaces( DLIList<Body*> &body_list,
- DLIList<RefEntity*> &faces_to_draw )
+ DLIList<RefEntity*> &faces_to_draw,
+ bool filter_slivers)
{
DLIList<RefFace*> list1, list2;
- return find_overlapping_surfaces( body_list, list1, list2, faces_to_draw, CUBIT_TRUE );
+ return find_overlapping_surfaces( body_list, list1, list2, faces_to_draw, CUBIT_TRUE,
+ filter_slivers);
}
+
CubitStatus
SurfaceOverlapTool::find_overlapping_surfaces( DLIList<BodySM*> &body_list,
DLIList<Surface*> &surface_list1,
- DLIList<Surface*> &surface_list2)
+ DLIList<Surface*> &surface_list2,
+ bool filter_slivers)
{
- int i,j;
- DLIList<BodySM*> tmp_body_list = body_list;
+ //collect all the surfaces
+ DLIList<Surface*> surface_list;
+ int i;
+ for( i=body_list.size(); i--; )
+ {
+ BodySM *body_sm = body_list.get_and_step();
+ DLIList<Surface*> surfs;
+ body_sm->surfaces_ignore_virtual( surfs, false );
+// body_sm->surfaces( surfs );
+ surface_list.merge_unique( surfs );
+ }
+
+ double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS;
+
+ // Populate the Surface AbstractTree
+ AbstractTree<Surface*> *a_tree = new RTree<Surface*>( tolerance );
+ surface_list.reset();
+ for( i=surface_list.size(); i--; )
+ {
+ Surface *surface = surface_list.get_and_step();
+ a_tree->add( surface );
+ }
+
+ std::map<Surface*, DLIList<SurfaceOverlapFacet*>* > surface_facet_map;
std::map<Surface*, double > surface_to_area_map;
- std::map<Surface*, DLIList<SurfaceOverlapFacet*>* > surface_facet_map;
std::map<Surface*, AbstractTree<SurfaceOverlapFacet*>* > a_tree_map;
- double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS;
- for(i=tmp_body_list.size(); i--; )
+ surface_list.reset();
+ for( i=surface_list.size(); i--; )
{
- BodySM *tmp_body1 = tmp_body_list.pop();
- CubitBox body_box1 = tmp_body1->bounding_box();
+ Surface *surf1 = surface_list.get_and_step();
- tmp_body_list.reset();
- for(j=tmp_body_list.size(); j--; )
- {
- BodySM *tmp_body2 = tmp_body_list.get_and_step();
+ BodySM *surf1_body = surf1->bodysm();
- //determine if bodies are close enough to have overlapping curves
- CubitBox body_box2 = tmp_body2->bounding_box();
+ // Remove this surface from AbstractTree so it is not found and never
+ // found again
+ a_tree->remove( surf1 );
- if( body_box1.overlap( tolerance, body_box2 ) )
- {
- //check individual surfaces for bounding box interference
- DLIList<Surface*> surfaces1, surfaces2;
- tmp_body1->surfaces( surfaces1 );
- tmp_body2->surfaces( surfaces2 );
-
- int ii;
- for( ii=surfaces1.size(); ii--; )
- {
- Surface *surface1 = surfaces1.get_and_step();
+ // Find RefFaces from AbstractTree that are within range of this surface
+ CubitBox surf1_box = surf1->bounding_box();
+ DLIList<Surface*> close_surfaces;
+ a_tree->find( surf1_box, close_surfaces );
- CubitBox surf1_bbox = surface1->bounding_box();
+ int j;
+ for( j=close_surfaces.size(); j--; )
+ {
+ Surface *surf2 = close_surfaces.get_and_step();
+ BodySM *surf2_body = surf2->bodysm();
- int jj;
- for( jj=surfaces2.size(); jj--; )
- {
- Surface *surface2 = surfaces2.get_and_step();
- CubitBox surf2_bbox = surface2->bounding_box();
+ //don't check for overlapping surfaces within bodies
+ if( surf1_body == surf2_body )
+ continue;
- if( surf1_bbox.overlap( tolerance, surf2_bbox ) == CUBIT_FALSE )
- continue;
-
- if( check_overlap( surface1, surface2,
- &surface_facet_map, &surface_to_area_map, &a_tree_map ) == CUBIT_TRUE )
- {
- surface_list1.append( surface1 );
- surface_list2.append( surface2 );
- }
- }
- }
+ if( check_overlap( surf1, surf2,
+ &surface_facet_map,
+ &surface_to_area_map,
+ &a_tree_map ) == CUBIT_TRUE )
+ {
+ surface_list1.append( surf1 );
+ surface_list2.append( surf2 );
}
}
}
-
+
//clean up maps;
std::map<Surface*, AbstractTree<SurfaceOverlapFacet*>* >::iterator tree_iter;
tree_iter = a_tree_map.begin();
@@ -178,7 +211,9 @@
//delete the list
delete tmp_list;
}
-
+
+ delete a_tree;
+
return CUBIT_SUCCESS;
}
@@ -187,7 +222,8 @@
DLIList<RefFace*> &ref_face_list1,
DLIList<RefFace*> &ref_face_list2,
DLIList<RefEntity*> &faces_to_draw,
- CubitBoolean show_messages )
+ CubitBoolean show_messages,
+ bool filter_slivers)
{
CubitStatus status = CUBIT_SUCCESS;
@@ -239,7 +275,7 @@
}
status = find_overlapping_surfaces( ref_face_list, ref_face_list1,
- ref_face_list2, faces_to_draw, list_pairs, prog_step );
+ ref_face_list2, faces_to_draw, list_pairs, prog_step, filter_slivers );
if( show_messages && ref_face_list.size() > prog_step )
AppUtil::instance()->progress_tool()->end();
@@ -270,7 +306,7 @@
body_ptr->ref_faces( body_face_list );
status = find_overlapping_surfaces( body_face_list, ref_face_list1,
- ref_face_list2, faces_to_draw, list_pairs, -1 );
+ ref_face_list2, faces_to_draw, list_pairs, -1, filter_slivers );
if( show_messages && body_list.size() > prog_step )
AppUtil::instance()->progress_tool()->step();
@@ -316,7 +352,8 @@
DLIList<RefFace*> &ref_face_list1,
DLIList<RefFace*> &ref_face_list2,
DLIList<RefEntity*> &faces_to_draw,
- CubitBoolean show_messages)
+ CubitBoolean show_messages,
+ bool filter_slivers)
{
CubitStatus status = CUBIT_SUCCESS;
@@ -350,7 +387,7 @@
prog_step = -1;
status = find_overlapping_surfaces( ref_face_list, ref_face_list1,
- ref_face_list2, faces_to_draw, list_pairs, prog_step );
+ ref_face_list2, faces_to_draw, list_pairs, prog_step, filter_slivers );
if( show_messages && ref_face_list.size() > prog_step )
AppUtil::instance()->progress_tool()->end();
@@ -389,7 +426,8 @@
DLIList<RefFace*> &ref_face_list2,
DLIList<RefEntity*> &pair_list,
CubitBoolean list_pairs,
- int prog_step )
+ int prog_step,
+ bool filter_slivers)
{
int number_pairs = 0;
CubitBoolean abort = CUBIT_FALSE;
@@ -442,8 +480,75 @@
ref_face_ptr2 = close_ref_faces.get_and_step();
- if( check_overlap( ref_face_ptr1, ref_face_ptr2, abort ) == CUBIT_TRUE )
+ bool overlap = check_overlap( ref_face_ptr1, ref_face_ptr2, abort );
+ if(overlap == CUBIT_TRUE && filter_slivers)
{
+ RefFace *f1, *f2;
+ DLIList<RefEdge*> f1_edges, f2_edges, *f1_edge_list, *f2_edge_list;
+ ref_face_ptr1->ref_edges(f1_edges);
+ ref_face_ptr2->ref_edges(f2_edges);
+ if(f1_edges.size() > f2_edges.size())
+ {
+ f1 = ref_face_ptr2;
+ f2 = ref_face_ptr1;
+ f1_edge_list = &f2_edges;
+ f2_edge_list = &f1_edges;
+ }
+ else
+ {
+ f1 = ref_face_ptr1;
+ f2 = ref_face_ptr2;
+ f1_edge_list = &f1_edges;
+ f2_edge_list = &f2_edges;
+ }
+ int b;
+ for(b=f1_edge_list->size(); b>0 && overlap; b--)
+ {
+ RefEdge *cur_edge = f1_edge_list->get_and_step();
+ if(cur_edge->is_merged())
+ {
+ DLIList<RefFace*> face_list;
+ cur_edge->ref_faces(face_list);
+ if(face_list.is_in_list(f2))
+ {
+ CubitVector mid_pt;
+ cur_edge->mid_point(mid_pt);
+ CubitVector f1_norm = f1->normal_at(mid_pt);
+ CubitVector f2_norm = f2->normal_at(mid_pt);
+ DLIList<CoEdge*> f1_coedges, f2_coedges;
+ cur_edge->get_co_edges(f1_coedges, f1);
+ cur_edge->get_co_edges(f2_coedges, f2);
+ if(f1_coedges.size() == 1 && f2_coedges.size() == 1)
+ {
+ CoEdge *ce1 = f1_coedges.get();
+ CoEdge *ce2 = f2_coedges.get();
+ CubitVector curve_dir;
+
+ if( cur_edge->get_curve_ptr()->geometry_type() == STRAIGHT_CURVE_TYPE )
+ cur_edge->get_point_direction(mid_pt, curve_dir);
+ else
+ cur_edge->tangent( mid_pt, curve_dir );
+
+ CubitVector ce1_dir, ce2_dir;
+ if(ce1->get_sense() == CUBIT_REVERSED)
+ ce1_dir = -curve_dir;
+ else
+ ce1_dir = curve_dir;
+ if(ce2->get_sense() == CUBIT_REVERSED)
+ ce2_dir = -curve_dir;
+ else
+ ce2_dir = curve_dir;
+ CubitVector in_dir1 = f1_norm * ce1_dir;
+ CubitVector in_dir2 = f2_norm * ce2_dir;
+ if(in_dir1 % in_dir2 < 0.0)
+ overlap = false;
+ }
+ }
+ }
+ }
+ }
+ if(overlap)
+ {
if( abort == CUBIT_TRUE )
goto done;
@@ -521,8 +626,6 @@
if( facet_map == NULL || facet_iterator == facet_map->end() )
{
- int junk1, junk2, junk3;
-
//for non-planar surfaces, facet wrt the smallest curve of the surface
double min_edge_length = 0.0;
@@ -538,7 +641,7 @@
{
min_edge_length = CUBIT_DBL_MAX;
double tmp_length;
- for( junk1=tmp_curves.size(); junk1--; )
+ for( i=tmp_curves.size(); i--; )
{
tmp_length = tmp_curves.get_and_step()->measure();
if( tmp_length > min_length_threshold && tmp_length < min_edge_length )
@@ -553,8 +656,7 @@
facet_list1 = new DLIList<SurfaceOverlapFacet*>;
GMem surface_graphics;
- surface1->get_geometry_query_engine()->get_graphics( surface1, junk1,
- junk2, junk3, &surface_graphics,
+ surface1->get_geometry_query_engine()->get_graphics( surface1, &surface_graphics,
facetAngTol, facetAbsTol, min_edge_length );
GPoint* plist = surface_graphics.point_list();
@@ -594,8 +696,6 @@
if( facet_map == NULL || facet_iterator == facet_map->end() )
{
- int junk1, junk2, junk3;
-
//for non-planar surfaces, facet wrt the smallest curve of the surface
double min_edge_length = 0.0;
@@ -611,7 +711,7 @@
{
min_edge_length = CUBIT_DBL_MAX;
double tmp_length;
- for( junk1=tmp_curves.size(); junk1--; )
+ for( i=tmp_curves.size(); i--; )
{
tmp_length = tmp_curves.get_and_step()->measure();
if( tmp_length > min_length_threshold && tmp_length < min_edge_length )
@@ -626,8 +726,7 @@
facet_list2 = new DLIList<SurfaceOverlapFacet*>;
GMem surface_graphics;
- surface2->get_geometry_query_engine()->get_graphics( surface2, junk1,
- junk2, junk3, &surface_graphics,
+ surface2->get_geometry_query_engine()->get_graphics( surface2, &surface_graphics,
facetAngTol, facetAbsTol, min_edge_length );
GPoint* plist = surface_graphics.point_list();
@@ -742,50 +841,50 @@
if( area_map )
{
std::map<Surface*, double>::iterator area_iter;
- area_iter = area_map->find( surface1 );
+ area_iter = area_map->find( tmp_surf1);
if( area_iter == area_map->end() )
{
- face1_area = surface1->measure();
- area_map->insert( std::map<Surface*, double>::value_type( surface1, face1_area ) );
+ face1_area = tmp_surf1->measure();
+ area_map->insert( std::map<Surface*, double>::value_type( tmp_surf1, face1_area ) );
}
else
face1_area = area_iter->second;
- area_iter = area_map->find( surface2 );
+ area_iter = area_map->find( tmp_surf2);
if( area_iter == area_map->end() )
{
- face2_area = surface2->measure();
- area_map->insert( std::map<Surface*, double>::value_type( surface2, face2_area ));
+ face2_area = tmp_surf2->measure();
+ area_map->insert( std::map<Surface*, double>::value_type( tmp_surf2, face2_area ));
}
else
face2_area = area_iter->second;
}
else
{
- face1_area = surface1->measure();
- face2_area = surface2->measure();
+ face1_area = tmp_surf1->measure();
+ face2_area = tmp_surf2->measure();
}
bool sample_deviation = false;
Surface *larger_surface = NULL;
//if the surfaces are non planar and one is much bigger than the other one...
//adjust the tolerance some
- if( (surface1->geometry_type() != PLANE_SURFACE_TYPE &&
- surface2->geometry_type() != PLANE_SURFACE_TYPE) )
+ if( (tmp_surf1->geometry_type() != PLANE_SURFACE_TYPE &&
+ tmp_surf2->geometry_type() != PLANE_SURFACE_TYPE) )
{
- double length1 = surface1->bounding_box().diagonal().length();
- double length2 = surface2->bounding_box().diagonal().length();
+ double length1 = tmp_surf1->bounding_box().diagonal().length();
+ double length2 = tmp_surf2->bounding_box().diagonal().length();
double ratio = 0;
if(length1 > length2)
{
ratio = length1/length2;
- larger_surface = surface1;
+ larger_surface = tmp_surf1;
}
else
{
ratio = length2/length1;
- larger_surface = surface2;
+ larger_surface = tmp_surf2;
}
if( ratio > 50 )
@@ -809,7 +908,7 @@
if( sample_deviation )
{
DLIList<SurfaceOverlapFacet*> *tmp_facet_list = NULL;
- if( larger_surface == surface1 )
+ if( larger_surface == tmp_surf1 )
tmp_facet_list = facet_list1;
else
tmp_facet_list = facet_list2;
@@ -818,8 +917,10 @@
for( i=tmp_facet_list->size(); i--; )
{
SurfaceOverlapFacet *tmp_facet = tmp_facet_list->get_and_step();
- if( (i%7) == 0)
- {
+ //we used to be lucky, where one seventh of the facets would give us a
+ //decent tolerance...this doesn't work now....not robust enough
+// if( (i%7) == 0) // commenting this out....sometimes you haveto
+// {
CubitVector point = tmp_facet->smallest_edge_midpoint();
//determine distance between surface and centroid
@@ -827,8 +928,10 @@
larger_surface->closest_point_trimmed( point, tmp_point );
double tmp_distance = point.distance_between( tmp_point );
if( tmp_distance > facet_compare_tol )
+ {
facet_compare_tol = tmp_distance;
- }
+ }
+// }
}
}
else
@@ -845,6 +948,11 @@
facet_compare_tol *= 0.0025;
}
}
+
+ //if the merge tolerance is a larger, use it
+ double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS;
+ if( tolerance > facet_compare_tol )
+ facet_compare_tol = tolerance;
facet_list1->reset();
for( i=facet_list1->size(); i--; )
@@ -871,22 +979,107 @@
// normalType - 1=any, 2=opposite, 3=same
//ang>=180.0-angt || ang<angt
- if( (normalType==1 && ang>=opp_low && ang<=opp_high) ||
+ if( ((normalType==1 && ang>=opp_low && ang<=opp_high) ||
+ (normalType==1 && ang>=angleMin && ang<=angleMax) ||
+ (normalType==2 && ang>=opp_low && ang<=opp_high) ||
+ (normalType==3 && ang>=angleMin && ang<=angleMax)) &&
+ (normalType != 2 || !skipFacingSurfaces || !facet1->facing( *facet2 )))// check to make sure the surfaces are not facing
+ {
+ // If triangle bounding boxes don't intersect - no overlap
+ if( facet1->bbox_overlap( facet_compare_tol, *facet2 ) )
+ {
+ // Check distance between triangles, must be within criteria
+ double dist = facet1->distance( *facet2 );
+ if( dist >= gapMin && dist <= facet_compare_tol )
+ {
+ // Check for projected overlap
+ // We want sum of area of ALL overlapping facets
+ area += facet1->projected_overlap( *facet2 );
+ if( area > tmp_overlapTolerance )
+ {
+ return CUBIT_TRUE;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return CUBIT_FALSE;
+}
+
+CubitBoolean
+SurfaceOverlapTool::check_overlap( DLIList<SurfaceOverlapFacet*> *facet_list1,
+ DLIList<SurfaceOverlapFacet*> *facet_list2,
+ AbstractTree<SurfaceOverlapFacet*> *a_tree,
+ CubitBoolean abort,
+ CubitBoolean draw_overlap,
+ double *overlap_area )
+{
+ double area = 0;
+ double opp_low = 180.0 - angleMax;
+ double opp_high = 180.0 - angleMin;
+
+ facet_list1->reset();
+ int num_tri1 = facet_list1->size();
+ int i,j;
+ for( i=num_tri1; i--; )
+ {
+ // Cancel button pushed or cntrl-C
+ if (CubitMessage::instance()->Interrupt())
+ {
+ PRINT_INFO("Find overlap operation aborted.\n");
+ abort = CUBIT_TRUE;
+ return CUBIT_FALSE;
+ }
+
+ SurfaceOverlapFacet *facet1 = facet_list1->get_and_step();
+
+ DLIList<SurfaceOverlapFacet*> close_facets;
+ if( a_tree )
+ {
+ a_tree->find( facet1->bounding_box(), close_facets );
+ facet_list2 = &close_facets;
+ }
+
+ facet_list2->reset();
+ for( j=facet_list2->size(); j--; )
+ {
+ // Cancel button pushed or cntrl-C
+ if (CubitMessage::instance()->Interrupt())
+ {
+ PRINT_INFO("Find overlap operation aborted.\n");
+ abort = CUBIT_TRUE;
+ return CUBIT_FALSE;
+ }
+
+ SurfaceOverlapFacet *facet2 = facet_list2->get_and_step();
+
+ // Check angle between triangles, must be within criteria
+ double ang = facet1->angle( *facet2 );
+
+ // Allow overlap for angles close to 180 and 0 degrees
+
+ // normalType - 1=any, 2=opposite, 3=same
+ //ang>=180.0-angt || ang<angt
+ if( ((normalType==1 && ang>=opp_low && ang<=opp_high) ||
(normalType==1 && ang>=angleMin && ang<=angleMax) ||
(normalType==2 && ang>=opp_low && ang<=opp_high) ||
- (normalType==3 && ang>=angleMin && ang<=angleMax) )
+ (normalType==3 && ang>=angleMin && ang<=angleMax) ) &&
+ (normalType != 2 || !skipFacingSurfaces || !facet1->facing( *facet2 )))// check to make sure the surfaces are not facing )
{
// If triangle bounding boxes don't intersect - no overlap
- if( facet1->bbox_overlap( facet_compare_tol, *facet2 ) )
+ if( facet1->bbox_overlap( gapMax, *facet2 ) )
{
// Check distance between triangles, must be within criteria
double dist = facet1->distance( *facet2 );
- if( dist >= gapMin && dist <= facet_compare_tol )
+ if( dist >= gapMin && dist <= gapMax )
{
// Check for projected overlap
// We want sum of area of ALL overlapping facets
- area += facet1->projected_overlap( *facet2 );
- if( area > tmp_overlapTolerance )
+ area += facet1->projected_overlap( *facet2, draw_overlap );
+ if( area > overlapTolerance &&
+ (draw_overlap == CUBIT_FALSE && overlap_area == NULL ) )
{
return CUBIT_TRUE;
}
@@ -894,14 +1087,32 @@
}
}
}
+ }
+ if( draw_overlap == CUBIT_TRUE )
+ {
+ PRINT_INFO("Total overlapping area = %lf\n", area );
+
+ if( area > 0.0 )
+ return CUBIT_TRUE;
}
+
+ if( overlap_area )
+ {
+ if( area > 0.0 )
+ {
+ *overlap_area = area;
+ return CUBIT_TRUE;
+ }
+ }
+
return CUBIT_FALSE;
}
-
CubitBoolean
SurfaceOverlapTool::check_overlap( RefFace *ref_face_ptr1, RefFace *ref_face_ptr2,
- CubitBoolean abort )
+ CubitBoolean abort,
+ CubitBoolean draw_overlap,
+ double *overlap_area )
{
if( ref_face_ptr1 == ref_face_ptr2 )
return CUBIT_FALSE;
@@ -913,12 +1124,9 @@
(ref_face_ptr1->get_surface_ptr()->geometry_type() !=
ref_face_ptr2->get_surface_ptr()->geometry_type() ))
return CUBIT_FALSE;
-
- int i, j;
+
AnalyticGeometryTool::instance();
abort = CUBIT_FALSE;
- double opp_low = 180.0 - angleMax;
- double opp_high = 180.0 - angleMin;
// Check for overlap between the found surfaces using the facets
TDSurfaceOverlap *tdso_1;
@@ -1017,79 +1225,13 @@
a_tree = tdso_2->get_facet_rtree();
}
- double area = 0;
+ bool surfs_overlap = check_overlap( facet_list1, facet_list2, a_tree,
+ abort, draw_overlap, overlap_area );
- facet_list1->reset();
- num_tri1 = facet_list1->size();
- for( i=num_tri1; i--; )
- {
- // Cancel button pushed or cntrl-C
- if (CubitMessage::instance()->Interrupt())
- {
- PRINT_INFO("Find overlap operation aborted.\n");
- abort = CUBIT_TRUE;
- return CUBIT_FALSE;
- }
-
- SurfaceOverlapFacet *facet1 = facet_list1->get_and_step();
-
- DLIList<SurfaceOverlapFacet*> close_facets;
- if( a_tree )
- {
- a_tree->find( facet1->bounding_box(), close_facets );
- facet_list2 = &close_facets;
- }
-
- facet_list2->reset();
- for( j=facet_list2->size(); j--; )
- {
- // Cancel button pushed or cntrl-C
- if (CubitMessage::instance()->Interrupt())
- {
- PRINT_INFO("Find overlap operation aborted.\n");
- abort = CUBIT_TRUE;
- return CUBIT_FALSE;
- }
-
- SurfaceOverlapFacet *facet2 = facet_list2->get_and_step();
-
- // Check angle between triangles, must be within criteria
- double ang = facet1->angle( *facet2 );
-
- // Allow overlap for angles close to 180 and 0 degrees
-
- // normalType - 1=any, 2=opposite, 3=same
- //ang>=180.0-angt || ang<angt
- if( (normalType==1 && ang>=opp_low && ang<=opp_high) ||
- (normalType==1 && ang>=angleMin && ang<=angleMax) ||
- (normalType==2 && ang>=opp_low && ang<=opp_high) ||
- (normalType==3 && ang>=angleMin && ang<=angleMax) )
- {
- // If triangle bounding boxes don't intersect - no overlap
- if( facet1->bbox_overlap( gapMax, *facet2 ) )
- {
- // Check distance between triangles, must be within criteria
- double dist = facet1->distance( *facet2 );
- if( dist >= gapMin && dist <= gapMax )
- {
- // Check for projected overlap
- // We want sum of area of ALL overlapping facets
- area += facet1->projected_overlap( *facet2 );
- if( area > overlapTolerance )
- {
- return CUBIT_TRUE;
- }
- }
- }
- }
- }
- }
- return CUBIT_FALSE;
+ return surfs_overlap;
}
-
-void
-SurfaceOverlapTool::list_settings()
+void SurfaceOverlapTool::list_settings()
{
char on_off[2][4];
strcpy( on_off[0], "Off" );
@@ -1477,73 +1619,81 @@
return CUBIT_SUCCESS;
}
-CubitStatus SurfaceOverlapTool::find_overlapping_curves( DLIList<BodySM*> &bodies,
+CubitStatus SurfaceOverlapTool::find_overlapping_curves( DLIList<Curve*> &curve_list,
DLIList< DLIList<Curve*> *> &overlapping_curve_lists,
- std::map<Curve*, DLIList<Curve*>* > &curve_to_list_map)
+ std::map<Curve*, DLIList<Curve*>* > &curve_to_list_map,
+ std::multimap<BodySM*, CubitVector> &body_point_imprint_map)
{
+ int i;
+
+ //put all the curves into a tree
+ double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS;
+
+ // Populate the Surface AbstractTree
+ AbstractTree<Curve*> *a_tree = new RTree<Curve*>( tolerance );
+ curve_list.reset();
+ for( i=curve_list.size(); i--; )
+ {
+ Curve *curve = curve_list.get_and_step();
+ a_tree->add( curve );
+ }
+
std::map<Curve*, DLIList<CurveOverlapFacet*>* > facet_map;
std::map<Curve*, DLIList<Curve*>* >::iterator list_iter;
-
- double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS;
- int i,j;
- bodies.reset();
- DLIList<BodySM*> tmp_body_list = bodies;
- for(i=tmp_body_list.size(); i--; )
+ curve_list.reset();
+ for( i=curve_list.size(); i--; )
{
- BodySM *tmp_body1 = tmp_body_list.pop();
- CubitBox body_box1 = tmp_body1->bounding_box();
+ Curve *curve1= curve_list.get_and_step();
- tmp_body_list.reset();
- for(j=tmp_body_list.size(); j--; )
+ BodySM *curve1_body = curve1->bodysm();
+
+ // Remove this surface from AbstractTree so it is not found and never
+ // found again
+ a_tree->remove( curve1 );
+
+ // Find RefFaces from AbstractTree that are within range of this surface
+ CubitBox curve1_box = curve1->bounding_box();
+ DLIList<Curve*> close_curves;
+ a_tree->find( curve1_box, close_curves );
+
+ int j;
+ for( j=close_curves.size(); j--; )
{
- BodySM *tmp_body2 = tmp_body_list.get_and_step();
-
- if( tmp_body2 == tmp_body1 )
+ Curve *curve2 = close_curves.get_and_step();
+ BodySM *curve2_body = curve2->bodysm();
+
+ if( curve2_body == curve1_body )
continue;
- //determine if bodies are close enough to have overlapping curves
- CubitBox body_box2 = tmp_body2->bounding_box();
- int ii, jj;
+ std::multimap<BodySM*, CubitVector> tmp_body_point_imprint_map;
- if( body_box1.overlap( tolerance, body_box2 ) )
+ if( check_overlap( curve1, curve2, &facet_map, &tmp_body_point_imprint_map ) )
{
- //check individual curves for bounding box interference
- DLIList<Curve*> curves1, curves2;
- tmp_body1->curves( curves1 );
- tmp_body2->curves( curves2 );
-
- for( ii=curves1.size(); ii--; )
+ //check to see if the curve1 is already overlapping with another curve
+ list_iter = curve_to_list_map.find( curve1 );
+ if( list_iter != curve_to_list_map.end() )
{
- Curve *curve1 = curves1.get_and_step();
-
- for( jj=curves2.size(); jj--; )
- {
- Curve *curve2 = curves2.get_and_step();
-
- if( check_overlap( curve1, curve2, &facet_map ) )
- {
- //check to see if the curve1 is already overlapping with another edge
- list_iter = curve_to_list_map.find( curve1 );
- if( list_iter != curve_to_list_map.end() )
- {
- DLIList<Curve*> *curve_list = list_iter->second;
- curve_list->append( curve2 );
- }
- else
- {
- //list for curve 1 does not exist....make a new one
- DLIList<Curve*> *curve_list = new DLIList<Curve*>;
- overlapping_curve_lists.append( curve_list );
- curve_list->append( curve1 );
- curve_list->append( curve2 );
- curve_to_list_map.insert( std::map<Curve*,
- DLIList<Curve*>*>::value_type( curve1, curve_list ));
- }
- }
- }
+ DLIList<Curve*> *tmp_curve_list = list_iter->second;
+ tmp_curve_list->append( curve2 );
}
+ else
+ {
+ //list for curve 1 does not exist....make a new one
+ DLIList<Curve*> *tmp_curve_list = new DLIList<Curve*>;
+ overlapping_curve_lists.append( tmp_curve_list );
+ tmp_curve_list->append( curve1 );
+ tmp_curve_list->append( curve2 );
+ curve_to_list_map.insert( std::map<Curve*,
+ DLIList<Curve*>*>::value_type( curve1, tmp_curve_list ));
+ }
}
+ else
+ {
+ //append what's in body_point_imprint_map to one passed in
+ body_point_imprint_map.insert( tmp_body_point_imprint_map.begin(),
+ tmp_body_point_imprint_map.end() );
+ }
}
}
@@ -1560,16 +1710,63 @@
delete co_facet_list;
}
+ delete a_tree;
+
return CUBIT_SUCCESS;
}
+CubitStatus SurfaceOverlapTool::find_overlapping_curves( DLIList<Surface*> &surf_list,
+ DLIList< DLIList<Curve*> *> &overlapping_curve_lists,
+ std::map<Curve*, DLIList<Curve*>* > &curve_to_list_map,
+ std::multimap<BodySM*, CubitVector> &body_point_imprint_map)
+{
+ //collect all the surfaces
+ DLIList<Curve*> curve_list;
+ int i;
+ for( i=surf_list.size(); i--; )
+ {
+ Surface *surf = surf_list.get_and_step();
+ DLIList<Curve*> curves;
+ surf->curves_ignore_virtual(curves, false);
+// body_sm->curves( curves);
+ curve_list.merge_unique( curves );
+ }
+
+ return find_overlapping_curves(curve_list, overlapping_curve_lists, curve_to_list_map,
+ body_point_imprint_map);
+}
+
+CubitStatus SurfaceOverlapTool::find_overlapping_curves( DLIList<BodySM*> &body_list,
+ DLIList< DLIList<Curve*> *> &overlapping_curve_lists,
+ std::map<Curve*, DLIList<Curve*>* > &curve_to_list_map,
+ std::multimap<BodySM*, CubitVector> &body_point_imprint_map )
+{
+ //collect all the surfaces
+ DLIList<Curve*> curve_list;
+ int i;
+ for( i=body_list.size(); i--; )
+ {
+ BodySM *body_sm = body_list.get_and_step();
+ DLIList<Curve*> curves;
+ body_sm->curves_ignore_virtual(curves, false);
+// body_sm->curves( curves);
+ curve_list.merge_unique( curves );
+ }
+
+ return find_overlapping_curves(curve_list, overlapping_curve_lists, curve_to_list_map,
+ body_point_imprint_map);
+
+}
+
CubitStatus SurfaceOverlapTool::find_overlapping_curves( DLIList<Body*> &bodies,
- std::multimap<RefEdge*, RefEdge*> &overlapping_edge_map )
+ std::multimap<RefEdge*, RefEdge*> &overlapping_edge_map,
+ double maxgap /* =-1*/)
{
- std::map<RefEdge*, DLIList<CurveOverlapFacet*>* > facet_map;
std::map<RefEdge*, DLIList<CurveOverlapFacet*>* >::iterator list_iter;
double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS;
+ if (maxgap != -1 && maxgap != 0.0)
+ tolerance = maxgap;
int i,j;
DLIList<Body*> tmp_body_list = bodies;
@@ -1588,55 +1785,172 @@
if( body_box1.overlap( tolerance, body_box2 ) )
{
- //check individual curves for bounding box interference
+ // create list of edges on each body.
+ // put the edges in body2 in edges1 so edges1 contains
+ // the list of curves contained in the body listed first in the list
DLIList<RefEdge*> edges1, edges2;
- tmp_body1->ref_edges( edges1 );
- tmp_body2->ref_edges( edges2 );
-
- int ii;
- for( ii=edges1.size(); ii--; )
- {
- RefEdge *edge1 = edges1.get_and_step();
+ tmp_body1->ref_edges( edges2 );
+ tmp_body2->ref_edges( edges1 );
+
+ //check individual curves for bounding box interference
+ if (!find_overlapping_curves(edges1, edges2, overlapping_edge_map, tolerance))
+ return CUBIT_FAILURE;
+ }
+ }
+ }
- int jj;
- for( jj=edges2.size(); jj--; )
- {
- RefEdge *edge2 = edges2.get_and_step();
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus SurfaceOverlapTool::find_overlapping_curves( DLIList<RefFace*> &faces,
+ std::multimap<RefEdge*, RefEdge*> &overlapping_edge_map,
+ double maxgap /*=-1*/)
+{
+ double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS;
+
+ if (maxgap != -1 && maxgap != 0.0)
+ tolerance = maxgap;
+
+ // Populate the Surface AbstractTree
+ AbstractTree<RefFace*> *a_tree = new RTree<RefFace*>( tolerance );
+ faces.reset();
+ int i;
+ for( i=faces.size(); i--; )
+ {
+ RefFace* face = faces.get_and_step();
+ a_tree->add( face );
+ }
+
+ faces.reset();
+ for( i=faces.size(); i--; )
+ {
+ RefFace* face1 = faces.get_and_step();
+
+ Body *face1_body = face1->body();
+
+ // Remove this face from AbstractTree so it is not found and never
+ // found again
+ a_tree->remove( face1 );
+
+ // Find RefFaces from AbstractTree that are within range of this surface
+ CubitBox face1_box = face1->bounding_box();
+ DLIList<RefFace*> close_faces;
+ a_tree->find( face1_box, close_faces );
+
+ int j;
+ for( j=close_faces.size(); j--; )
+ {
+ RefFace *face2 = close_faces.get_and_step();
+ Body *face2_body = face2->body();
+
+ //don't check for overlapping faces within bodies
+ if( face1_body == face2_body )
+ continue;
+
+ DLIList<RefEdge*> edges1, edges2;
+ face1->ref_edges( edges1 );
+ face2->ref_edges( edges2 );
+
+ if (!find_overlapping_curves(edges1, edges2, overlapping_edge_map, tolerance))
+ return CUBIT_FAILURE;
- if( check_overlap( edge1, edge2, &facet_map ) )
- {
- overlapping_edge_map.insert( std::multimap<RefEdge*, RefEdge*>
- ::value_type( edge1, edge2));
- }
- }
- }
+ }
+ }
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus SurfaceOverlapTool::find_overlapping_curves( DLIList<RefEdge*> &edgelist,
+ std::multimap<RefEdge*, RefEdge*> &overlapping_edge_map, double maxgap /*=-1*/ )
+{
+ // for now, check every edge against every other edge
+ // (the helper function will skip edges if they are in the same body)
+
+ DLIList<RefEdge*> edgelist2 = edgelist;
+ return find_overlapping_curves(edgelist, edgelist2, overlapping_edge_map, maxgap);
+}
+
+CubitStatus SurfaceOverlapTool::find_overlapping_curves( DLIList<RefEdge*> &edges1, DLIList<RefEdge*> &edges2,
+ std::multimap<RefEdge*, RefEdge*> &overlapping_edge_map,
+ double maxgap /*=-1*/)
+{
+ int i;
+ std::map<RefEdge*, DLIList<CurveOverlapFacet*>* > facet_map;
+ std::map<RefEdge*, DLIList<CurveOverlapFacet*>* >::iterator list_iter;
+
+ double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS;
+
+ if (maxgap != -1 && maxgap != 0.0)
+ tolerance = maxgap;
+
+ for( i=edges1.size(); i--; )
+ {
+ RefEdge *edge1 = edges1.get_and_step();
+
+ int j;
+ for( j=edges2.size(); j--; )
+ {
+ RefEdge *edge2 = edges2.get_and_step();
+
+ if( edge1 == edge2 )
+ continue;
+
+ bool pair_already_in_map = false;
+
+ std::multimap<RefEdge*, RefEdge*>::iterator it;
+ it = overlapping_edge_map.find( edge2 );
+ if( it != overlapping_edge_map.end() )
+ continue;
+
+ // check to see if this pair is already in the overlap map.
+ // If it is, don't need to bother checking it for overlap
+ /*
+ std::multimap<RefEdge*, RefEdge*>::iterator it;
+ std::pair< std::multimap<RefEdge*,RefEdge*>::iterator, std::multimap<RefEdge*,RefEdge*>::iterator > range;
+
+ range = overlapping_edge_map.equal_range(edge1);
+
+ for (it=range.first; it!=range.second; it++)
+ {
+ if ( (it->second == edge2) && (it->first == edge1) )
+ pair_already_in_map = true;
}
+ if (pair_already_in_map)
+ continue;
+
+ */
+
+ if( check_overlap( edge1, edge2, &facet_map, &tolerance ) )
+ {
+ overlapping_edge_map.insert( std::multimap<RefEdge*, RefEdge*>
+ ::value_type( edge1, edge2));
+ //PRINT_INFO("Curve %d and %d overlap.\n", edge1->id(), edge2->id());
+ //PRINT_INFO("Insert Curve %d, Curve %d.\n", edge1->id(), edge2->id());
+ }
}
}
-
//clean up facet map
list_iter=facet_map.begin();
for(; list_iter != facet_map.end(); list_iter++ )
{
DLIList<CurveOverlapFacet*> *co_facet_list = list_iter->second;
+ //delete all the facets in the list
+ for( i=co_facet_list->size(); i--; )
+ delete co_facet_list->get_and_step();
+ delete co_facet_list;
}
return CUBIT_SUCCESS;
}
CubitBoolean SurfaceOverlapTool::check_overlap( Curve *curve1, Curve *curve2,
- std::map<Curve*, DLIList<CurveOverlapFacet*>* > *facet_map )
+ std::map<Curve*, DLIList<CurveOverlapFacet*>* > *facet_map,
+ std::multimap<BodySM*,CubitVector> *body_point_imprint_map )
{
//if surfaces are not splines and are not of the same type,
//they won't overlap
GeometryType curve1_type = curve1->geometry_type();
GeometryType curve2_type = curve2->geometry_type();
- if( ( curve1_type != SPLINE_CURVE_TYPE &&
- curve2_type != SPLINE_CURVE_TYPE) &&
- (curve1_type != curve2_type ))
- return CUBIT_FALSE;
-
double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS;
std::map<Curve*, DLIList<CurveOverlapFacet*>* >::iterator facet_iterator;
@@ -1652,11 +1966,15 @@
double curve1_length = curve1->measure();
double curve2_length = curve2->measure();
+/*
if( curve1_length < curve2_length )
min_overlap = curve1->measure() * 0.01;
else
min_overlap = curve2->measure() * 0.01;
+ */
+ min_overlap = tolerance;
+
DLIList<CurveOverlapFacet*> *facet_list1 = NULL;
DLIList<CurveOverlapFacet*> *facet_list2 = NULL;
@@ -1669,8 +1987,7 @@
facet_list1 = new DLIList<CurveOverlapFacet*>;
GMem curve_graphics;
- int junk;
- curve1->get_geometry_query_engine()->get_graphics( curve1, junk,
+ curve1->get_geometry_query_engine()->get_graphics( curve1,
&curve_graphics, 0.0 );
GPoint *points = curve_graphics.point_list();
@@ -1705,8 +2022,7 @@
facet_list2 = new DLIList<CurveOverlapFacet*>;
GMem curve_graphics;
- int junk;
- curve2->get_geometry_query_engine()->get_graphics( curve2, junk,
+ curve2->get_geometry_query_engine()->get_graphics( curve2,
&curve_graphics, 0.0 );
GPoint *points = curve_graphics.point_list();
@@ -1737,38 +2053,153 @@
DLIList<CurveOverlapFacet*> *tmp_list = facet_list1;
facet_list1 = facet_list2;
facet_list2 = tmp_list;
+ Curve *tmp_curve = curve1;
+ curve1 = curve2;
+ curve2 = tmp_curve;
}
-
+
+ CubitVector curv1_start_pt;
+ CubitVector curv2_start_pt;
+ CubitVector curv1_end_pt;
+ CubitVector curv2_end_pt;
+
facet_list1->reset();
facet_list2->reset();
+ //get start/end facet points on curves
+ if( body_point_imprint_map )
+ {
+ curv1_start_pt = facet_list1->get()->start_point();
+ curv2_start_pt = facet_list2->get()->start_point();
+ facet_list1->last();
+ facet_list2->last();
+ curv1_end_pt = facet_list1->get()->end_point();
+ curv2_end_pt = facet_list2->get()->end_point();
+ }
+
+ facet_list1->reset();
+ facet_list2->reset();
int kk;
double total_overlap = 0.0;
bool overlap = false;
//now determine if enough curve facets overlap
- for( kk=facet_list1->size(); kk--; )
+ int list_size1 = facet_list1->size();
+ for( kk=list_size1; kk--; )
{
CurveOverlapFacet *curr_facet = facet_list1->get_and_step();
if( curr_facet->length() < GEOMETRY_RESABS )
continue;
+ //if 'curr_facet' is the first or last facet in curve1,
+ //check to see if the start/end point is on curve2, and not coincident
+ //with the start/end point of curve2. If so, it's a case where you need
+ //to imprint this start/end point onto the body of curve2.
+ if( body_point_imprint_map )
+ {
+ if( kk == list_size1-1 ) //first facet in curve1
+ {
+ CubitVector closest_point;
+ curve2->closest_point_trimmed( curr_facet->start_point(), closest_point );
+ if( curv2_start_pt.distance_between( curr_facet->start_point() ) > tolerance &&
+ curv2_end_pt.distance_between( curr_facet->start_point() ) > tolerance &&
+ closest_point.distance_between( curr_facet->start_point() ) < tolerance )
+ {
+ BodySM *tmp_body_sm = curve2->bodysm();
+ body_point_imprint_map->insert( std::multimap<BodySM*,
+ CubitVector>::value_type(
+ tmp_body_sm, closest_point));
+ }
+ }
+ if( kk == 0 ) //last facet in curve1
+ {
+ CubitVector closest_point;
+ curve2->closest_point_trimmed( curr_facet->end_point(), closest_point );
+ if( curv2_start_pt.distance_between( curr_facet->end_point() ) > tolerance &&
+ curv2_end_pt.distance_between( curr_facet->end_point() ) > tolerance &&
+ closest_point.distance_between( curr_facet->end_point() ) < tolerance )
+ {
+ //insert into vertex-volume imprint map
+ BodySM *tmp_body_sm = curve2->bodysm();
+ body_point_imprint_map->insert( std::multimap<BodySM*,
+ CubitVector>::value_type(
+ tmp_body_sm, closest_point));
+ }
+ }
+ }
+
//do bounding boxes of facets overlap?
int jj;
- for( jj=facet_list2->size(); jj--; )
+ int list_size2 = facet_list2->size();
+ for( jj=list_size2; jj--; )
{
CurveOverlapFacet *other_facet = facet_list2->get_and_step();
if( curr_facet->bbox_overlap( tolerance, other_facet ) )
{
- if( curr_facet->facet_to_facet_distance( other_facet ) < tolerance )
+ double distance_between_facets = curr_facet->facet_to_facet_distance( other_facet );
+ if( distance_between_facets < tolerance )
{
if( other_facet->length() < GEOMETRY_RESABS )
continue;
- //are facets parallel within some tolerance angle?
- double angle = curr_facet->angle( other_facet );
- if( angle < 1 || fabs(180-angle ) < 1 )
+ //if 'other_facet' is the first or last facet in curve1,
+ //check to see if the start/end point is on curve1, and not coincident
+ //with the start/end point of curve1. If so, it's a case where you need
+ //to imprint this start/end point onto the body of curve1.
+ if( body_point_imprint_map )
{
+ if( jj == list_size2-1 ) //first facet in curve1
+ {
+ CubitVector closest_point;
+ curve1->closest_point_trimmed( other_facet->start_point(), closest_point );
+
+ if( curv1_start_pt.distance_between( other_facet->start_point() ) > tolerance &&
+ curv1_end_pt.distance_between( other_facet->start_point() ) > tolerance &&
+ closest_point.distance_between( other_facet->start_point() ) < tolerance )
+ {
+ //insert into vertex-volume imprint map
+ BodySM *tmp_body_sm = curve1->bodysm();
+ body_point_imprint_map->insert( std::multimap<BodySM*,
+ CubitVector>::value_type(
+ tmp_body_sm, closest_point ));
+ }
+ }
+ if( jj == 0 ) //last facet in curve1
+ {
+ CubitVector closest_point;
+ curve1->closest_point_trimmed( other_facet->end_point(), closest_point );
+ if( curv1_start_pt.distance_between( other_facet->end_point() ) > tolerance &&
+ curv1_end_pt.distance_between( other_facet->end_point() ) > tolerance &&
+ closest_point.distance_between( other_facet->end_point() ) < tolerance )
+ {
+ //insert into vertex-volume imprint map
+ BodySM *tmp_body_sm = curve1->bodysm();
+ body_point_imprint_map->insert( std::multimap<BodySM*,
+ CubitVector>::value_type(
+ tmp_body_sm, closest_point ));
+ }
+ }
+ }
+
+ //get the long and short facet edge
+ double curr_facet_length = curr_facet->length();
+ double other_facet_length = other_facet->length();
+ CurveOverlapFacet *long_facet = ( curr_facet_length > other_facet_length ?
+ curr_facet : other_facet );
+ CurveOverlapFacet *short_facet = curr_facet;
+ if( long_facet == curr_facet )
+ short_facet = other_facet;
+
+ //make sure both endpoints of the smaller facet edge lie within a radius
+ //or merge tolerance to an infinite line defined by longer facet edge
+ CubitVector direction = long_facet->end_point() - long_facet->start_point();
+ double dist1 = short_facet->start_point().distance_from_infinite_line(
+ long_facet->start_point(), direction );
+ double dist2 = short_facet->end_point().distance_from_infinite_line(
+ long_facet->start_point(), direction );
+
+ if( dist1 <= tolerance && dist2 <= tolerance )
+ {
double overlap_tolerance =
curr_facet->length() < other_facet->length() ? curr_facet->length():
other_facet->length();
@@ -1852,10 +2283,11 @@
curve1->closest_point( mid_point1, dummy_vec, NULL, &curvature1 );
curve2->closest_point( mid_point2, dummy_vec, NULL, &curvature2 );
- double rad1 = curvature1.length();
- double rad2 = curvature2.length();
+ double rad1 = 1/curvature1.length();
+ double rad2 = 1/curvature2.length();
- if( fabs( rad1 - rad2 ) > 0.001 )
+ //if( fabs( rad1 - rad2 ) > 0.001 )
+ if( fabs( rad1 - rad2 ) > tolerance )
return CUBIT_FALSE;
}
else
@@ -1868,9 +2300,10 @@
}
CubitBoolean SurfaceOverlapTool::check_overlap( RefEdge *edge1, RefEdge *edge2,
- std::map<RefEdge*, DLIList<CurveOverlapFacet*>* > *facet_map )
+ std::map<RefEdge*, DLIList<CurveOverlapFacet*>* > *facet_map,
+ double *overlap_tol )
{
- //if surfaces are not splines and are not of the same type,
+ //if edges are not splines and are not of the same type,
//they won't overlap
if( (edge1->get_curve_ptr()->geometry_type() != SPLINE_CURVE_TYPE &&
edge2->get_curve_ptr()->geometry_type() != SPLINE_CURVE_TYPE) &&
@@ -1878,7 +2311,15 @@
edge2->get_curve_ptr()->geometry_type() ))
return CUBIT_FALSE;
+ // we don't want to consider edges from the same body
+ if (edge1->body() == edge2->body())
+ return CUBIT_FALSE;
+
+
double tolerance = GeometryQueryTool::get_geometry_factor()*GEOMETRY_RESABS;
+ if( overlap_tol )
+ tolerance = *overlap_tol;
+
std::map<RefEdge*, DLIList<CurveOverlapFacet*>* >::iterator facet_iterator;
CubitBox edge_box1 = edge1->bounding_box();
@@ -2060,7 +2501,9 @@
//if curvatures are more than 10% off
double curvature_diff = fabs( rad1 - rad2 );
- if( rad1 || rad2 )
+ if( (rad1 || rad2 ) &&
+ (rad1 > GEOMETRY_RESABS || //radii must be of significance even look at
+ rad2 > GEOMETRY_RESABS ))
{
if( curvature_diff/( (fabs(rad1) + fabs(rad2))/2 ) > 0.1 )
return CUBIT_FALSE;
@@ -2074,4 +2517,3 @@
return CUBIT_TRUE;
}
-
Modified: cgm/branches/cubit/geom/SurfaceOverlapTool.hpp
===================================================================
--- cgm/branches/cubit/geom/SurfaceOverlapTool.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/SurfaceOverlapTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -17,29 +17,43 @@
template <class X> class DLIList;
class RefFace;
+//! Tool to find surfaces and curves that overlap.
class CUBIT_GEOM_EXPORT SurfaceOverlapTool
{
public :
+ //! From the specified surfaces, find surfaces that overlap.
CubitStatus find_overlapping_surfaces( DLIList<RefFace*> &ref_face_list,
- DLIList<RefEntity*> &faces_to_draw );
+ DLIList<RefEntity*> &faces_to_draw,
+ bool filter_slivers = false );
+
+ //! From the specified bodies, find surfaces that overlap.
CubitStatus find_overlapping_surfaces( DLIList<Body*> &body_list,
- DLIList<RefEntity*> &faces_to_draw );
+ DLIList<RefEntity*> &faces_to_draw,
+ bool filter_slivers = false );
+
+ //! From the specified surfaces, find surfaces that overlap.
CubitStatus find_overlapping_surfaces( DLIList<RefFace*> &ref_face_list,
DLIList<RefFace*> &ref_face_list1,
DLIList<RefFace*> &ref_face_list2,
DLIList<RefEntity*> &faces_to_draw,
- CubitBoolean show_messages = CUBIT_FALSE);
+ CubitBoolean show_messages = CUBIT_FALSE,
+ bool filter_slivers = false);
+
+ //! From the specified bodies, find surfaces that overlap.
CubitStatus find_overlapping_surfaces( DLIList<Body*> &body_list,
DLIList<RefFace*> &ref_face_list1,
DLIList<RefFace*> &ref_face_list2,
DLIList<RefEntity*> &faces_to_draw,
- CubitBoolean show_messages = CUBIT_FALSE);
+ CubitBoolean show_messages = CUBIT_FALSE,
+ bool filter_slivers = false);
+ //! From the specified bodies, find surfaces that overlap.
CubitStatus find_overlapping_surfaces( DLIList<BodySM*> &body_list,
DLIList<Surface*> &surface_list1,
- DLIList<Surface*> &surface_list2 );
+ DLIList<Surface*> &surface_list2,
+ bool filter_slivers = false );
// Searches for surfaces that overlap each other and are good
// candidates for imprinting. It can even find those with gaps
@@ -55,20 +69,78 @@
// overlap...", and groupResults, listPairs and displayPairs will be
// used, otherwise they will be false (default).
+ //! From the specified surfaces, find overlapping curves.
+ CubitStatus find_overlapping_curves( DLIList<Surface*> &surf_list,
+ DLIList< DLIList<Curve*> *> &overlapping_curve_lists,
+ std::map<Curve*, DLIList<Curve*>* > &curve_to_list_map,
+ std::multimap<BodySM*, CubitVector> &body_point_imprint_map);
+
+ //! From the specified curves, find those that overlap.
+ CubitStatus find_overlapping_curves( DLIList<Curve*> &curve_list,
+ DLIList< DLIList<Curve*> *> &overlapping_curve_lists,
+ std::map<Curve*, DLIList<Curve*>* > &curve_to_list_map,
+ std::multimap<BodySM*, CubitVector> &body_point_imprint_map);
+
+ //! From the specified bodies, find curves that overlap.
CubitStatus find_overlapping_curves( DLIList<Body*> &bodies,
- std::multimap<RefEdge*, RefEdge*> &overlapping_edge_map );
+ std::multimap<RefEdge*, RefEdge*> &overlapping_edge_map,
+ double maxgap = -1);
+
+ //! From the specified bodies, find curves that overlap.
CubitStatus find_overlapping_curves( DLIList<BodySM*> &bodies,
DLIList< DLIList<Curve*> *> &overlapping_curve_lists,
- std::map<Curve*, DLIList<Curve*>* > &curve_to_list_map );
+ std::map<Curve*, DLIList<Curve*>* > &curve_to_list_map,
+ std::multimap<BodySM*, CubitVector> &body_vertex_imprint_map);
+ //! From the specified surfaces, find curves that overlap.
+ CubitStatus find_overlapping_curves( DLIList<RefFace*> &faces,
+ std::multimap<RefEdge*,
+ RefEdge*> &overlapping_edge_map,
+ double maxgap = -1);
+
+
+ //! From the specified curves, find curves that overlap.
+ CubitStatus find_overlapping_curves( DLIList<RefEdge*> &edgelist,
+ std::multimap<RefEdge*, RefEdge*> &overlapping_edge_map,
+ double maxgap = -1);
+
+ //! From the specified curves, find curves that overlap.
+ CubitStatus find_overlapping_curves( DLIList<RefEdge*> &edges1, DLIList<RefEdge*> &edges2,
+ std::multimap<RefEdge*, RefEdge*> &overlapping_edge_map,
+ double maxgap = -1);
+
+ //! Checks to see if two curves overlap. Reuses graphic facets.
CubitBoolean check_overlap( RefEdge *edge1, RefEdge *edge2,
- std::map<RefEdge*, DLIList<CurveOverlapFacet*>* > *facet_map );
+ std::map<RefEdge*, DLIList<CurveOverlapFacet*>* > *facet_map,
+ double *overlap_tol = NULL );
+ //! Checks to see if two surfaces overlap.
+ CubitBoolean check_overlap( RefFace *ref_face_ptr1,
+ RefFace *ref_face_ptr2,
+ CubitBoolean abort,
+ CubitBoolean draw_overlap = CUBIT_FALSE,
+ double *overlap_area = NULL );
+
+ //! Checks to see if two curves overlap. Reuses graphic facets.
CubitBoolean check_overlap( Curve *curve1, Curve *curve2,
- std::map<Curve*, DLIList<CurveOverlapFacet*>* > *facet_map );
+ std::map<Curve*, DLIList<CurveOverlapFacet*>* > *facet_map,
+ std::multimap<BodySM*, CubitVector > *body_point_imprint_map = NULL );
+ //! Checks to see the two groups of facets overlap.
+ CubitBoolean check_overlap( DLIList<SurfaceOverlapFacet*> *facet_list1,
+ DLIList<SurfaceOverlapFacet*> *facet_list2,
+ AbstractTree<SurfaceOverlapFacet*> *a_tree,
+ CubitBoolean abort,
+ CubitBoolean draw_overlap,
+ double *overlap_area );
+
+ //! Draws the overlapping surface pair.
+ CubitBoolean draw_overlapping_surface_pair( RefFace *ref_face_1,
+ RefFace *ref_face_2);
+
+
+ //! List the settings used for surface overlap detection
void list_settings();
- // List the settings used for surface overlap detection
unsigned short get_facet_ang_tol();
void set_facet_ang_tol( unsigned short angle_tol );
@@ -130,7 +202,8 @@
static CubitBoolean get_check_across_bodies();
static void set_check_across_bodies( CubitBoolean setting );
-
+ CubitBoolean get_skip_facing_surfaces();
+ void set_skip_facing_surfaces( CubitBoolean setting );
static SurfaceOverlapTool* instance();
// Returns a static pointer to unique instance of this class.
@@ -141,19 +214,18 @@
private :
+
CubitStatus find_overlapping_surfaces( DLIList<RefFace*> &ref_face_list,
DLIList<RefFace*> &ref_face_list1,
DLIList<RefFace*> &ref_face_list2,
DLIList<RefEntity*> &pair_list,
CubitBoolean list_pairs,
- int prog_step );
+ int prog_step,
+ bool filter_slivers = false);
// Private workhorse function for finding the overlapping surfaces. Here
// pair_list is a list of all the surfaces that were found that overlap.
// If prog_step == -1 it does not step the progress bar.
- CubitBoolean check_overlap( RefFace *ref_face_ptr1,
- RefFace *ref_face_ptr2,
- CubitBoolean abort );
CubitBoolean check_overlap( Surface *surface1,
Surface *surface2,
std::map<Surface*, DLIList<SurfaceOverlapFacet*>* > *facet_map,
@@ -189,19 +261,65 @@
SurfaceOverlapTool();
//- Constructor for the SurfaceOverlapTool object
+ /*! The angular tolerance indicates the maximum angle between
+ normals of adjacent surface facets. The default angular
+ tolerance is 15° - consider using a value of 5° . This will
+ generate a more accurate facetted representation of the
+ geometry for overlap detection. */
+ static unsigned short facetAngTol;
+
+ /*! The distance tolerance means the maximum actual distance
+ between the generated facets and the surface. This value is
+ by default ignored by the facetter - consider specifying a
+ reasonable value here for more accurate results */
static double facetAbsTol;
- static unsigned short facetAngTol;
+
+ /*! The overlap algorithm will search for surfaces that are
+ within a distance from the gapMin to gapMax. */
static double gapMin;
static double gapMax;
+
+ //@{
+ /*! Angle comparison for determining if facets are coplanar. If
+ they are within angleMin and angleMax they are considered to be
+ coplanar. */
static double angleMin;
static double angleMax;
+ //@}
+
+ //! Searches for overlapping surface that have surface normals
+ //! in any, opposite, or the same direction.
static int normalType; // 1=any, 2=opposite, 3=same
+
+ //! Controls if surfaces are put in a group or not.
static CubitBoolean groupResults;
+
+ //! Prints out the lists of overlapping surface pairs.
static CubitBoolean listPairs;
+
+ //! Draws the lists of overlapping surface pairs.
static CubitBoolean displayPairs;
+
+ //! Imprint overlapping surfaces parts onto one another.
static CubitBoolean imprintResults;
+
+ //! The area threshold that 2 surfaces have to actually overlap.
+ //! Prevents detection of sliver overlaps.
static double overlapTolerance;
+
+ //! if the normalType is 2 skip surfaces that face each other
+ static CubitBoolean skipFacingSurfaces;
+
+ //! By default this tool will not search for overlapping
+ //! pairs within bodies - only between different bodies.
+ //! Turn this setting on to search for pairs within bodies.
+ //! Note however that this will slow the algorithm down.
static CubitBoolean checkWithinBodies;
+
+ //! If true, by default, will try to find surfaces of body A
+ //! that overlap surfaces of body B. Setting this flag to
+ //! false will make the tool only check for surfaces that
+ //! overlap in the same body.
static CubitBoolean checkAcrossBodies;
};
@@ -251,38 +369,30 @@
void SurfaceOverlapTool::set_overlap_tolerance( double val )
{overlapTolerance=val;}
-#ifdef CAT
inline
int SurfaceOverlapTool::get_normal_type()
{return normalType;}
-#endif
inline
void SurfaceOverlapTool::set_normal_type( int type )
{normalType=type;}
-#ifdef CAT
inline
CubitBoolean SurfaceOverlapTool::get_group_results()
{return groupResults;}
-#endif
inline
void SurfaceOverlapTool::set_group_results( CubitBoolean setting )
{groupResults=setting;}
-#ifdef CAT
inline
CubitBoolean SurfaceOverlapTool::get_list_pairs()
{return listPairs;}
-#endif
inline
void SurfaceOverlapTool::set_list_pairs( CubitBoolean setting )
{listPairs=setting;}
-#ifdef CAT
inline
CubitBoolean SurfaceOverlapTool::get_display_pairs()
{return displayPairs;}
-#endif
inline
void SurfaceOverlapTool::set_display_pairs( CubitBoolean setting )
{displayPairs=setting;}
@@ -304,7 +414,12 @@
inline
void SurfaceOverlapTool::set_check_across_bodies( CubitBoolean setting )
{checkAcrossBodies=setting;}
-
+inline
+CubitBoolean SurfaceOverlapTool::get_skip_facing_surfaces()
+{return skipFacingSurfaces;}
+inline
+void SurfaceOverlapTool::set_skip_facing_surfaces( CubitBoolean setting )
+{skipFacingSurfaces=setting;}
#endif
Modified: cgm/branches/cubit/geom/TDSplitSurface.cpp
===================================================================
--- cgm/branches/cubit/geom/TDSplitSurface.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/TDSplitSurface.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -877,3 +877,17 @@
return CUBIT_SUCCESS;
}
+
+//================================================================================
+// Description: This class holds data on vertices for split across extend
+// Author : Steve Storm
+// Date : 10/7/2007
+//================================================================================
+TDSplitSurfaceExtend::TDSplitSurfaceExtend()
+{
+ successFlg = CUBIT_FALSE;
+}
+
+TDSplitSurfaceExtend::~TDSplitSurfaceExtend()
+{
+}
Modified: cgm/branches/cubit/geom/TDSplitSurface.hpp
===================================================================
--- cgm/branches/cubit/geom/TDSplitSurface.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/TDSplitSurface.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -413,4 +413,41 @@
inline CubitBoolean TDSplitSurface::is_d_collapsed()
{ return sideD->is_collapsed(); }
+
+//================================================================================
+// Description: This class holds data on vertices for split across extend
+// Author : Steve Storm
+// Date : 10/7/2007
+//================================================================================
+class CUBIT_GEOM_EXPORT TDSplitSurfaceExtend : public ToolData
+{
+public:
+
+ TDSplitSurfaceExtend();
+ //- Constructor
+
+ ~TDSplitSurfaceExtend();
+ //- Destructor
+
+ void set_success();
+ //- This indicates we successfully extended from this vertex
+
+ CubitBoolean is_success();
+ //- Did we successfully extend from this vertex?
+
+ static int is_split_surface_extend(const ToolData* td)
+ {return (CAST_TO(td, const TDSplitSurfaceExtend) != NULL);}
+
+private:
+
+ CubitBoolean successFlg;
+};
+
+inline void
+TDSplitSurfaceExtend::set_success()
+{ successFlg = CUBIT_TRUE; }
+
+inline CubitBoolean
+TDSplitSurfaceExtend::is_success()
+{ return successFlg; }
#endif // TD_SPLIT_SURFACE_HPP
Modified: cgm/branches/cubit/geom/TDUniqueId.cpp
===================================================================
--- cgm/branches/cubit/geom/TDUniqueId.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/TDUniqueId.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -86,23 +86,19 @@
//- it is a match, erase it by iterator. This will leave the other entry with
//- the similar key in the list, which is necessary for save/restore, and remove the
//- deactivated geometry due to the merge.
- int map_count = unique_id_list().count(uniqueId);
- if( map_count == 1 )
- unique_id_list().erase(uniqueId);
- else if( map_count > 1 )
- {
- std::pair<TDUIDList::iterator, TDUIDList::iterator>
- bounds_pair = unique_id_list().equal_range(uniqueId);
- TDUIDList::iterator
- it = bounds_pair.first, upper = bounds_pair.second;
-
- while( (*it).second != this && it != upper )
- it++;
-
- if( it != upper )
- unique_id_list().erase( it );
- }
+ std::pair<TDUIDList::iterator, TDUIDList::iterator>
+ bounds_pair = unique_id_list().equal_range(uniqueId);
+
+ TDUIDList::iterator it;
+ for(it = bounds_pair.first; it != bounds_pair.second; ++it)
+ {
+ if(it->second == this)
+ {
+ unique_id_list().erase( it );
+ break;
+ }
+ }
}
int TDUniqueId::get_unique_id(ToolDataUser *owner,
@@ -133,7 +129,6 @@
return 0;
if ((*it).first == temp_id) {
-
// the lower bound key is equal to temp_id, so this id is in the list
// look for duplicate id's, return one that's directly related
@@ -191,16 +186,29 @@
void TDUniqueId::clear_copy_map()
{
//remove TDs off of entities
-
COPYUIDMap::iterator iter = mapForCopying.begin();
for(; iter != mapForCopying.end(); iter++ )
{
- ToolDataUser *td_user = find_td_unique_id( (*iter).second );
+ DLIList<ToolDataUser*> tool_data_users;
+ int num_tool_datas = find_td_unique_id( (*iter).second, tool_data_users );
+
+ for( ; num_tool_datas--; )
+ {
+ ToolDataUser *td_user = tool_data_users.get_and_step();
+
//make sure the pointer isn't null
- if(td_user)
- td_user->remove_TD(TDUniqueId::is_unique_id);
- }
+ ToolData *tool_data = NULL;
+ if(td_user)
+ tool_data = td_user->remove_TD(TDUniqueId::is_unique_id);
+
+ //delete the TDUniqueId as well
+ if( tool_data )
+ delete tool_data;
+ td_user = find_td_unique_id( (*iter).second );
+ }
+ }
+
//clear out the map
if (mapForCopying.empty()) return;
mapForCopying.erase(mapForCopying.begin(), mapForCopying.end());
Modified: cgm/branches/cubit/geom/TopologyBridge.cpp
===================================================================
--- cgm/branches/cubit/geom/TopologyBridge.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/TopologyBridge.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -291,6 +291,91 @@
}
}
+void TopologyBridge::curves_ignore_virtual( DLIList<Curve*>& curves, bool unique )
+{
+ int i;
+ if(dynamic_cast<BodySM*>(this))
+ {
+ DLIList<TopologyBridge*> lumps;
+ this->get_children_virt(lumps);
+ for(i=lumps.size(); i>0; i--)
+ lumps.get_and_step()->curves_ignore_virtual(curves, unique);
+ }
+ else if(dynamic_cast<Lump*>(this))
+ {
+ DLIList<TopologyBridge*> shells;
+ this->get_children_virt(shells);
+ for(i=shells.size(); i>0; i--)
+ shells.get_and_step()->curves_ignore_virtual(curves, unique);
+ }
+ else if(dynamic_cast<ShellSM*>(this))
+ {
+ DLIList<TopologyBridge*> surfs;
+ this->get_children_virt(surfs);
+ for(i=surfs.size(); i>0; i--)
+ surfs.get_and_step()->curves_ignore_virtual(curves, unique);
+ }
+ else if(dynamic_cast<Surface*>(this))
+ {
+ DLIList<TopologyBridge*> loops;
+ this->get_children_virt(loops);
+ for(i=loops.size(); i>0; i--)
+ loops.get_and_step()->curves_ignore_virtual(curves, unique);
+ }
+ else if(dynamic_cast<LoopSM*>(this))
+ {
+ DLIList<TopologyBridge*> coedges;
+ this->get_children_virt(coedges);
+ for(i=coedges.size(); i>0; i--)
+ coedges.get_and_step()->curves_ignore_virtual(curves, unique);
+ }
+ else if(dynamic_cast<CoEdgeSM*>(this))
+ {
+ DLIList<TopologyBridge*> tmp_curves;
+ this->get_children_virt(tmp_curves);
+ for(i=tmp_curves.size(); i>0; i--)
+ tmp_curves.get_and_step()->curves_ignore_virtual(curves, unique);
+ }
+ else if(dynamic_cast<Curve*>(this))
+ {
+ curves.append(dynamic_cast<Curve*>(this));
+ }
+ if(unique)
+ curves.uniquify_ordered();
+}
+
+void TopologyBridge::surfaces_ignore_virtual( DLIList<Surface*>& surfaces, bool unique )
+{
+ int i;
+ if(dynamic_cast<BodySM*>(this))
+ {
+ DLIList<TopologyBridge*> lumps;
+ this->get_children_virt(lumps);
+ for(i=lumps.size(); i>0; i--)
+ lumps.get_and_step()->surfaces_ignore_virtual(surfaces, unique);
+ }
+ else if(dynamic_cast<Lump*>(this))
+ {
+ DLIList<TopologyBridge*> shells;
+ this->get_children_virt(shells);
+ for(i=shells.size(); i>0; i--)
+ shells.get_and_step()->surfaces_ignore_virtual(surfaces, unique);
+ }
+ else if(dynamic_cast<ShellSM*>(this))
+ {
+ DLIList<TopologyBridge*> surfs;
+ this->get_children_virt(surfs);
+ for(i=surfs.size(); i>0; i--)
+ surfs.get_and_step()->surfaces_ignore_virtual(surfaces, unique);
+ }
+ else if(dynamic_cast<Surface*>(this))
+ {
+ surfaces.append(dynamic_cast<Surface*>(this));
+ }
+ if(unique)
+ surfaces.uniquify_ordered();
+}
+
void TopologyBridge::curves( DLIList<Curve*>& curves, bool unique )
{
DLIList<TopologyBridge*> related;
Modified: cgm/branches/cubit/geom/TopologyBridge.hpp
===================================================================
--- cgm/branches/cubit/geom/TopologyBridge.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/TopologyBridge.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -194,8 +194,10 @@
void lumps(DLIList<Lump*> &lumps,bool unique = true);
void shellsms(DLIList<ShellSM*> &shellsms,bool unique = true);
void surfaces(DLIList<Surface*> &surfaces,bool unique = true);
+ void surfaces_ignore_virtual(DLIList<Surface*> &surfaces,bool unique = true);
void loopsms(DLIList<LoopSM*> &loopsms,bool unique = true);
- void curves(DLIList<Curve*> &curves,bool unique = true);
+ void curves(DLIList<Curve*> &curves, bool unique = true);
+ void curves_ignore_virtual(DLIList<Curve*> &curves, bool unique = true);
void coedgesms(DLIList<CoEdgeSM*> &coedgesms,bool unique = true);
void points(DLIList<Point*> &points,bool unique = true);
//- topology traversal of TB's; implemented based on native traversal
Modified: cgm/branches/cubit/geom/facet/FacetCurve.cpp
===================================================================
--- cgm/branches/cubit/geom/facet/FacetCurve.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/facet/FacetCurve.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -238,12 +238,17 @@
//-------------------------------------------------------------------------
double FacetCurve::length_from_u( double parameter1, double parameter2 )
{
- if( periodic )
- {
- adjust_periodic_parameter( parameter1 );
- adjust_periodic_parameter( parameter2 );
- }
- return curveFacetEvalTool->length_from_u( parameter1, parameter2 );
+
+ //Don't perform the periodic adjustment so that
+ // this function will satisfy the properties of
+ // the function as defined in RefEdge.hpp.
+ // Also, take the fabs of the arc length for the same reason.
+ //if( periodic )
+ //{
+ // adjust_periodic_parameter( parameter1 );
+ // adjust_periodic_parameter( parameter2 );
+ //}
+ return fabs(curveFacetEvalTool->length_from_u( parameter1, parameter2 ));
}
//-------------------------------------------------------------------------
Modified: cgm/branches/cubit/geom/facet/FacetLoop.cpp
===================================================================
--- cgm/branches/cubit/geom/facet/FacetLoop.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/facet/FacetLoop.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -66,6 +66,27 @@
}
//-------------------------------------------------------------------------
+// Purpose : The purpose of this function is to see if a loop is an external
+// or internal loop of a surface.
+//
+// Special Notes :
+//
+// Creator : Jonathan Bugman
+//
+// Creation Date : 9/9/2008
+//-------------------------------------------------------------------------
+CubitBoolean FacetLoop::is_external()
+{
+ PRINT_ERROR( "This command is not supported with this engine.\n");
+ return CUBIT_FAILURE;
+}
+
+LoopType FacetLoop::loop_type()
+{
+ return LOOP_TYPE_UNKNOWN;
+}
+
+//-------------------------------------------------------------------------
// Purpose : The purpose of this function is to append a
// attribute to the GE. The name is attached to the
// underlying solid model entity this one points to.
Modified: cgm/branches/cubit/geom/facet/FacetLoop.hpp
===================================================================
--- cgm/branches/cubit/geom/facet/FacetLoop.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/facet/FacetLoop.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -45,6 +45,14 @@
virtual ~FacetLoop() ;
//- The destructor
+ virtual CubitBoolean is_external() ;
+ //R CubitBoolean
+ //R- CUBIT_TRUE/CUBIT_FALSE
+ //- Returns CUBIT_TRUE if the Loop is an external Loop and CUBIT_FALSE
+ //- otherwise.
+
+ virtual LoopType loop_type() ;
+
virtual void append_simple_attribute_virt(CubitSimpleAttrib*);
//R void
//I
Modified: cgm/branches/cubit/geom/facet/FacetModifyEngine.cpp
===================================================================
--- cgm/branches/cubit/geom/facet/FacetModifyEngine.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/facet/FacetModifyEngine.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -70,24 +70,24 @@
// do nothing in some very rare cases. From Steven Engelhardt's Weblog.
#define MODIFY_CHECK_RETURN_NULL \
-do {if(!modifyEnabled){ \
+do {if(!modifyEnabled){ \
PRINT_INFO("Facet-based geometry modification is a beta capability.\n");\
PRINT_ERROR("This capability is currently disabled.\n");\
- PRINT_INFO("To enable this capability, issue the command 'set facet_modify on'. \n");\
+ PRINT_INFO("To enable this capability, issue the command 'set developer commands on'. \n");\
return NULL;} }while(0)
#define MODIFY_CHECK_RETURN_VOID \
do {if(!modifyEnabled){ \
PRINT_INFO("Facet-based geometry modification is a beta capability.\n");\
PRINT_ERROR("This capability is currently disabled.\n");\
- PRINT_INFO("To enable this capability, issue the command 'set facet_modify on'. \n");\
+ PRINT_INFO("To enable this capability, issue the command 'set developer commands on'. \n");\
return;} }while(0)
#define MODIFY_CHECK_RETURN_FAILURE \
do {if(!modifyEnabled){ \
PRINT_INFO("Facet-based geometry modification is a beta capability.\n");\
PRINT_ERROR("This capability is currently disabled.\n");\
- PRINT_INFO("To enable this capability, issue the command 'set facet_modify on'. \n");\
+ PRINT_INFO("To enable this capability, issue the command 'set developer commands on'. \n");\
return CUBIT_FAILURE;} }while(0)
//===============================================================================
// Function : FacetModifyEngine
@@ -170,6 +170,20 @@
//===============================================================================
// Function : make_Curve
// Member Type: PUBLIC
+// Description: make a curve using point_tangents to describe curvature
+// Author : John Fowler
+// Date : 10/02
+//===============================================================================
+Curve* FacetModifyEngine::make_Curve( DLIList<CubitVector*>& point_list,
+ DLIList<CubitVector*>& point_tangents) const
+{
+ PRINT_ERROR("Option not supported for mesh based geometry.\n");
+ return (Curve*)NULL;
+}
+
+//===============================================================================
+// Function : make_Curve
+// Member Type: PUBLIC
// Description: make a curve
// Author : John Fowler
// Date : 10/02
@@ -216,6 +230,21 @@
}
//===============================================================================
+// Function : make_extended_sheet
+// Member Type: PUBLIC
+// Description: make an extended sheet from a set of surfaces
+// Author :
+// Date :
+//===============================================================================
+BodySM* FacetModifyEngine::make_extended_sheet( DLIList<Surface*> & /*surface_list*/,
+ CubitBox * /*clip_box_ptr*/,
+ bool /*preview*/ ) const
+{
+ PRINT_ERROR("Option not supported for mesh based geometry.\n");
+ return (BodySM*) NULL;
+}
+
+//===============================================================================
// Function : make_Surface
// Member Type: PUBLIC
// Description: make a surface
@@ -609,6 +638,17 @@
return body_ptr;
}
+CubitStatus FacetModifyEngine::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
+{
+ PRINT_INFO("This functionality is not implemented for faceted geometry.\n");
+ return CUBIT_FAILURE;
+}
+
void FacetModifyEngine::set_sphere_eval_data
(
ChollaEngine *cholla_ptr,
@@ -896,15 +936,182 @@
// Function : brick
// Member Type: PUBLIC
// Description: create a brick with facets given center axes and extension
-// Author : John Fowler
-// Date : 10/02
+// Author : Steve Owen
+// Date : 1/09
//===============================================================================
-BodySM* FacetModifyEngine::brick( const CubitVector &/*center*/,
- const CubitVector* /*axes[3]*/,
- const CubitVector &/*extension*/) const
+BodySM* FacetModifyEngine::brick( const CubitVector ¢er,
+ const CubitVector axes[3],
+ const CubitVector &extension) const
{
- PRINT_ERROR("Option not supported for mesh based geometry.\n");
- return (BodySM*) NULL;
+
+
+ MODIFY_CHECK_RETURN_NULL;
+ CubitStatus rv = CUBIT_SUCCESS;
+ CubitVector uvec, vvec, wvec, corner, mid;
+ DLIList <CubitFacet *>facet_list;
+ DLIList <CubitPoint *>point_list;
+ CubitPoint *new_point;
+ CubitFacet *facet_ptr;
+ int i, numpoints, numtris;
+ double feature_angle;
+ int interp_order;
+ CubitBoolean smooth_non_manifold, split_surfaces;
+ BodySM *body_ptr = NULL;
+ std::vector<CubitPoint *> points;
+
+ numpoints = 14;
+ numtris = 24;
+
+ uvec = extension.x() * axes[0];
+ vvec = extension.y() * axes[1];
+ wvec = extension.z() * axes[2];
+
+ corner = center - uvec - vvec - wvec;
+ new_point = (CubitPoint *) new CubitPointData( corner.x(),corner.y(),corner.z() );
+ points.push_back(new_point);
+
+ corner = center + uvec - vvec - wvec;
+ new_point = (CubitPoint *) new CubitPointData( corner.x(),corner.y(),corner.z() );
+ points.push_back(new_point);
+
+ corner = center + uvec - vvec + wvec;
+ new_point = (CubitPoint *) new CubitPointData( corner.x(),corner.y(),corner.z() );
+ points.push_back(new_point);
+
+ corner = center - uvec - vvec + wvec;
+ new_point = (CubitPoint *) new CubitPointData( corner.x(),corner.y(),corner.z() );
+ points.push_back(new_point);
+
+ corner = center - uvec + vvec - wvec;
+ new_point = (CubitPoint *) new CubitPointData( corner.x(),corner.y(),corner.z() );
+ points.push_back(new_point);
+
+ corner = center + uvec + vvec - wvec;
+ new_point = (CubitPoint *) new CubitPointData( corner.x(),corner.y(),corner.z() );
+ points.push_back(new_point);
+
+ corner = center + uvec + vvec + wvec;
+ new_point = (CubitPoint *) new CubitPointData( corner.x(),corner.y(),corner.z() );
+ points.push_back(new_point);
+
+ corner = center - uvec + vvec + wvec;
+ new_point = (CubitPoint *) new CubitPointData( corner.x(),corner.y(),corner.z() );
+ points.push_back(new_point);
+
+ mid = center - wvec;
+ new_point = (CubitPoint *) new CubitPointData( mid.x(), mid.y(), mid.z() );
+ points.push_back(new_point);
+
+ mid = center + uvec;
+ new_point = (CubitPoint *) new CubitPointData( mid.x(), mid.y(), mid.z() );
+ points.push_back(new_point);
+
+ mid = center + wvec;
+ new_point = (CubitPoint *) new CubitPointData( mid.x(), mid.y(), mid.z() );
+ points.push_back(new_point);
+
+ mid = center - uvec;
+ new_point = (CubitPoint *) new CubitPointData( mid.x(), mid.y(), mid.z() );
+ points.push_back(new_point);
+
+ mid = center - vvec;
+ new_point = (CubitPoint *) new CubitPointData( mid.x(), mid.y(), mid.z() );
+ points.push_back(new_point);
+
+ mid = center + vvec;
+ new_point = (CubitPoint *) new CubitPointData( mid.x(), mid.y(), mid.z() );
+ points.push_back(new_point);
+
+ for ( i = 0; i < numpoints; i++ ) {
+ point_list.append(points[i]);
+ }
+
+ // bottom face
+ facet_ptr = new CubitFacetData( points[0],points[1], points[12] );
+ facet_list.append( facet_ptr );
+ facet_ptr = new CubitFacetData( points[1],points[2], points[12] );
+ facet_list.append( facet_ptr );
+ facet_ptr = new CubitFacetData( points[2],points[3], points[12] );
+ facet_list.append( facet_ptr );
+ facet_ptr = new CubitFacetData( points[3],points[0], points[12] );
+ // back face
+ facet_list.append( facet_ptr );
+ facet_ptr = new CubitFacetData( points[1],points[0], points[8] );
+ facet_list.append( facet_ptr );
+ facet_ptr = new CubitFacetData( points[5],points[1], points[8] );
+ facet_list.append( facet_ptr );
+ facet_ptr = new CubitFacetData( points[4],points[5], points[8] );
+ facet_list.append( facet_ptr );
+ facet_ptr = new CubitFacetData( points[0],points[4], points[8] );
+ facet_list.append( facet_ptr );
+ // left face
+ facet_ptr = new CubitFacetData( points[0],points[3], points[11] );
+ facet_list.append( facet_ptr );
+ facet_ptr = new CubitFacetData( points[3],points[7], points[11] );
+ facet_list.append( facet_ptr );
+ facet_ptr = new CubitFacetData( points[7],points[4], points[11] );
+ facet_list.append( facet_ptr );
+ facet_ptr = new CubitFacetData( points[4],points[0], points[11] );
+ facet_list.append( facet_ptr );
+ // top face
+ facet_ptr = new CubitFacetData( points[7],points[6], points[13] );
+ facet_list.append( facet_ptr );
+ facet_ptr = new CubitFacetData( points[6],points[5], points[13] );
+ facet_list.append( facet_ptr );
+ facet_ptr = new CubitFacetData( points[5],points[4], points[13] );
+ facet_list.append( facet_ptr );
+ facet_ptr = new CubitFacetData( points[4],points[7], points[13] );
+ facet_list.append( facet_ptr );
+ // right face
+ facet_ptr = new CubitFacetData( points[1],points[5], points[9] );
+ facet_list.append( facet_ptr );
+ facet_ptr = new CubitFacetData( points[5],points[6], points[9] );
+ facet_list.append( facet_ptr );
+ facet_ptr = new CubitFacetData( points[6],points[2], points[9] );
+ facet_list.append( facet_ptr );
+ facet_ptr = new CubitFacetData( points[2],points[1], points[9] );
+ facet_list.append( facet_ptr );
+ // front face
+ facet_ptr = new CubitFacetData( points[3],points[2], points[10] );
+ facet_list.append( facet_ptr );
+ facet_ptr = new CubitFacetData( points[2],points[6], points[10] );
+ facet_list.append( facet_ptr );
+ facet_ptr = new CubitFacetData( points[6],points[7], points[10] );
+ facet_list.append( facet_ptr );
+ facet_ptr = new CubitFacetData( points[7],points[3], points[10] );
+ facet_list.append( facet_ptr );
+
+ points.clear(); // clear out the points vector since we are through with it.
+
+ feature_angle = 100.0;
+ interp_order = 0;
+ smooth_non_manifold = CUBIT_TRUE;
+ split_surfaces = CUBIT_FALSE;
+
+ ChollaEngine *cholla_ptr = NULL;
+ FacetModifyEngine *fme = const_cast<FacetModifyEngine *> (this);
+ rv = fme->build_cholla_surfaces( facet_list,
+ point_list,
+ feature_angle,
+ interp_order,
+ smooth_non_manifold,
+ split_surfaces,
+ cholla_ptr );
+ if ( rv == CUBIT_SUCCESS )
+ {
+ finish_facet_Body( cholla_ptr,
+ NULL,
+ feature_angle,
+ interp_order,
+ body_ptr);
+ if ( cholla_ptr )
+ {
+ cholla_ptr->delete_me();
+ delete cholla_ptr;
+ }
+
+ }
+ return body_ptr;
}
//===============================================================================
@@ -1322,7 +1529,8 @@
status = fbint->dofacetboolean_subtract(tool_body,from_bodies,new_bodies,
keep_old,to_be_deleted,op);
delete fbint;
- FacetQueryEngine::instance()->delete_solid_model_entities(tool_body);
+ if( keep_old == false )
+ FacetQueryEngine::instance()->delete_solid_model_entities(tool_body);
}
for ( i = 0; i < from_bodies.size(); i++ ) {
@@ -1435,6 +1643,7 @@
CubitStatus FacetModifyEngine::imprint( DLIList<BodySM*> &body_list,
DLIList<Curve*> &ref_edge_list,
DLIList<BodySM*>& new_body_list,
+ DLIList<TopologyBridge*> &temporary_bridges,
bool keep_old,
bool show_messages) const
{
@@ -1483,6 +1692,7 @@
//===============================================================================
CubitStatus FacetModifyEngine::imprint( DLIList<Surface*> &/*ref_face_list*/,
DLIList<Curve*> &/*ref_edge_list*/,
+ DLIList<TopologyBridge*> &temporary_bridges,
DLIList<BodySM*>& /*new_body_list*/,
bool /*keep_old_body*/ ) const
{
@@ -1500,7 +1710,10 @@
CubitStatus FacetModifyEngine::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
{
PRINT_ERROR("Option not supported for mesh based geometry.\n");
return CUBIT_FAILURE;
@@ -1518,7 +1731,9 @@
DLIList<BodySM*>& /*new_body_list*/,
bool keep_old, /* keep old body */
DLIList<TopologyBridge*> *new_tbs,
- DLIList<TopologyBridge*> *att_tbs ) const
+ DLIList<TopologyBridge*> *att_tbs,
+ double *tol_in,
+ bool clean_up_slivers) const
{
PRINT_ERROR("Option not supported for mesh based geometry.\n");
return CUBIT_FAILURE;
@@ -1575,7 +1790,6 @@
return CUBIT_FAILURE;
}
-
//===============================================================================
// Function : intersect
// Member Type: PUBLIC
@@ -1695,6 +1909,11 @@
}
+void FacetModifyEngine::get_possible_invalid_tbs(DLIList<TopologyBridge*> &bridges_in,
+ DLIList<TopologyBridge*> &bridges_out)
+{
+}
+
//===============================================================================
// Function : unite
// Member Type: PUBLIC
@@ -1844,6 +2063,25 @@
return CUBIT_FAILURE;
}
+CubitStatus FacetModifyEngine::sweep_to_body( DLIList<Curve*> curve_list,
+ BodySM *target_body,
+ CubitVector distance,
+ DLIList<BodySM*> &new_bodies,
+ bool unite ) const
+{
+ PRINT_ERROR("Option not supported for mesh based geometry.\n");
+ return CUBIT_FAILURE;
+}
+
+CubitStatus FacetModifyEngine::sweep_to_body( Surface *source_surface,
+ BodySM *target_body,
+ CubitVector distance,
+ DLIList<BodySM*> &new_bodies ) const
+{
+ PRINT_ERROR("Option not supported for mesh based geometry.\n");
+ return CUBIT_FAILURE;
+}
+
//HEADER- Webcut-related functions
//===============================================================================
@@ -1857,8 +2095,10 @@
const CubitVector &v1,
const CubitVector &v2,
const CubitVector &v3,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*>& results_list,
- bool imprint ) const
+ ImprintType imprint_type,
+ bool /*preview*/) const
{
MODIFY_CHECK_RETURN_FAILURE;
@@ -1980,8 +2220,10 @@
//===============================================================================
CubitStatus FacetModifyEngine::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
{
PRINT_ERROR("Option not supported for mesh based geometry.\n");
return CUBIT_FAILURE;
@@ -1997,8 +2239,10 @@
CubitStatus FacetModifyEngine::webcut_across_translate( DLIList<BodySM*>& /*body_list*/,
Surface* /*plane_surf1*/,
Surface* /*plane_surf2*/,
+ DLIList<BodySM*>& /*neighbor_imprint_list*/,
DLIList<BodySM*>& /*results_list*/,
- bool /*imprint*/ ) const
+ ImprintType imprint_type,
+ bool /*preview*/) const
{
PRINT_ERROR("Option not supported for mesh based geometry.\n");
return CUBIT_FAILURE;
@@ -2013,8 +2257,10 @@
//===============================================================================
CubitStatus FacetModifyEngine::webcut_with_sheet(DLIList<BodySM*> & /*webcut_body_list*/,
BodySM * /*sheet_body*/,
+ DLIList<BodySM*>& /*neighbor_imprint_list*/,
DLIList<BodySM*> & /*new_bodies*/,
- bool /*imprint*/ )
+ ImprintType imprint_type,
+ bool /*preview*/)
{
PRINT_ERROR("Option not supported for mesh based geometry.\n");
return CUBIT_FAILURE;
@@ -2027,11 +2273,13 @@
// Author : John Fowler
// Date : 10/02
//===============================================================================
-CubitStatus FacetModifyEngine::webcut_with_extended_surf(DLIList<BodySM*> & /*webcut_body_list*/,
- Surface * /*extend_from*/,
+CubitStatus FacetModifyEngine::webcut_with_extended_sheet(DLIList<BodySM*> & /*webcut_body_list*/,
+ DLIList<Surface*> & /*surface_list*/,
+ DLIList<BodySM*>& /*neighbor_imprint_list*/,
DLIList<BodySM*> & /*new_bodies*/,
int & /*num_cut*/,
- bool /*imprint*/ )
+ ImprintType imprint_type,
+ bool /*preview*/)
{
PRINT_ERROR("Option not supported for mesh based geometry.\n");
return CUBIT_FAILURE;
@@ -2048,8 +2296,10 @@
double radius,
const CubitVector &axis,
const CubitVector ¢er,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*>& results_list,
- bool imprint )
+ ImprintType imprint_type,
+ bool /*preview*/ )
{
MODIFY_CHECK_RETURN_FAILURE;
@@ -2136,8 +2386,10 @@
const CubitVector &/*center*/,
const CubitVector* /*axes[3]*/,
const CubitVector &/*extension*/,
+ DLIList<BodySM*> &/*neighbor_imprint_list*/,
DLIList<BodySM*> &/*results_list*/,
- bool /*imprint*/ )
+ ImprintType imprint_type,
+ bool /*preview*/)
{
PRINT_ERROR("Option not supported for mesh based geometry.\n");
return CUBIT_FAILURE;
@@ -2156,8 +2408,10 @@
const CubitVector* /*axes[2]*/,
double /*width*/,
double /*height*/,
+ DLIList<BodySM*> &/*neighbor_imprint_list*/,
DLIList<BodySM*> &/*results_list*/,
- bool /*imprint*/ )
+ ImprintType imprint_type,
+ bool /*preview*/)
{
PRINT_ERROR("Option not supported for mesh based geometry.\n");
return CUBIT_FAILURE;
@@ -2173,8 +2427,10 @@
CubitStatus FacetModifyEngine::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*/)
+ ImprintType imprint_type,
+ bool /*preview*/)
{
PRINT_ERROR("Option not supported for mesh based geometry.\n");
return CUBIT_FAILURE;
@@ -2244,6 +2500,21 @@
return CUBIT_SUCCESS;
}
+//===============================================================================
+// Function : separate_surfaces
+// Member Type: PUBLIC
+// Description: Separates surfaces from sheet bodies into separate bodies.
+// Connected surfaces will remain connected but be placed in a new
+// body. NOT IMPLEMENTED
+// Author :
+// Date :
+//===============================================================================
+CubitStatus FacetModifyEngine::separate_surfaces( DLIList<Surface*> &surf_list,
+ DLIList<BodySM*> &new_bodies )
+{
+ PRINT_ERROR("Option not supported for mesh based geometry.\n");
+ return CUBIT_FAILURE;
+}
//===============================================================================
// Function : reverse_body
@@ -2310,12 +2581,18 @@
// Date : 10/02
//===============================================================================
CubitStatus FacetModifyEngine::regularize_entity( GeometryEntity * /*old_entity_ptr*/,
- BodySM *& /*new_body_ptr*/ )
+ BodySM *& /*new_body_ptr*/)
{
PRINT_ERROR("Option not supported for mesh based geometry.\n");
return CUBIT_FAILURE;
}
+CubitStatus FacetModifyEngine::test_regularize_entity( GeometryEntity *)
+{
+ PRINT_ERROR("Option not supported for mesh based geometry.\n");
+ return CUBIT_FAILURE;
+}
+
//===============================================================================
// Function : offset_curves
// Member Type: PUBLIC
@@ -2334,6 +2611,21 @@
}
//===============================================================================
+// Function : split_curve
+// Member Type: PUBLIC
+// Description:
+// Author : Alex Hays
+// Date : 9/08
+//===============================================================================
+CubitStatus FacetModifyEngine::split_curve( Curve* curve_to_split,
+ const CubitVector& split_location,
+ DLIList<Curve*>& created_curves )
+{
+ PRINT_ERROR("Option not supported for mesh based geometry.\n");
+ return CUBIT_FAILURE;
+}
+
+//===============================================================================
// Function : trim_curve
// Member Type: PUBLIC
// Description:
@@ -2350,16 +2642,17 @@
}
//===============================================================================
-// Function : create_body_from_surfs
+// Function : create_solid_bodies_from_surfs
// Member Type: PUBLIC
// Description:
// Author : Steve Owen
// Date : 9/11/03
//===============================================================================
-CubitStatus FacetModifyEngine::create_body_from_surfs(DLIList<Surface*> & ref_face_list,
- BodySM *& new_body,
+CubitStatus FacetModifyEngine::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
{
//MODIFY_CHECK_RETURN_FAILURE;
@@ -2427,10 +2720,24 @@
surface_list,
file_format );
+ BodySM *new_body = NULL;
if (rv == CUBIT_SUCCESS)
{
surf_ptr = surface_list.get();
new_body = surf_ptr->bodysm();
+
+ if( sheet == false )
+ {
+ CubitVector centroid;
+ double volume = 0.0;
+ new_body->mass_properties( centroid, volume);
+ if( volume <= 0.0 )
+ {
+ FacetQueryEngine::instance()->delete_solid_model_entities(new_body);
+ PRINT_INFO("Failing...Resulting body has no volume.\n");
+ return CUBIT_FAILURE;
+ }
+ }
// delete the old model
@@ -2460,6 +2767,9 @@
new_body = NULL;
}
+ if( new_body )
+ new_bodies.append( new_body );
+
return CUBIT_SUCCESS;
}
@@ -2665,6 +2975,31 @@
}
//=============================================================================
+// Function : tweak_bend
+// Member Type: PUBLIC
+// Description: Bend solid bodies based on a bend radius and angle
+// Author :
+// Date :
+//=============================================================================
+CubitStatus FacetModifyEngine::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
+{
+ PRINT_ERROR("Option not supported for mesh based geometry.\n");
+ return CUBIT_FAILURE;
+}
+
+//=============================================================================
// Function : tweak_chamfer
// Member Type: PUBLIC
// Description: Chamfer curves on solid bodies. The left and right offsets are
@@ -2813,6 +3148,8 @@
//=============================================================================
CubitStatus FacetModifyEngine::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
@@ -2831,6 +3168,8 @@
//=============================================================================
CubitStatus FacetModifyEngine::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
@@ -2850,7 +3189,6 @@
CubitStatus FacetModifyEngine::tweak_remove( DLIList<Surface*> & /*surface_list*/,
DLIList<BodySM*> & /*new_bodysm_list*/,
CubitBoolean /*extend_adjoining*/,
- CubitBoolean /*keep_surface*/,
CubitBoolean /*keep_old_body*/,
CubitBoolean /*preview*/ ) const
{
@@ -2886,6 +3224,8 @@
CubitStatus FacetModifyEngine::tweak_target( DLIList<Surface*> & /*surface_list*/,
DLIList<Surface*> & /*target_surf_list*/,
DLIList<BodySM*> & /*new_bodysm_list*/,
+ CubitBoolean /*extend_flg*/,
+ CubitPlane * /*limit_plane*/,
CubitBoolean /*reverse_flg*/,
CubitBoolean /*keep_old_body*/,
CubitBoolean /*preview*/ ) const
@@ -2905,9 +3245,12 @@
CubitStatus FacetModifyEngine::tweak_target( DLIList<Curve*> & /*curve_list*/,
DLIList<Surface*> & /*target_surf_list*/,
DLIList<BodySM*> & /*new_bodysm_list*/,
+ CubitBoolean /*extend_flg*/,
+ CubitPlane * /*limit_plane*/,
CubitBoolean /*reverse_flg*/,
CubitBoolean /*keep_old_body*/,
- CubitBoolean /*preview*/ ) const
+ CubitBoolean /*preview*/,
+ double /*max_area_increase = 0*/ ) const
{
PRINT_ERROR("Option not supported for mesh based geometry.\n");
return CUBIT_FAILURE;
@@ -2925,16 +3268,41 @@
//=============================================================================
CubitStatus FacetModifyEngine::tweak_target( DLIList<Curve*> & /*curve_list*/,
DLIList<Curve*> & /*target_curve_list*/,
- DLIList<BodySM*> & /*new_bodysm_list*/,
+ DLIList<BodySM*> & /*new_bodysm_list*/,
+ CubitBoolean /*extend_flg*/,
+ CubitPlane * /*limit_plane*/,
CubitBoolean /*reverse_flg*/,
CubitBoolean /*keep_old_body*/,
+ CubitBoolean /*preview*/,
+ double /*max_area_increase = 0*/ ) const
+{
+ PRINT_ERROR("Option not supported for mesh based geometry.\n");
+ return CUBIT_FAILURE;
+}
+
+//=============================================================================
+// 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 :
+// Date :
+//=============================================================================
+CubitStatus FacetModifyEngine::tweak_target( Point * /*point_ptr*/,
+ DLIList<Surface*> & /*modify_surface_list*/,
+ CubitVector & /*target_loc*/,
+ BodySM *& /*new_bodysm_ptr*/,
+ CubitBoolean /*keep_old_body*/,
CubitBoolean /*preview*/ ) const
{
PRINT_ERROR("Option not supported for mesh based geometry.\n");
return CUBIT_FAILURE;
}
-
CubitStatus FacetModifyEngine::remove_curve_slivers( BodySM* /*body*/,
double /*lengthlimit*/ ) const
{
@@ -2982,11 +3350,28 @@
BodySM*& /*new_body*/,
double /*offset_distance*/ ) const
{
- PRINT_ERROR("Function not implemented in this engine.\n");
+ PRINT_ERROR("Function not implemented in Facet engine.\n");
return CUBIT_FAILURE;
}
//================================================================================
+// Description: Creates an offset sheet.
+// Author :
+// Date :
+//================================================================================
+CubitStatus
+FacetModifyEngine::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
+{
+ PRINT_ERROR("Function not implemented in Facet engine.\n");
+ return CUBIT_FAILURE;
+}
+
+//================================================================================
// Description: Creates an offset body.
// Author : Tyronne Lim
// Date : 08/18/03
@@ -3005,7 +3390,8 @@
// Date : 08/18/03
//================================================================================
CubitStatus FacetModifyEngine::create_skin_surface( DLIList<Curve*>& /*curves*/,
- BodySM*& /*new_body*/ ) const
+ BodySM*& /*new_body*/,
+ DLIList<Curve*>& /*guides*/) const
{
PRINT_ERROR("Function not implemented in this engine.\n");
return CUBIT_FAILURE;
@@ -3065,6 +3451,13 @@
return CUBIT_FAILURE;
}
+CubitStatus FacetModifyEngine::create_surface( DLIList<Point*> & /*points*/,
+ BodySM *& /*new_body*/ ) const
+{
+ PRINT_ERROR("Function not implemented in this engine.\n");
+ return CUBIT_FAILURE;
+}
+
//================================================================================
// Description: Creates a weld surface.
// Author : Tyronne Lim
@@ -3081,6 +3474,17 @@
return CUBIT_FAILURE;
}
+
+CubitStatus FacetModifyEngine::stitch( DLIList<BodySM*> &bodies_to_stitch,
+ DLIList<BodySM*> &new_bodies,
+ bool tighten_gaps,
+ double tolerance )const
+{
+ PRINT_ERROR("Function not implemented in this engine.\n");
+ return CUBIT_FAILURE;
+}
+
+
//================================================================================
// Facet-based geometry entities
// Methods for building specific facet-based geometry entities
@@ -3624,6 +4028,7 @@
rv = cholla_ptr->create_geometry( use_feature_angle, feature_angle,
interp_order, smooth_non_manifold,
split_surfaces );
+
}
return rv;
}
@@ -3811,6 +4216,8 @@
ChollaPoint *fpm1_ptr = fpoint_list.get_and_step();
CubitPoint *start_point, *end_point;
chcurv_ptr->get_ends( start_point, end_point );
+ assert(start_point != NULL);
+ assert(end_point != NULL);
if (fpm0_ptr->get_facets() != start_point)
{
ChollaPoint *temp_ptr;
@@ -4803,8 +5210,10 @@
bool up_to_next,
Surface *stop_surf,
Curve *curve_to_sweep_along,
+ DLIList<BodySM*> &/*neighbor_imprint_list*/,
DLIList<BodySM*> &results_list,
- CubitBoolean imprint)
+ ImprintType imprint_type,
+ bool /*preview*/)
{
PRINT_ERROR("Option not supported for mesh based geometry.\n");
return CUBIT_FAILURE;
@@ -4817,8 +5226,10 @@
bool through_all,
Surface *stop_surf,
Curve *curve_to_sweep_along,
+ DLIList<BodySM*> &/*neighbor_imprint_list*/,
DLIList<BodySM*> &results_list,
- CubitBoolean imprint)
+ ImprintType imprint_type,
+ bool /*preview*/)
{
PRINT_ERROR("Option not supported for mesh based geometry.\n");
return CUBIT_FAILURE;
@@ -4832,8 +5243,10 @@
double angle,
Surface *stop_surf,
bool up_to_next,
+ DLIList<BodySM*> &/*neighbor_imprint_list*/,
DLIList<BodySM*> &results_list,
- CubitBoolean imprint)
+ ImprintType imprint_type,
+ bool /*preview*/)
{
PRINT_ERROR("Option not supported for mesh based geometry.\n");
return CUBIT_FAILURE;
@@ -4846,8 +5259,10 @@
const CubitVector &sweep_axis,
double angle,
Surface *stop_surf,
+ DLIList<BodySM*> &/*neighbor_imprint_list*/,
DLIList<BodySM*> &results_list,
- CubitBoolean imprint)
+ ImprintType imprint_type,
+ bool /*preview*/)
{
PRINT_ERROR("Option not supported for mesh based geometry.\n");
return CUBIT_FAILURE;
@@ -4867,4 +5282,32 @@
return CUBIT_FAILURE;
}
+CubitStatus FacetModifyEngine::tolerant_imprint( DLIList<Surface*> &surfs_in,
+ DLIList<BodySM*> &new_bodysm_list) const
+{
+ PRINT_ERROR("Option not supported for mesh based geometry.\n");
+ return CUBIT_FAILURE;
+}
+
+CubitStatus FacetModifyEngine::tolerant_imprint_surface_with_curves(
+ Surface * /*surface_to_imprint*/,
+ DLIList<Curve*> & /*curves*/,
+ DLIList<TopologyBridge*> &temporary_bridges,
+ BodySM *& /*new_body*/,
+ DLIList<TopologyBridge*> *new_tbs,
+ DLIList<TopologyBridge*> *att_tbs) const
+{
+ PRINT_ERROR("Option not supported for mesh based geometry.\n");
+ return CUBIT_FAILURE;
+}
+
+CubitStatus FacetModifyEngine::curve_surface_intersection( Surface * /*surface*/,
+ Curve* /*curve*/,
+ DLIList<Curve*> &/*new_curves*/ ) const
+{
+ PRINT_ERROR("Option not supported for mesh based geometry.\n");
+ return CUBIT_FAILURE;
+}
+
+
// EOF
Modified: cgm/branches/cubit/geom/facet/FacetModifyEngine.hpp
===================================================================
--- cgm/branches/cubit/geom/facet/FacetModifyEngine.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/facet/FacetModifyEngine.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -68,6 +68,10 @@
virtual ~FacetModifyEngine();
//- virtual destructor
+ virtual bool supports_interoperability() { return false; }
+ //- Returns whether intermixing of real and virtual geometry operations
+ //- is supported for the current geometry kernel.
+
virtual Point* make_Point( CubitVector const& point) const ;
virtual Curve* make_Curve(Curve *curve_ptr) const;
@@ -93,10 +97,17 @@
Point const* point2_ptr,
CubitVector const* intermediate_point_ptr,
CubitSense sense) const;
+
+ virtual Curve* make_Curve( DLIList<CubitVector*>& point_list,
+ DLIList<CubitVector*>& point_tangents) const;
virtual Surface* make_Surface( Surface *old_surface_ptr,
CubitBoolean extended_from = CUBIT_FALSE) const;
+
+ virtual BodySM* make_extended_sheet( DLIList<Surface*> &surface_list,
+ CubitBox *clip_box = NULL,
+ bool preview = false ) const;
virtual Surface* make_Surface( GeometryType surface_type,
DLIList<Curve*>& curve_list,
@@ -157,25 +168,32 @@
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=CUBIT_TRUE) const;
virtual CubitStatus imprint( DLIList<Surface*> &ref_face_list,
DLIList<Curve*> &ref_edge_list,
+ DLIList<TopologyBridge*> &temporary_bridges,
DLIList<BodySM*>& new_body_list,
bool keep_old_body ) const;
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;
virtual CubitStatus imprint( DLIList<BodySM*> &body_list,
DLIList<CubitVector*> &vector_list,
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;
virtual CubitStatus imprint_projected_edges( DLIList<Surface*> &ref_face_list,
DLIList<Curve*> &ref_edge_list,
@@ -194,7 +212,18 @@
DLIList<Curve*> &ref_edge_list_in,
DLIList<Curve*> &ref_edge_list_new,
bool print_error = true ) const;
-
+
+ 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 curve_surface_intersection( Surface *surface,
+ Curve* curve,
+ DLIList<Curve*> &new_curves ) const;
+
virtual CubitStatus intersect(BodySM* tool_body_ptr,
DLIList<BodySM*> &from_bodies,
DLIList<BodySM*> &new_bodies,
@@ -209,7 +238,10 @@
virtual CubitStatus unite(DLIList<BodySM*> &bodies,
DLIList<BodySM*> &newBodies,
- bool keep_old = CUBIT_FALSE) const;
+ bool keep_old = CUBIT_FALSE) const;
+
+ virtual void get_possible_invalid_tbs(DLIList<TopologyBridge*> &bridges_in,
+ DLIList<TopologyBridge*> &bridges_out);
virtual CubitStatus thicken(DLIList<BodySM*>& bodies,
DLIList<BodySM*>& new_bodies,
@@ -256,6 +288,19 @@
double draft_angle = 0.0,
int draft_type = 0,
bool rigid = CUBIT_FALSE ) 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;
virtual CubitStatus webcut_with_sweep_surfaces(
@@ -268,8 +313,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);
virtual CubitStatus webcut_with_sweep_curves(
DLIList<BodySM*> &blank_bodies,
@@ -278,8 +325,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);
virtual CubitStatus webcut_with_sweep_curves_rotated(
DLIList<BodySM*> &blank_bodies,
@@ -288,8 +337,10 @@
const CubitVector &sweep_axis,
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);
virtual CubitStatus webcut_with_sweep_surfaces_rotated(
DLIList<BodySM*> &blank_bodies,
@@ -299,65 +350,84 @@
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);
//HEADER- Webcut-related functions
virtual CubitStatus webcut(DLIList<BodySM*>& webcut_body_list,
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;
virtual CubitStatus webcut(DLIList<BodySM*>& webcut_body_list,
BodySM const* tool_body,
+ DLIList<BodySM*>& neighbor_imprint_list,
DLIList<BodySM*>& results_list,
- bool imprint = false ) const;
+ ImprintType imprint_type = NO_IMPRINT,
+ bool preview = false) const;
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;
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);
- virtual CubitStatus webcut_with_extended_surf(DLIList<BodySM*> &webcut_body_list,
- Surface *extend_from,
+ virtual CubitStatus webcut_with_extended_sheet(DLIList<BodySM*> &webcut_body_list,
+ 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);
virtual CubitStatus webcut_with_cylinder(DLIList<BodySM*> &webcut_body_list,
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,
+ bool preview = false);
virtual CubitStatus webcut_with_brick( DLIList<BodySM*>& webcut_body_list,
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,
+ bool preview = false);
virtual CubitStatus webcut_with_planar_sheet( DLIList<BodySM*>& webcut_body_list,
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);
virtual CubitStatus webcut_with_curve_loop(DLIList<BodySM*> &webcut_body_list,
DLIList<Curve*> &ref_edge_list,
DLIList<BodySM*>& results_list,
- bool imprint = false );
+ DLIList<BodySM*>& neighbor_imprint_list,
+ ImprintType imprint_type = NO_IMPRINT,
+ bool preview = false);
virtual CubitStatus section( DLIList<BodySM*> §ion_body_list,
const CubitVector &point_1,
@@ -370,6 +440,9 @@
virtual CubitStatus split_body( BodySM *body_ptr,
DLIList<BodySM*> &new_bodies );
+
+ virtual CubitStatus separate_surfaces( DLIList<Surface*> &surf_list,
+ DLIList<BodySM*> &new_bodies );
virtual CubitStatus reverse_body( BodySM *body_to_reverse );
@@ -381,6 +454,7 @@
virtual CubitStatus regularize_entity(GeometryEntity *old_entity_ptr,
BodySM *&new_body_ptr);
+ virtual CubitStatus test_regularize_entity( GeometryEntity *old_refentity_ptr);
virtual CubitStatus offset_curves( DLIList<Curve*>& ref_edge_list,
DLIList<Curve*>& result_curve_list,
@@ -390,15 +464,20 @@
virtual CubitStatus scale ( BodySM *&body, const CubitVector& factors );
+ virtual CubitStatus split_curve( Curve* curve_to_split,
+ const CubitVector& split_location,
+ DLIList<Curve*>& created_curves );
+
virtual Curve* trim_curve( Curve* trim_curve,
const CubitVector& trim_vector,
const CubitVector& keep_vector,
bool keep_old = false );
- virtual CubitStatus create_body_from_surfs(DLIList<Surface*> &ref_face_list,
- BodySM *&new_body,
- bool keep_old = false,
- bool heal = false) const;
+ virtual CubitStatus create_solid_bodies_from_surfs(DLIList<Surface*> &ref_face_list,
+ DLIList<BodySM*> &new_bodies,
+ bool keep_old = false,
+ bool heal = true,
+ bool sheet = false ) const;
virtual Curve* create_arc_three( Point* ref_vertex1,
Point* ref_vertex2,
@@ -468,6 +547,22 @@
BodySM *body_to_trim_to,
BodySM *&midsurface_body ) const;
+ 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 ) 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,
@@ -540,26 +635,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
@@ -578,6 +676,8 @@
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;
@@ -587,9 +687,12 @@
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 surface_area_increase_allowed = 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.
@@ -598,13 +701,30 @@
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 surface_area_increase_allowed = 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.
*/
+
+ 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, double lengthlimit ) const;
@@ -621,9 +741,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,
@@ -646,12 +781,21 @@
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*> &points,
+ BodySM *&new_body ) const;
+
virtual CubitStatus create_weld_surface( CubitVector &root,
Surface *ref_face1, double leg1, Surface *ref_face2, double leg2,
BodySM *&new_body ) const;
+ virtual CubitStatus stitch( DLIList<BodySM*> &bodies_to_stitch,
+ DLIList<BodySM*> &new_bodies,
+ bool tighten_gaps,
+ double tolerance )const;
+
+
//--------------------------------------------------------------
//- Methods for building specific facet-based geometry entities
//--------------------------------------------------------------
@@ -814,6 +958,15 @@
// From the facet surface list, create geometric surface,
// loops and coedges for each surface in the list
+ virtual CubitStatus tolerant_imprint(DLIList<Surface*> &surfs_in,
+ DLIList<BodySM*> &new_bodysm_list) const;
+ 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;
+
CubitStatus tolerant_imprint( DLIList<BodySM*> &bodies_in,
DLIList<BodySM*> &new_bodies,
DLIList<TopologyBridge*> *new_tbs = NULL,
Modified: cgm/branches/cubit/geom/facet/FacetParamTool.cpp
===================================================================
--- cgm/branches/cubit/geom/facet/FacetParamTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/facet/FacetParamTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -191,7 +191,7 @@
// Author: chynes
// Date: 7/10/02
//===================================================================================
-CubitStatus FacetParamTool::transform_to_uv(CubitVector &xyz_location, CubitVector &uv_location)
+CubitStatus FacetParamTool::transform_to_uv(const CubitVector &xyz_location, CubitVector &uv_location)
{
DLIList<CubitFacet *> facet_list;
FacetEvalTool *fetool;
@@ -252,7 +252,7 @@
// Author: chynes
// Date: 7/10/02
//===================================================================================
-CubitStatus FacetParamTool::transform_to_xyz(CubitVector &xyz_location, CubitVector &uv_location)
+CubitStatus FacetParamTool::transform_to_xyz(CubitVector &xyz_location, const CubitVector &uv_location)
{
CubitStatus rv = CUBIT_SUCCESS;
CubitFacet *tri_ptr;
@@ -328,7 +328,7 @@
// Date: 7/10/02
//===================================================================================
CubitStatus FacetParamTool::
-locate_point_in_uv(FacetSurface *surf, CubitVector &the_point, CubitFacet *&tri_ptr)
+locate_point_in_uv(FacetSurface *surf, const CubitVector &the_point, CubitFacet *&tri_ptr)
{
CubitStatus rv = CUBIT_SUCCESS;
@@ -392,7 +392,7 @@
// Date: 7/10/02
//===================================================================================
CubitStatus FacetParamTool::
-exhaustive_locate_point_in_uv(FacetSurface *surf, CubitVector &the_point, CubitFacet *&tri_ptr)
+exhaustive_locate_point_in_uv(FacetSurface *surf, const CubitVector &the_point, CubitFacet *&tri_ptr)
{
CubitStatus rv = CUBIT_SUCCESS;
Modified: cgm/branches/cubit/geom/facet/FacetParamTool.hpp
===================================================================
--- cgm/branches/cubit/geom/facet/FacetParamTool.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/facet/FacetParamTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -32,13 +32,13 @@
CubitStatus set_up_space(void);
- CubitStatus transform_to_uv(CubitVector &xyz_location, CubitVector &uv_location);
+ CubitStatus transform_to_uv(const CubitVector &xyz_location, CubitVector &uv_location);
- CubitStatus transform_to_xyz(CubitVector &xyz_location, CubitVector &uv_location);
+ CubitStatus transform_to_xyz(CubitVector &xyz_location, const CubitVector &uv_location);
- CubitStatus locate_point_in_uv(FacetSurface *surf, CubitVector &the_point, CubitFacet *&tri_ptr);
+ CubitStatus locate_point_in_uv(FacetSurface *surf, const CubitVector &the_point, CubitFacet *&tri_ptr);
- CubitStatus exhaustive_locate_point_in_uv(FacetSurface *surf, CubitVector &the_point, CubitFacet *&tri_ptr);
+ CubitStatus exhaustive_locate_point_in_uv(FacetSurface *surf, const CubitVector &the_point, CubitFacet *&tri_ptr);
#ifdef BOYD14
CubitStatus export_facets(int numn, int numf, double *points, int *facets);
Modified: cgm/branches/cubit/geom/facet/FacetQueryEngine.cpp
===================================================================
--- cgm/branches/cubit/geom/facet/FacetQueryEngine.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/facet/FacetQueryEngine.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -414,13 +414,13 @@
// Date :
//================================================================================
CubitStatus FacetQueryEngine::get_graphics( Surface* surface_ptr,
- int& number_triangles,
- int& number_points,
- int& number_facets,
GMem* gMem,
unsigned short ,
double, double ) const
{
+ if( !gMem )
+ return CUBIT_FAILURE;
+
// get the FacetSurface.
int i;
FacetSurface *facet_surf_ptr = CAST_TO(surface_ptr,FacetSurface);
@@ -434,16 +434,13 @@
// set return values, and if GMem is NULL return
// (caller just wanted to know the counts.)
- number_facets = surface_facets.size() * 4;
- number_points = surface_points.size();
- number_triangles = surface_facets.size();
- if( !gMem )
- return CUBIT_SUCCESS;
+ int number_points = surface_points.size();
+ int number_triangles = surface_facets.size();
// Allocate space in GMem
- gMem->allocate_tri(surface_facets.size());
- gMem->fListCount = number_facets;
+ gMem->allocate_tri(number_triangles);
+ gMem->fListCount = surface_facets.size() * 4;
gMem->pointListCount = number_points;
// Copy points to GMem
@@ -483,7 +480,6 @@
// Date :
//================================================================================
CubitStatus FacetQueryEngine::get_graphics( Curve* curve_ptr,
- int& num_points,
GMem* gMem,
double /*tolerance*/ ) const
{
@@ -497,12 +493,14 @@
facet_curv_ptr->get_points(curve_points);
curve_points.reset();
curve_facets.reset();
- num_points = curve_points.size();
+ int num_points = curve_points.size();
GPoint *new_point_list = new GPoint[num_points];
int *new_facet_list = new int [number_facets*3];
int ii;
+ CubitPoint *cur_pnt;
for ( ii = 0; ii < num_points; ii++ )
{
+ cur_pnt = curve_points.get();
new_point_list[ii].x = curve_points.get()->x();
new_point_list[ii].y = curve_points.get()->y();
new_point_list[ii].z = curve_points.get()->z();
@@ -1748,7 +1746,7 @@
CubitBoolean free_surfaces)
{
errno = 0;
- FILE *file_ptr = fopen(file_name, "r");
+ FILE *file_ptr = fopen(file_name, "rb");
if (!file_ptr)
{
PRINT_ERROR("Cannot open file: %s (%s)\n", file_name, strerror(errno) );
@@ -2296,18 +2294,169 @@
return CUBIT_SUCCESS;
}
-CubitStatus FacetQueryEngine::fire_ray(BodySM *,
- const CubitVector &,
- const CubitVector &,
- DLIList<double>&,
- DLIList<GeometryEntity*> *) const
+CubitStatus FacetQueryEngine::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
{
- PRINT_ERROR("FacetQueryEngine::fire_ray not yet implemented.\n");
- return CUBIT_FAILURE;
+
+ TopologyBridge *bridge_ptr;
+ int i, j;
+ bool hit = false;
+
+ DLIList<double> tmp_ray_params;
+ DLIList<FacetSurface*> at_surface_list;
+ DLIList<FacetCurve*> at_curve_list;
+ DLIList<FacetPoint*> at_point_list;
+
+ if( ray_radius == 0.0 )
+ ray_radius = get_sme_resabs_tolerance();
+
+ at_entity_list.reset();
+ for (i=0; i<at_entity_list.size(); i++)
+ {
+ hit = false;
+ bridge_ptr = at_entity_list.get_and_step();
+
+ //determine which type of geometry we have. body, lump, face, curve?
+ if (CAST_TO(bridge_ptr, FacetBody))
+ {
+ FacetBody* f_body = CAST_TO(bridge_ptr, FacetBody);
+ DLIList<Surface*> surface_list;
+ f_body->surfaces(surface_list);
+ }
+ else if (CAST_TO(bridge_ptr, FacetLump))
+ {
+ FacetLump* f_lump = CAST_TO(bridge_ptr, FacetLump);
+ PRINT_INFO("Found FacetLump.\n");
+ DLIList<FacetSurface*> f_surface_list;
+ f_lump->get_surfaces(f_surface_list);
+ at_surface_list.merge_unique(f_surface_list);
+ }
+ else if (CAST_TO(bridge_ptr, Surface))
+ {
+ FacetSurface* f_surface = CAST_TO(bridge_ptr, FacetSurface);
+
+ DLIList<CubitFacet*> facet_list;
+ DLIList<CubitPoint*> point_list;
+ f_surface->get_my_facets(facet_list, point_list);
+
+ //PRINT_INFO("There are %d facets.\n", facet_list.size());
+
+ //RTree<CubitFacet*> rtree(ray_radius);
+ //for (j=0; j<facet_list.size(); j++)
+ // rtree.add(facet_list.get_and_step();
+
+ //DLIList<CubitFacet*> facet_list1;
+ //CubitBox range_box();
+ //make range box for the ray
+ //rtree.find(range_box, facet_list1);
+
+ CubitVector* intersection_pt = new CubitVector();
+ double distance;
+
+ for (j=0; j<facet_list.size(); j++)
+ {
+ if (hit)
+ break;
+
+ CubitFacet* facet = facet_list.get_and_step();
+
+ // Find intersection of ray with triangle
+ int rv = FacetEvalTool::intersect_ray(origin, direction, facet, intersection_pt, distance);
+
+ switch (rv)
+ {
+ case -1:
+ //PRINT_INFO("Facet is degenerate (segment or point).\n");
+ break;
+ case 0:
+ //PRINT_INFO("Ray does not intersect the facet.\n");
+ break;
+ case 1:
+ {
+ hit = true;
+ if (hit_entity_list)
+ hit_entity_list->append(bridge_ptr);
+ ray_params.append(distance);
+ //PRINT_INFO("Ray intersects facet at %f, %f, %f.\n", intersection_pt->x(), intersection_pt->y(), intersection_pt->z());
+
+ continue;
+ }
+ case 2:
+ //PRINT_INFO("Ray is in same plane as the facet.\n");
+ break;
+ }
+ }
+ if (intersection_pt)
+ delete intersection_pt;
+
+ }
+ else if (CAST_TO(bridge_ptr, Curve))
+ {
+ FacetCurve* f_curve = CAST_TO(bridge_ptr, FacetCurve);
+ DLIList<CubitFacetEdge*> facet_edge_list;
+ f_curve->get_facets(facet_edge_list);
+
+ //PRINT_INFO("There are %d facetedges.\n", facet_edge_list.size());
+ CubitVector* intersection_pt = new CubitVector();
+ double distance;
+
+ for (j=0; j<facet_edge_list.size(); j++)
+ {
+ if (hit)
+ break;
+
+ CubitFacetEdge* facet_edge = facet_edge_list.get_and_step();
+
+ int rv = FacetEvalTool::intersect_ray(origin, direction, facet_edge, intersection_pt, distance);
+
+ switch (rv)
+ {
+ case -1:
+ //PRINT_INFO("Facet is degenerate (segment or point).\n");
+ break;
+ case 0:
+ //PRINT_INFO("Ray does not intersect the facet edge.\n");
+ break;
+ case 1:
+ {
+ hit = true;
+ if (hit_entity_list)
+ hit_entity_list->append(bridge_ptr);
+ ray_params.append(distance);
+ //PRINT_INFO("Ray intersects facet at %f, %f, %f.\n", intersection_pt->x(), intersection_pt->y(), intersection_pt->z());
+
+ continue;
+ }
+ case 2:
+ //PRINT_INFO("Ray is parallel to the facet.\n");
+ break;
+ }
+
+ }
+ if (intersection_pt)
+ delete intersection_pt;
+ }
+ else if (CAST_TO(bridge_ptr, FacetPoint))
+ {
+ FacetPoint* f_point = CAST_TO(bridge_ptr, FacetPoint);
+ at_point_list.append_unique(f_point);
+ }
+ else
+ ;//PRINT_INFO("Cast error in FacetQueryEngine::fire_ray.\n");
+
+ }
+
+ return CUBIT_SUCCESS;
}
- //- fire a ray at the specified body, returning the entities hit and
- //- the parameters along the ray; return CUBIT_FAILURE if error
+ //- fire a ray at the specified entities, returning the parameters
+ //- (distances) along the ray and optionally the entities hit
+
double FacetQueryEngine::get_sme_resabs_tolerance() const
{
PRINT_ERROR("FacetQueryEngine::get_sme_resabs_tolerance not yet implemented.\n");
@@ -2456,7 +2605,10 @@
unsigned int dummy_int=0;
- while (isspace(line[dummy_int])&& dummy_int<strlen(line)) dummy_int++;
+ // One of the functions called by isspace() has an assert that can fail in debug mode if
+ // line[dummy_int] is negative so check for it here.
+ while (line[dummy_int] > -1 && isspace(line[dummy_int]) && dummy_int < strlen(line))
+ dummy_int++;
if (strlen(line)-dummy_int>5)
{
@@ -3266,7 +3418,10 @@
DLIList <Surface *> shell_surfaces;
DLIList <CubitPoint *> mypoint_list;
facet_list_ptr = shell_facet_list.get_and_step();
- rv = FacetModifyEngine::instance()->build_facet_surface( NULL,
+ if(facet_list_ptr == NULL)
+ rv = CUBIT_FAILURE;
+ else
+ rv = FacetModifyEngine::instance()->build_facet_surface( NULL,
*facet_list_ptr, mypoint_list,
feature_angle, interp_order,
smooth_non_manifold,
@@ -3389,13 +3544,30 @@
return CUBIT_FAILURE;
}
- int n = sscanf(line, "%d %d", &npoints, &nfacets);
- if (n < 1 || n > 2 && file_format == CUBIT_FACET_FILE )
+ int n;
+ char type_header[8];
+ CubitBoolean is_off_file = CUBIT_FALSE;
+ n = sscanf( line, "%s", type_header );
+ if( !strcmp( type_header, "OFF" ) ||
+ !strcmp( type_header, "off" ) )
{
- PRINT_ERROR("Format error in facet file %s on line %d\n", file_name, iline);
- fclose( fp );
- return CUBIT_FAILURE;
+ PRINT_INFO( "Reading OFF file...\n" );
+ fgets(line, 128, fp);
+ iline++;
+ is_off_file = CUBIT_TRUE;
}
+
+ n = sscanf(line, "%d %d", &npoints, &nfacets);
+ if( !is_off_file )
+ {
+ if (n < 1 || n > 2 && file_format == CUBIT_FACET_FILE )
+ {
+ PRINT_ERROR("Format error in facet file %s on line %d\n", file_name, iline);
+ fclose( fp );
+ return CUBIT_FAILURE;
+ }
+ }
+
if (npoints <= 0)
{
PRINT_ERROR("Expecting number of nodes in facet file %s on line %d\n", file_name, iline);
@@ -3434,15 +3606,30 @@
fclose( fp );
return CUBIT_FAILURE;
}
-
- n = sscanf(line, "%d %lf %lf %lf", &id, &xx, &yy, &zz );
- if (n != 4)
+ if( is_off_file )
{
- PRINT_ERROR("Format error in facet file %s on line %d\n", file_name, iline);
- PRINT_INFO(" Expecting 1 integer and 3 doubles, but instead read %d values\n", n);
- fclose( fp );
- return CUBIT_FAILURE;
+ n = sscanf( line, "%lf %lf %lf", &xx, &yy, &zz );
+ id = ii;
+ if (n != 3)
+ {
+ PRINT_ERROR("Format error in OFF file %s on line %d\n", file_name, iline);
+ PRINT_INFO(" Expecting 3 doubles, but instead read %d values\n", n);
+ fclose( fp );
+ return CUBIT_FAILURE;
+ }
}
+ else
+ {
+ n = sscanf(line, "%d %lf %lf %lf", &id, &xx, &yy, &zz );
+ if (n != 4)
+ {
+ PRINT_ERROR("Format error in facet file %s on line %d\n", file_name, iline);
+ PRINT_INFO(" Expecting 1 integer and 3 doubles, but instead read %d values\n", n);
+ fclose( fp );
+ return CUBIT_FAILURE;
+ }
+ }
+
new_point = (CubitPoint *) new CubitPointData( xx, yy, zz );
new_point->set_id( id );
add_hash_point( new_point );
@@ -3523,28 +3710,56 @@
}
else
{
- n = sscanf(line, "%d %d %d %d %d", &id, &conn[4*ii], &conn[4*ii+1],
- &conn[4*ii+2], &conn[4*ii+3] );
+// if( is_off_file )
+// {
+// n = sscanf( line, "%d %d %d %d", &id, &conn[4*ii], &conn[4*ii+1],
+// &conn[4*ii+2], &conn[4*ii+3] );
+// if (n < 4 || n > 5)
+// {
+// PRINT_ERROR("Format error in OFF file %s on line %d reading facets\n", file_name, iline);
+// PRINT_INFO(" Expecting 4 or 5 integers, but instead read %d values\n", n);
+// PRINT_INFO(" For example: <facet_size> <i0> <i1> <i2> [<i3>]\n");
+// fclose( fp );
+// return CUBIT_FAILURE;
+// }
- if (n < 4 || n > 5)
- {
- PRINT_ERROR("Format error in facet file %s on line %d reading facets\n", file_name, iline);
- PRINT_INFO(" Expecting 4 or 5 integers, but instead read %d values\n", n);
- PRINT_INFO(" For example: <id> <i0> <i1> <i2> [<i3>]\n");
- fclose( fp );
- return CUBIT_FAILURE;
- }
-
- // for triangles -- duplicate the point
- if (n==4)
- {
- conn[4*ii+3] = conn[4*ii+2];
- ntri++;
- }
- else
- {
- nquad++;
- }
+// // for triangles -- duplicate the point
+// // if( n==3 )
+// if( id==3 )
+// {
+// conn[4*ii+3] = conn[4*ii+2];
+// ntri++;
+// }
+// else
+// {
+// nquad++;
+// }
+// }
+// else
+// {
+ n = sscanf(line, "%d %d %d %d %d", &id, &conn[4*ii], &conn[4*ii+1],
+ &conn[4*ii+2], &conn[4*ii+3] );
+
+ if (n < 4 || n > 5)
+ {
+ PRINT_ERROR("Format error in facet file %s on line %d reading facets\n", file_name, iline);
+ PRINT_INFO(" Expecting 4 or 5 integers, but instead read %d values\n", n);
+ PRINT_INFO(" For example: <id> <i0> <i1> <i2> [<i3>]\n");
+ fclose( fp );
+ return CUBIT_FAILURE;
+ }
+
+ // for triangles -- duplicate the point
+ if (n==4)
+ {
+ conn[4*ii+3] = conn[4*ii+2];
+ ntri++;
+ }
+ else
+ {
+ nquad++;
+ }
+// }
}
}
@@ -4756,6 +4971,9 @@
return CUBIT_FAILURE;
}
+
+
+
//===============================================================================
// Function : bodies_overlap
// Member Type: PUBLIC
@@ -4788,4 +5006,11 @@
*/
}
+CubitBoolean FacetQueryEngine::volumes_overlap (Lump * /*lump_ptr_1*/,
+ Lump * /*lump_ptr_2*/ ) const
+{
+ PRINT_ERROR("Currently, Cubit is unable to determine overlap for Facet-based geometry.\n");
+ return CUBIT_FALSE;
+}
+
//EOF
Modified: cgm/branches/cubit/geom/facet/FacetQueryEngine.hpp
===================================================================
--- cgm/branches/cubit/geom/facet/FacetQueryEngine.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/facet/FacetQueryEngine.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -56,19 +56,9 @@
class BodySM;
class GeometryEntity;
-class BodySM;
-class Lump;
-class ShellSM;
-class Surface;
-class LoopSM;
-class Curve;
-class CoEdgeSM;
-class Point;
-class TopologyEntity;
class CubitBox;
class CubitString;
-class OtherSolidModelingEntity;
class FacetLump;
class FacetShell;
class FacetLoop;
@@ -78,11 +68,6 @@
class FacetCurve;
class FacetPoint;
-class RefEntity;
-class RefVertex;
-class RefEdge;
-class RefFace;
-class Loop;
class CubitFacet;
class CubitQuadFacet;
class CubitFacetEdge;
@@ -182,15 +167,11 @@
Body* copy_body( Body *body_ptr );
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;
virtual CubitStatus get_graphics( Curve* curve_ptr,
- int& num_points,
GMem* gMem = NULL,
double tolerance = 0.0 ) const;
//R CubitStatus
@@ -245,7 +226,7 @@
DLIList<CubitVector*>& intersection_list,
CubitBoolean bounded = CUBIT_FALSE );
- virtual CubitStatus entity_extrema( DLIList<GeometryEntity*> &ref_entity_list,
+ virtual CubitStatus entity_extrema( DLIList<GeometryEntity*> &entity_list,
const CubitVector *dir1,
const CubitVector *dir2,
const CubitVector *dir3,
@@ -314,13 +295,22 @@
virtual CubitStatus delete_solid_model_entities( Curve* curve_ptr ) const;
virtual CubitStatus delete_solid_model_entities( Point* point_ptr ) const;
- virtual CubitStatus fire_ray(BodySM *body,
- const CubitVector &ray_point,
- const CubitVector &unit,
- DLIList<double>& ray_params,
- DLIList<GeometryEntity*> *entity_list = NULL) const;
- //- fire a ray at the specified body, returning the entities hit and
- //- the parameters along the ray; return CUBIT_FAILURE if error
+ virtual CubitStatus 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=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. 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).
+ //- NOTE: returned entities hit might be "hidden" beneath virtual entities.
+ //- To resolve to visible entities, use "get_visible_ents_for_hits"
+ //- in GeometryQueryTool.
virtual double get_sme_resabs_tolerance() const; // Gets solid modeler's resolution absolute tolerance
virtual double set_sme_resabs_tolerance( double new_resabs );
@@ -484,6 +474,8 @@
DLIList<FacetSurface*>& output_patch );
virtual CubitBoolean bodies_overlap (BodySM *body_ptr_1,
BodySM *body_ptr_2 ) const;
+ virtual CubitBoolean volumes_overlap (Lump *lump_ptr_1,
+ Lump *lump_ptr_2 ) const;
//R CubitBoolean
//R- CUBIT_TRUE if the two bodies overlap, CUBIT_FALSE if they don't
//R- overlap. If the bodies are touching the function
Modified: cgm/branches/cubit/geom/facet/FacetboolInterface.cpp
===================================================================
--- cgm/branches/cubit/geom/facet/FacetboolInterface.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/facet/FacetboolInterface.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -147,11 +147,12 @@
CubitFacet *facet_ptr;
if(mydebug)
GfxDebug::clear();
- for ( k = 0; k < coordsout.size(); k += 3 ) {
+ for ( k = 0; k < coordsout.size(); k += 3 )
+ {
facet_ptr = new CubitFacetData( points[coordsout[k]],
points[coordsout[k+1]],
points[coordsout[k+2]] );
- int *cptr = new int[3];
+ int cptr[3];
cptr[0] = curveindex[k];
cptr[1] = curveindex[k+1];
cptr[2] = curveindex[k+2];
@@ -254,7 +255,7 @@
facet_ptr = new CubitFacetData( points[coordsout2[k]],
points[coordsout2[k+1]],
points[coordsout2[k+2]] );
- int *cptr = new int[3];
+ int cptr[3];
cptr[0] = curveindex2[k];
cptr[1] = curveindex2[k+1];
cptr[2] = curveindex2[k+2];
@@ -873,7 +874,7 @@
facet_ptr = new CubitFacetData( points[coordsout[k]],
points[coordsout[k+1]],
points[coordsout[k+2]] );
- int *cptr = new int[3];
+ int cptr[3];
cptr[0] = curveindex[k];
cptr[1] = curveindex[k+1];
cptr[2] = curveindex[k+2];
@@ -1371,7 +1372,7 @@
facet_ptr = new CubitFacetData( points[coordsout[k]],
points[coordsout[k+1]],
points[coordsout[k+2]] );
- int *cptr = new int[3];
+ int cptr[3];
cptr[0] = curveindex[k];
cptr[1] = curveindex[k+1];
cptr[2] = curveindex[k+2];
@@ -1509,7 +1510,7 @@
facet_ptr = new CubitFacetData( points[coordsout1[k]],
points[coordsout1[k+1]],
points[coordsout1[k+2]] );
- int *cptr = new int[3];
+ int cptr[3];
cptr[0] = curveindex1[k];
cptr[1] = curveindex1[k+1];
cptr[2] = curveindex1[k+2];
@@ -1569,7 +1570,7 @@
facet_ptr = new CubitFacetData( points[coordsout2[k]],
points[coordsout2[k+1]],
points[coordsout2[k+2]] );
- int *cptr = new int[3];
+ int cptr[3];
cptr[0] = curveindex2[k];
cptr[1] = curveindex2[k+1];
cptr[2] = curveindex2[k+2];
Modified: cgm/branches/cubit/geom/facetbool/FBRetriangulate.cpp
===================================================================
--- cgm/branches/cubit/geom/facetbool/FBRetriangulate.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/facetbool/FBRetriangulate.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -306,7 +306,6 @@
vy2 = verts[my_tri->v2]->coord[1];
vz2 = verts[my_tri->v2]->coord[2];
- dpe_orig = my_tri->edge_list.end();
dpe = my_tri->edge_list.begin();
while ( dpe != my_tri->edge_list.end() ) {
edge = *dpe;
@@ -350,12 +349,13 @@
// in what follows. Erasing elements from a vector is inefficient, but
// this shouldn't happen often.
dpe = my_tri->edge_list.begin();
+ dpe_orig = my_tri->edge_list.end();
while ( dpe != dpe_orig ) {
edge = *dpe;
if ( edge->edge_type == BDRY_EDGE ) {
- my_tri->edge_list.erase(dpe);
- dpe_orig -= 1;
+ dpe = my_tri->edge_list.erase(dpe);
+ dpe_orig = my_tri->edge_list.end();
} else {
dpe++;
}
Modified: cgm/branches/cubit/geom/parallel/Makefile.am
===================================================================
--- cgm/branches/cubit/geom/parallel/Makefile.am 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/parallel/Makefile.am 2010-01-06 19:22:14 UTC (rev 3423)
@@ -27,6 +27,7 @@
AcisMemFile.cpp \
CABodies.cpp \
CGMMemFile.cpp \
+ ParallelGeomTool.cpp \
ProcData.cpp \
TDParallel.cpp
@@ -37,6 +38,7 @@
AcisMemFile.hpp \
CABodies.cpp \
CGMMemFile.hpp \
+ ParallelGeomTool.hpp \
ProcData.hpp \
TDParallel.hpp
Added: cgm/branches/cubit/geom/testing/AngleCalc.cpp
===================================================================
--- cgm/branches/cubit/geom/testing/AngleCalc.cpp (rev 0)
+++ cgm/branches/cubit/geom/testing/AngleCalc.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,65 @@
+
+
+#include "stdio.h"
+
+#include "GeometryQueryTool.hpp"
+#include "GeometryModifyTool.hpp"
+#include "RefEdge.hpp"
+#include "RefVertex.hpp"
+#include "CoEdge.hpp"
+#include "RefFace.hpp"
+#include "CubitDefines.h"
+#include "CubitBox.hpp"
+
+#include "TestUtilities.hpp"
+
+int AngleCalc(int argc, char* argv[])
+{
+ Body* brick = GeometryModifyTool::instance()->brick(1,2,4);
+ if(!brick)
+ {
+ printf("failed to make brick\n");
+ return 1;
+ }
+
+ // compute angles at each vertex and be sure they are 90 degrees
+ DLIList<RefFace*> faces;
+ GeometryQueryTool::instance()->ref_faces(faces);
+
+ bool errors = false;
+
+ for(int i=0; i<faces.size(); i++)
+ {
+ // get loops
+ DLIList<DLIList<CoEdge*>*> loops;
+ RefFace* face = faces.get_and_step();
+ face->co_edge_loops(loops);
+
+ for(int j=0; j<loops.size(); j++)
+ {
+ for(int k=0; k<loops[j]->size(); k++)
+ {
+ CoEdge* edge1 = loops[j]->next(k);
+ CoEdge* edge2 = loops[j]->next(k+1);
+
+ double angle = GeometryQueryTool::instance()->geometric_angle(edge1, edge2);
+ angle = angle * (180/CUBIT_PI);
+ if(fabs(90 - angle) > 0.01)
+ {
+ RefEdge* redge1 = edge1->get_ref_edge_ptr();
+ RefEdge* redge2 = edge2->get_ref_edge_ptr();
+ RefVertex* vert = redge1->common_ref_vertex(redge2);
+
+ printf("wrong angle at vertex (%f) %i with surface %i\n",
+ angle, vert->id(), face->id());
+ errors = true;
+ }
+
+ }
+ delete loops[j];
+ }
+ }
+
+ return errors ? 1 : 0;
+}
+
Added: cgm/branches/cubit/geom/testing/CMakeLists.txt
===================================================================
--- cgm/branches/cubit/geom/testing/CMakeLists.txt (rev 0)
+++ cgm/branches/cubit/geom/testing/CMakeLists.txt 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,82 @@
+
+# test suite to test cgm apis
+# this test suite attempts to work for all cgm ports
+PROJECT(CGM_TESTS)
+
+
+# a list of tests
+# each testname has a testname.cpp file that implements
+# a "int testname(int, char**)" as its entry point
+# testname(int, char**) returns 0 on success
+# when testname(int, char**) is called, cgm has already been initialized
+# and is ready to use with active ports already set
+SET(CGM_TESTS
+ AngleCalc
+ CreateGeometry
+ ReadIgesFile
+ GraphicsData
+ )
+
+
+# CGM_PORTS contains an identifier for the port to use
+# these identifiers are recognized in cgm_test.cpp
+IF(CGM_ACIS)
+ SET(CGM_PORTS ${CGM_PORTS} "acis")
+ INCLUDE(${cubit_acis_SOURCE_DIR}/UseACIS.cmake)
+ ADD_DEFINITIONS(-DCGM_ACIS)
+ INCLUDE_DIRECTORIES(${cubit_acis_SOURCE_DIR} ${ACIS_INCLUDE_DIR})
+ SET(PORT_LIBS ${PORT_LIBS} cubit_ACIS gtcAttrib)
+ IF(NOT WIN32 AND BUILD_64)
+ SET(SKIP_ReadIgesFile-acis 1)
+ ENDIF(NOT WIN32 AND BUILD_64)
+ENDIF(CGM_ACIS)
+IF(CGM_SMLIB)
+ SET(CGM_PORTS ${CGM_PORTS} "smlib")
+ INCLUDE(${cubit_smlib_SOURCE_DIR}/UseSMLib.cmake)
+ INCLUDE_DIRECTORIES(${cubit_smlib_SOURCE_DIR} ${SMLIB_INCLUDE_DIR})
+ ADD_DEFINITIONS(-DCGM_SMLIB)
+ SET(PORT_LIBS ${PORT_LIBS} cubit_smlib)
+ENDIF(CGM_SMLIB)
+
+
+# functions that'll start/end cgm
+# CREATE_TEST_SOURCELIST will insert the function calls into the test driver
+SET(CMAKE_TESTDRIVER_BEFORE_TESTMAIN " start_cgm(ac,av);")
+SET(CMAKE_TESTDRIVER_AFTER_TESTMAIN " end_cgm(ac,av);")
+CREATE_TEST_SOURCELIST(TEST_SRCS cgm_test_driver.cpp ${CGM_TESTS}
+ EXTRA_INCLUDE "cgm_test.hpp")
+
+SET(DATA_DIR "${CMAKE_CURRENT_SOURCE_DIR}/data")
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/TestConfig.h.in
+ ${CMAKE_CURRENT_BINARY_DIR}/TestConfig.h @ONLY)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+
+SET(TEST_SRCS
+ ${TEST_SRCS}
+ cgm_test.cpp
+ cgm_test.hpp
+ TestUtilities.cpp
+ TestUtilities.hpp
+ TestConfig.h
+ )
+
+ADD_EXECUTABLE(cgm_test ${TEST_SRCS})
+TARGET_LINK_LIBRARIES(cgm_test ${PORT_LIBS} cubit_geom cubit_util)
+
+GET_TARGET_PROPERTY(cgm_test_exe cgm_test LOCATION)
+
+# add all the tests for each port
+FOREACH(port ${CGM_PORTS})
+ MESSAGE("adding tests for ${port}")
+ FOREACH(test ${CGM_TESTS})
+ IF(NOT SKIP_${test}-${port})
+ ADD_TEST(
+ cgm-${test}-${port} ${cgm_test_exe} ${test}
+ -E ${port}
+ )
+ ENDIF(NOT SKIP_${test}-${port})
+ ENDFOREACH(test)
+ENDFOREACH(port)
+
Added: cgm/branches/cubit/geom/testing/CreateGeometry.cpp
===================================================================
--- cgm/branches/cubit/geom/testing/CreateGeometry.cpp (rev 0)
+++ cgm/branches/cubit/geom/testing/CreateGeometry.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,230 @@
+
+
+#include "stdio.h"
+
+#include "GeometryQueryTool.hpp"
+#include "GeometryModifyTool.hpp"
+#include "CubitDefines.h"
+#include "CubitBox.hpp"
+
+#include "Body.hpp"
+#include "RefEdge.hpp"
+#include "RefVertex.hpp"
+
+#include "TestUtilities.hpp"
+
+
+static int test_brick()
+{
+ Body* brick = GeometryModifyTool::instance()->brick(1,2,4);
+ if(!brick)
+ {
+ printf("failed to make brick\n");
+ return 1;
+ }
+ if(!cubit_box_identical(brick->bounding_box(),
+ CubitBox(CubitVector(-0.5,-1,-2), CubitVector(0.5,1,2)),
+ GEOMETRY_RESABS*2.0, true))
+ {
+ printf("boxes not identical\n");
+ return 1;
+ }
+ return 0;
+}
+
+static int test_oriented_brick()
+{
+ CubitVector center(1, 2, 4);
+ CubitVector axes[3] = {
+ CubitVector(1, 0, .2),
+ CubitVector(0, 1, .4),
+ CubitVector(0.1, 0, 1)
+ };
+ CubitVector extension(3, 5, 7);
+
+ Body* brick = GeometryModifyTool::instance()->brick(center, axes, extension);
+ if(!brick)
+ {
+ printf("failed to make brick\n");
+ return 1;
+ }
+ if(!cubit_box_identical(brick->bounding_box(),
+ CubitBox(CubitVector(-3.577819, -5.210785, -4.768732),
+ CubitVector(5.577819, 9.210785, 12.768732)),
+ GEOMETRY_RESABS*2.0, true))
+ {
+ printf("boxes not identical\n");
+ return 1;
+ }
+ return 0;
+}
+
+static int test_sphere()
+{
+ Body* sphere = GeometryModifyTool::instance()->sphere(1);
+ if(!sphere)
+ {
+ printf("failed to make sphere\n");
+ return 1;
+ }
+ if(!cubit_box_identical(sphere->bounding_box(),
+ CubitBox(CubitVector(-1,-1,-1), CubitVector(1,1,1)),
+ GEOMETRY_RESABS*2.0, true))
+ {
+ printf("boxes not identical\n");
+ return 1;
+ }
+ return 0;
+}
+
+static int test_torus()
+{
+ printf("making torus\n");
+ Body* torus = GeometryModifyTool::instance()->torus(1, .2);
+ if(!torus)
+ {
+ printf("failed to make torus\n");
+ return 1;
+ }
+ if(!cubit_box_identical(torus->bounding_box(),
+ CubitBox(CubitVector(-1.2,-1.2,-0.2), CubitVector(1.2,1.2,0.2)),
+ GEOMETRY_RESABS*2.0, true))
+ {
+ printf("boxes not identical\n");
+ return 1;
+ }
+ return 0;
+}
+
+static int test_planar_sheet()
+{
+ CubitVector axes[2] = {
+ CubitVector(1,0,0),
+ CubitVector(.1,.9,0)
+ };
+
+ Body* body = GeometryModifyTool::instance()->planar_sheet(CubitVector(1,1,1),
+ axes, 2, 3);
+
+ if(!body)
+ {
+ printf("failed to make planar sheet\n");
+ return 1;
+ }
+ if(!cubit_box_identical(body->bounding_box(),
+ CubitBox(CubitVector(-0.165647,-0.490826,1.0),
+ CubitVector(2.165647,2.490826,1.0)),
+ GEOMETRY_RESABS*2.0, true))
+ {
+ printf("boxes not identical\n");
+ return 1;
+ }
+
+
+ body = GeometryModifyTool::instance()->planar_sheet(
+ CubitVector(0,0,0),
+ CubitVector(1,0,0),
+ CubitVector(1,1,0),
+ CubitVector(0,1,.2)
+ );
+
+ if(body)
+ {
+ printf("should have failed to make planar sheet out of non-planar points\n");
+ return 1;
+ }
+
+ body = GeometryModifyTool::instance()->planar_sheet(
+ CubitVector(0,0,0),
+ CubitVector(0,0,0),
+ CubitVector(1,1,0),
+ CubitVector(0,1,0)
+ );
+
+ if(body)
+ {
+ printf("should have failed to make planar sheet with coincident input points\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+static int test_arc()
+{
+ RefVertex* pt1 = GeometryModifyTool::instance()->make_RefVertex(CubitVector(0,0,0));
+ RefVertex* pt2 = GeometryModifyTool::instance()->make_RefVertex(CubitVector(1,1,0));
+ RefVertex* pt3 = GeometryModifyTool::instance()->make_RefVertex(CubitVector(2,0,0));
+
+ RefEdge* arc = GeometryModifyTool::instance()->create_arc_three(pt1, pt2, pt3, false);
+ if(!arc)
+ {
+ printf("failed to make arc\n");
+ return 1;
+ }
+ if(!cubit_box_identical(arc->bounding_box(),
+ CubitBox(CubitVector(0, 0, 0), CubitVector(2, 1, 0)),
+ GEOMETRY_RESABS*2.0, true))
+ {
+ printf("boxes not identical\n");
+ return 1;
+ }
+
+ // previously free curves at end points must be consumed
+ DLIList<RefVertex*> all_verts;
+ GeometryQueryTool::instance()->ref_vertices(all_verts);
+ if(all_verts.size() != 3)
+ {
+ printf("vertices not consumed properly with curve creation\n");
+ return 1;
+ }
+
+ GeometryQueryTool::instance()->delete_RefVertex(pt2);
+
+ RefVertex* pt4 = GeometryModifyTool::instance()->make_RefVertex(CubitVector(1,-1,0));
+ RefEdge* arc2 = GeometryModifyTool::instance()->create_arc_three(pt1, pt4, pt3, true);
+
+ if(!cubit_box_identical(arc2->bounding_box(),
+ CubitBox(CubitVector(0, -1, 0), CubitVector(2, 1, 0)),
+ GEOMETRY_RESABS*2.0, true))
+ {
+ printf("boxes not identical\n");
+ return 1;
+ }
+
+ all_verts.clean_out();
+ GeometryQueryTool::instance()->ref_vertices(all_verts);
+ if(all_verts.size() != 4)
+ {
+ printf("vertices not consumed properly with curve creation\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+int CreateGeometry(int argc, char* argv[])
+{
+ int ret = 0;
+
+ ret |= test_brick();
+ GeometryQueryTool::instance()->delete_geometry();
+
+ ret |= test_oriented_brick();
+ GeometryQueryTool::instance()->delete_geometry();
+
+ ret |= test_sphere();
+ GeometryQueryTool::instance()->delete_geometry();
+
+ ret |= test_torus();
+ GeometryQueryTool::instance()->delete_geometry();
+
+ ret |= test_planar_sheet();
+ GeometryQueryTool::instance()->delete_geometry();
+
+ ret |= test_arc();
+ GeometryQueryTool::instance()->delete_geometry();
+
+ return ret;
+}
+
Added: cgm/branches/cubit/geom/testing/GraphicsData.cpp
===================================================================
--- cgm/branches/cubit/geom/testing/GraphicsData.cpp (rev 0)
+++ cgm/branches/cubit/geom/testing/GraphicsData.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,127 @@
+
+
+#include "stdio.h"
+
+#include "GMem.hpp"
+#include "GeometryQueryTool.hpp"
+#include "GeometryModifyTool.hpp"
+#include "GeometryQueryEngine.hpp"
+#include "RefEdge.hpp"
+#include "RefFace.hpp"
+#include "CubitDefines.h"
+#include "CubitBox.hpp"
+
+#include "TestUtilities.hpp"
+
+int GraphicsData(int argc, char* argv[])
+{
+ GeometryModifyTool::instance()->brick(10,10,10);
+
+ GeometryQueryEngine* engine = GeometryQueryTool::instance()->get_gqe();
+
+ if(!engine)
+ {
+ printf("no engine\n");
+ return 1;
+ }
+
+ CubitBox uninit_box;
+
+ CubitBox model_bbox(
+ CubitVector(-5, -5, -5),
+ CubitVector(5, 5, 5)
+ );
+
+
+ DLIList<RefEdge*> edges;
+ GeometryQueryTool::instance()->ref_edges(edges);
+
+ // expect 24 edges
+ if(edges.size() != 12)
+ {
+ printf("wrong edge count\n");
+ return 1;
+ }
+
+ // get graphics data for the curves
+
+ CubitBox g_curves = uninit_box;
+ GMem gmem;
+ for(int i=0; i<edges.size(); i++)
+ {
+ RefEdge* edge = edges.get_and_step();
+ if(engine->get_graphics(edge->get_curve_ptr(), &gmem) != CUBIT_SUCCESS ||
+ gmem.pointListCount == 0)
+ {
+ printf("got no edge facet data for edge %i\n", edge->id());
+ }
+ else
+ {
+ for(int j=0; j<gmem.pointListCount; j++)
+ {
+ const GPoint& pt = gmem.point_list()[j];
+ g_curves |= CubitVector(pt.x, pt.y, pt.z);
+ }
+ }
+ }
+
+ printf("curve bbox range = %f %f %f\n",
+ g_curves.x_range(), g_curves.y_range(), g_curves.z_range());
+
+ if(!cubit_box_identical(g_curves, model_bbox, GEOMETRY_RESABS))
+ {
+ printf("didn't get accurate facet data for curves\n");
+ return 1;
+ }
+
+
+ CubitBox g_surfaces = uninit_box;
+ DLIList<RefFace*> faces;
+ GeometryQueryTool::instance()->ref_faces(faces);
+
+ // expect 6 edges
+ if(faces.size() != 6)
+ {
+ printf("wrong face count\n");
+ return 1;
+ }
+
+ // get graphics data for the surfaces
+ for(int i=0; i<faces.size(); i++)
+ {
+ RefFace* face = faces.get_and_step();
+ if(engine->get_graphics(face->get_surface_ptr(), &gmem) != CUBIT_SUCCESS ||
+ gmem.pointListCount == 0 || gmem.fListCount == 0)
+ {
+ printf("got no face facet data for face %i\n", face->id());
+ }
+ else
+ {
+ const GPoint* pts = gmem.point_list();
+ const int* facets = gmem.facet_list();
+ int facet_size = gmem.fListCount;
+ for(int j=0; j<facet_size;)
+ {
+ int num = facets[j++];
+ for(int k=0; k<num; k++)
+ {
+ const GPoint& pt = pts[facets[j++]];
+ g_surfaces |= CubitVector(pt.x, pt.y, pt.z);
+ }
+ }
+ }
+ }
+
+ printf("surface bbox range = %f %f %f\n",
+ g_surfaces.x_range(), g_surfaces.y_range(), g_surfaces.z_range());
+
+ if(!cubit_box_identical(g_surfaces, model_bbox, GEOMETRY_RESABS))
+ {
+ printf("didn't get accurate facet data for surfaces\n");
+ return 1;
+ }
+
+
+ return 0;
+}
+
Added: cgm/branches/cubit/geom/testing/Makefile.am
===================================================================
--- cgm/branches/cubit/geom/testing/Makefile.am (rev 0)
+++ cgm/branches/cubit/geom/testing/Makefile.am 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,24 @@
+BASE_TESTS = AngleCalc.engine \
+ GreateGeometry.engine \
+ ReadIgesFile.engine \
+ GraphicsData.engine
+
+TESTS=
+if build_ACIS
+ TESTS += $(BASE_TESTS:.engine=.acis)
+endif
+if build_OCC
+ TESTS += $(BASE_TESTS:.engine=.occ)
+endif
+
+
+SUFFIXES += .acis .occ
+check_PROGRAMS = $(TESTS) cgm_test
+cgm_test_SOURCES = cgm_test.cpp \
+ cgm_test.hpp \
+ TestUtilities.hpp \
+ TestUtilities.cpp \
+ TestConfig.h
+
+%.acis %.occ: cgm_test_script
+ cp -f cgm_test_script $@
Added: cgm/branches/cubit/geom/testing/ReadIgesFile.cpp
===================================================================
--- cgm/branches/cubit/geom/testing/ReadIgesFile.cpp (rev 0)
+++ cgm/branches/cubit/geom/testing/ReadIgesFile.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,22 @@
+
+#include "stdio.h"
+#include "TestUtilities.hpp"
+
+#include "GeometryQueryTool.hpp"
+
+int ReadIgesFile(int argc, char* argv[])
+{
+
+ std::string file = data_file("brick.iges");
+
+ CubitStatus stat = GeometryQueryTool::instance()->import_solid_model(file.c_str(), "IGES");
+
+ if(stat != CUBIT_SUCCESS)
+ {
+ printf("failed to read iges file %s\n", file.c_str());
+ return 1;
+ }
+
+ return 0;
+}
+
Added: cgm/branches/cubit/geom/testing/TestConfig.h.in
===================================================================
--- cgm/branches/cubit/geom/testing/TestConfig.h.in (rev 0)
+++ cgm/branches/cubit/geom/testing/TestConfig.h.in 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,8 @@
+
+#ifndef TEST_CONFIG_HPP
+#define TEST_CONFIG_HPP
+
+static const char* DataDir = "@DATA_DIR@";
+
+#endif
+
Added: cgm/branches/cubit/geom/testing/TestUtilities.cpp
===================================================================
--- cgm/branches/cubit/geom/testing/TestUtilities.cpp (rev 0)
+++ cgm/branches/cubit/geom/testing/TestUtilities.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,39 @@
+
+
+#include "TestUtilities.hpp"
+#include "TestConfig.h"
+
+std::string data_file(char* filename)
+{
+ return DataDir + std::string("/") + std::string(filename);
+}
+
+
+bool cubit_box_identical(const CubitBox& box1, const CubitBox& box2, double tol,
+ bool print_data)
+{
+ if(print_data)
+ {
+ printf("box 1 {(%f %f %f), (%f %f %f)}\n",
+ box1.minimum().x(),
+ box1.minimum().y(),
+ box1.minimum().z(),
+ box1.maximum().x(),
+ box1.maximum().y(),
+ box1.maximum().z()
+ );
+ printf("box 2 {(%f %f %f), (%f %f %f)}\n",
+ box2.minimum().x(),
+ box2.minimum().y(),
+ box2.minimum().z(),
+ box2.maximum().x(),
+ box2.maximum().y(),
+ box2.maximum().z()
+ );
+ }
+
+ return box1.maximum().within_tolerance(box2.maximum(), tol) &&
+ box1.minimum().within_tolerance(box2.minimum(), tol);
+}
+
+
Added: cgm/branches/cubit/geom/testing/TestUtilities.hpp
===================================================================
--- cgm/branches/cubit/geom/testing/TestUtilities.hpp (rev 0)
+++ cgm/branches/cubit/geom/testing/TestUtilities.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,18 @@
+
+#ifndef TEST_UTILITIES_HPP
+#define TEST_UTILITIES_HPP
+
+#include "CubitBox.hpp"
+#include <string>
+
+// function to get the path to a data file in the data directory
+std::string data_file(char* filename);
+
+// compare if 2 CubitBoxes are identical
+bool cubit_box_identical(const CubitBox& box1, const CubitBox& box2, double tol,
+ bool print_data = false);
+
+
+
+#endif
+
Added: cgm/branches/cubit/geom/testing/cgm_test.cpp
===================================================================
--- cgm/branches/cubit/geom/testing/cgm_test.cpp (rev 0)
+++ cgm/branches/cubit/geom/testing/cgm_test.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,83 @@
+
+
+#include "cgm_test.hpp"
+
+#include "AppUtil.hpp"
+#include "TextProgressTool.hpp"
+#include "CGMApp.hpp"
+#include "GeometryQueryTool.hpp"
+#include "GeometryModifyTool.hpp"
+
+#ifdef CGM_SMLIB
+#include "SMLibQueryEngine.hpp"
+#include "SMLibModifyEngine.hpp"
+#endif
+
+#ifdef CGM_ACIS
+#include "AcisQueryEngine.hpp"
+#include "AcisModifyEngine.hpp"
+#endif
+
+
+static std::string cgm_port;
+
+void start_cgm(int argc, char** argv)
+{
+ for(int i=0; i<argc; i++)
+ {
+ // get library name
+ if(std::string(argv[i]) == "-E" && i+1 < argc)
+ {
+ cgm_port = argv[i+1];
+ }
+ }
+
+
+ // init util
+ AppUtil::instance()->startup(argc, argv);
+ AppUtil::instance()->progress_tool(new TextProgressTool());
+
+ // init cgm
+ CGMApp::instance()->startup(argc, argv);
+
+ GeometryQueryEngine* query_engine = NULL;
+ GeometryModifyEngine* modify_engine = NULL;
+ printf("using %s engine\n", cgm_port.c_str());
+
+ // find the engine
+ if(0)
+ {
+ // nothing here
+ }
+#ifdef CGM_ACIS
+ else if(cgm_port == "acis")
+ {
+ query_engine = AcisQueryEngine::instance();
+ modify_engine = AcisModifyEngine::instance();
+ }
+#endif
+#ifdef CGM_SMLIB
+ else if(cgm_port == "smlib")
+ {
+ query_engine = SMLibQueryEngine::instance();
+ modify_engine = SMLibModifyEngine::instance();
+ }
+#endif
+
+ if(query_engine == NULL || modify_engine == NULL)
+ {
+ printf("no engine set with -E flag\n");
+ exit(1);
+ }
+}
+
+void end_cgm(int argc, char** argv)
+{
+ CGMApp::instance()->shutdown();
+ CGMApp::delete_instance();
+
+ // close down util module
+ AppUtil::instance()->shutdown();
+ AppUtil::delete_instance();
+}
+
Added: cgm/branches/cubit/geom/testing/cgm_test.hpp
===================================================================
--- cgm/branches/cubit/geom/testing/cgm_test.hpp (rev 0)
+++ cgm/branches/cubit/geom/testing/cgm_test.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,13 @@
+
+
+#ifndef CGM_TEST_H
+#define CGM_TEST_H
+
+// function to initialize cgm
+void start_cgm(int argc, char** argv);
+// function to shutdown cgm
+void end_cgm(int argc, char** argv);
+
+
+#endif // CGM_TEST_H
+
Added: cgm/branches/cubit/geom/testing/cgm_test_script
===================================================================
--- cgm/branches/cubit/geom/testing/cgm_test_script (rev 0)
+++ cgm/branches/cubit/geom/testing/cgm_test_script 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,6 @@
+#!/bin.sh
+
+name="$0"
+test=`expr $name : '\(.*\)\.'`
+engine=`expr $name : '.*\.\(.*\)'
+cgm_test $test -E $engine
Added: cgm/branches/cubit/geom/testing/data/brick.iges
===================================================================
--- cgm/branches/cubit/geom/testing/data/brick.iges (rev 0)
+++ cgm/branches/cubit/geom/testing/data/brick.iges 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,58 @@
+ACIS data in IGES format S 1
+
+1H,,1H;,10HCubit 7.1b,7HUnknown,4HACIS,17H*IGES writer V5.2,32,308,15, G 1
+
+308,15,7HUnknown,1.,2,2HMM,1,1.,15H20020710.130033,0.002, G 2
+
+2886.7513459481,7Hcjstimp,9HCLINTONNT,10,0,15H20020710.130033; G 3
+
+ 128 1 0 1 0 0 0 000000001D 1
+
+ 128 0 4 2 1 0D 2
+
+ 128 3 0 1 0 0 0 000000001D 3
+
+ 128 0 4 2 1 0D 4
+
+ 128 5 0 1 0 0 0 000000001D 5
+
+ 128 0 4 2 1 0D 6
+
+ 128 7 0 1 0 0 0 000000001D 7
+
+ 128 0 4 2 1 0D 8
+
+ 128 9 0 1 0 0 0 000000001D 9
+
+ 128 0 4 2 1 0D 10
+
+ 128 11 0 1 0 0 0 000000001D 11
+
+ 128 0 4 2 1 0D 12
+
+128,1,1,1,1,0,0,1,0,0,0.,0.,10.,10.,0.,0.,10.,10.,1.,1.,1.,1., 1P 1
+
+-5.,-5.,5.,5.,-5.,5.,-5.,5.,5.,5.,5.,5.,0.,10.,0.,10.; 1P 2
+
+128,1,1,1,1,0,0,1,0,0,-10.,-10.,0.,0.,0.,0.,10.,10.,1.,1.,1., 3P 3
+
+1.,5.,-5.,-5.,-5.,-5.,-5.,5.,5.,-5.,-5.,5.,-5.,-10.,0.,0.,10.; 3P 4
+
+128,1,1,1,1,0,0,1,0,0,-10.,-10.,0.,0.,0.,0.,10.,10.,1.,1.,1., 5P 5
+
+1.,-5.,-5.,5.,-5.,-5.,-5.,5.,-5.,5.,5.,-5.,-5.,-10.,0.,0.,10.; 5P 6
+
+128,1,1,1,1,0,0,1,0,0,-10.,-10.,0.,0.,0.,0.,10.,10.,1.,1.,1., 7P 7
+
+1.,-5.,-5.,-5.,-5.,-5.,5.,-5.,5.,-5.,-5.,5.,5.,-10.,0.,0.,10.; 7P 8
+
+128,1,1,1,1,0,0,1,0,0,-10.,-10.,0.,0.,0.,0.,10.,10.,1.,1.,1., 9P 9
+
+1.,-5.,5.,-5.,-5.,5.,5.,5.,5.,-5.,5.,5.,5.,-10.,0.,0.,10.; 9P 10
+
+128,1,1,1,1,0,0,1,0,0,-10.,-10.,0.,0.,0.,0.,10.,10.,1.,1.,1., 11P 11
+
+1.,5.,-5.,5.,5.,-5.,-5.,5.,5.,5.,5.,5.,-5.,-10.,0.,0.,10.; 11P 12
+
+S 1G 3D 12P 12 T 1
+
Property changes on: cgm/branches/cubit/geom/testing/data/brick.iges
___________________________________________________________________
Added: svn:executable
+ *
Modified: cgm/branches/cubit/geom/virtual/CMakeLists.txt
===================================================================
--- cgm/branches/cubit/geom/virtual/CMakeLists.txt 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/CMakeLists.txt 2010-01-06 19:22:14 UTC (rev 3423)
@@ -50,6 +50,7 @@
RemoveBlends.cpp
SegmentedCurve.cpp
SimplifyTool.cpp
+ SplitCompositeSurfaceTool.cpp
SubCurve.cpp
SubEntitySet.cpp
SubSurface.cpp
Modified: cgm/branches/cubit/geom/virtual/CollapseCurveTool.cpp
===================================================================
--- cgm/branches/cubit/geom/virtual/CollapseCurveTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/CollapseCurveTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -27,9 +27,14 @@
#include "Point.hpp"
#include "Loop.hpp"
#include "RefFace.hpp"
+#include "Body.hpp"
#include "PartitionTool.hpp"
#include "CompositeTool.hpp"
#include "CollapseCurveTool.hpp"
+#include "GeometryModifyTool.hpp"
+#include "SplitCompositeSurfaceTool.hpp"
+#include "CubitUndo.hpp"
+//#include "InteropTool.hpp"
/*
*/
@@ -46,9 +51,10 @@
return instance_;
}
-CubitStatus CollapseCurveTool::collapse_curve(DLIList <RefEdge*> ref_edge_list,
+CubitStatus CollapseCurveTool::collapse_curve_only_virtual(DLIList <RefEdge*> ref_edge_list,
DLIList<RefVertex*> ref_vertex_list,
- int ignore_surfaces)
+ int ignore_surfaces,
+ double *small_curve_size)
{
CubitStatus result = CUBIT_SUCCESS;
@@ -82,6 +88,11 @@
CubitVector position_on_left_curve(0,0,0), position_on_right_curve(0,0,0);
CubitVector discard_pos(0,0,0), keep_pos(0,0,0);
+ bool undo_state = CubitUndo::get_undo_enabled();
+ if( undo_state )
+ CubitUndo::save_state_with_cubit_file( ref_edge_list );
+ CubitUndo::set_undo_enabled(false);
+
if(edge_to_collapse == NULL)
{
PRINT_ERROR("No curve was found to collapse.\n");
@@ -120,7 +131,7 @@
finished = 1;
}
}
-
+
if(!finished)
{
// Get the valency of the keep and discard vertices.
@@ -208,6 +219,32 @@
}
}
+ if(!finished && small_curve_size)
+ {
+ // Check if the edges attached to the discard vertex are longer
+ // than the small curve size.
+ DLIList<RefEdge*> tmp_edges;
+ discard_vertex->ref_edges(tmp_edges);
+ if(tmp_edges.move_to(edge_to_collapse))
+ tmp_edges.extract();
+ int y;
+ bool all_edges_long_enough = true;
+ for(y=tmp_edges.size(); y && all_edges_long_enough; y--)
+ {
+ RefEdge *cur_edge = tmp_edges.get_and_step();
+ if(cur_edge->get_arc_length() <= *small_curve_size)
+ all_edges_long_enough = false;
+ }
+ if(!all_edges_long_enough)
+ {
+ PRINT_ERROR("Cannot collapse curve %d to vertex %d--not all of the curves attached to\n"
+ "vertex %d are longer than the small_curve_size. Try collapsing to vertex %d instead.\n",
+ edge_to_collapse->id(), keep_vertex->id(), discard_vertex->id(), discard_vertex->id());
+ result = CUBIT_FAILURE;
+ finished = 1;
+ }
+ }
+
// Look at all of the coedges on the curve being collapsed and
// throw out any that are on nonmanifold surfaces. The collapse
// curve may be on a boundary of a merged surface. This is ok
@@ -290,6 +327,9 @@
// keep vertex looking at the discard vertex.
Loop *left_loop = enter_coedge->get_loop_ptr();
Loop *right_loop = exit_coedge->get_loop_ptr();
+ DLIList<SenseEntity*> left_sense_entities, right_sense_entities;
+ left_loop->get_sense_entity_list(left_sense_entities);
+ right_loop->get_sense_entity_list(right_sense_entities);
// We need to get these two coedges because the chains defined by the "next" and
// "previous" pointers in the CoEdge objects are not circular (you can have a NULL
@@ -322,9 +362,10 @@
DLIList<RefEdge*> right_face_edges;
left_common_face->ref_edges(left_face_edges);
right_common_face->ref_edges(right_face_edges);
- if(left_face_edges.size() < 3 || right_face_edges.size() < 3)
+ if(left_face_edges.size() < 3 || right_face_edges.size() < 3 ||
+ left_sense_entities.size() < 3 || right_sense_entities.size() < 3)
{
- PRINT_ERROR("Cannot collapse a curve that bounds a face with only two edges.\n");
+ PRINT_ERROR("Cannot collapse a curve that bounds a face or loop with only two edges.\n");
finished = 1;
}
else
@@ -528,7 +569,6 @@
// the collapse edge and isn't nonmanifold.
DLIList<CoEdge*> side_edge_coedges;
side_edge->co_edges(side_edge_coedges);
- RefFace *adjacent_face = NULL;
DLIList<RefFace*> possible_adj_faces;
// First loop through and get all of the potential faces.
@@ -875,19 +915,1051 @@
}
}
- if(result == CUBIT_FAILURE)
+ CubitUndo::set_undo_enabled(undo_state);
+
+ return result;
+}
+
+CubitStatus CollapseCurveTool::collapse_curve(DLIList <RefEdge*> ref_edge_list,
+ DLIList<RefVertex*> ref_vertex_list,
+ int ignore_surfaces,
+ double *small_curve_size)
+{
+ CubitStatus result = CUBIT_SUCCESS;
+
+ RefEdge *edge_to_collapse = ref_edge_list.get();
+ RefVertex *keep_vertex = NULL;
+ RefVertex *discard_vertex = NULL;
+ CoEdge *exit_coedge = NULL;
+ CoEdge *enter_coedge = NULL;
+ DLIList<RefEdge*> curves_to_partition;
+ DLIList<RefFace*> surfaces_to_partition;
+ DLIList<CubitVector> partition_positions;
+ DLIList<CubitVector> keep_vecs;
+ DLIList<CubitVector> partition_curve_vecs;
+ DLIList<RefFace*> adjacent_surfaces;
+ DLIList<double> angles;
+ DLIList<double> arc_lengths;
+ DLIList<RefEdge*> ref_edges_on_discard_vertex;
+ DLIList<RefEdge*> ref_edges_on_keep_vertex;
+ DLIList<RefVertex*> new_partition_vertices;
+ DLIList<RefEdge*> new_partition_edges;
+ RefEdge *close_edge = NULL;
+ RefEdge *far_edge = NULL;
+ DLIList<RefEdge*> edges_to_composite;
+ int keep_vertex_specified = 0;
+ int discard_valency = 0;
+ int keep_valency = 0;
+ int finished = 0;
+ double arc_length = 0;
+ double u = 0, v = 0;
+ CubitVector left_vec(0,0,0), right_vec(0,0,0);
+ CubitVector position_on_left_curve(0,0,0), position_on_right_curve(0,0,0);
+ CubitVector discard_pos(0,0,0), keep_pos(0,0,0);
+ Body *the_body;
+
+ bool undo_state = CubitUndo::get_undo_enabled();
+ if( undo_state )
+ CubitUndo::save_state_with_cubit_file( ref_edge_list );
+ CubitUndo::set_undo_enabled(false);
+
+ if(edge_to_collapse == NULL)
{
- int i;
- for(i=new_partition_edges.size(); i--;)
+ PRINT_ERROR("No curve was found to collapse.\n");
+ finished = 1;
+ result = CUBIT_FAILURE;
+ }
+
+ if(edge_to_collapse->is_merged())
+ {
+ PRINT_ERROR("Cannot collapse a merged curve.\n");
+ finished = 1;
+ result = CUBIT_FAILURE;
+ }
+
+ if(edge_to_collapse->start_vertex()->is_merged() &&
+ edge_to_collapse->end_vertex()->is_merged())
+ {
+ PRINT_ERROR("Cannot collapse a curve where both vertices are merged.\n");
+ finished = 1;
+ result = CUBIT_FAILURE;
+ }
+ else if(edge_to_collapse->start_vertex()->is_merged())
+ {
+ if(ref_vertex_list.size() > 0)
{
- CompositeTool::instance()->remove_edge(new_partition_edges.get_and_step(), true);
+ if(ref_vertex_list.get() == edge_to_collapse->end_vertex())
+ {
+ PRINT_ERROR("Specified vertex to collapse to is merged--try using other vertex.\n");
+ finished = 1;
+ result = CUBIT_FAILURE;
+ }
}
- for(i=new_partition_vertices.size(); i--;)
+ else
+ ref_vertex_list.append(edge_to_collapse->start_vertex());
+ }
+ else if(edge_to_collapse->end_vertex()->is_merged())
+ {
+ if(ref_vertex_list.size() > 0)
{
- CompositeTool::instance()->remove_vertex(new_partition_vertices.get_and_step(), true);
+ if(ref_vertex_list.get() == edge_to_collapse->start_vertex())
+ {
+ PRINT_ERROR("Specified vertex to collapse to is merged--try using other vertex.\n");
+ finished = 1;
+ result = CUBIT_FAILURE;
+ }
}
+ else
+ ref_vertex_list.append(edge_to_collapse->end_vertex());
}
+ if(!finished)
+ {
+ the_body = edge_to_collapse->body();
+
+ // Make sure we have a vertex to keep.
+ if(ref_vertex_list.size() > 0)
+ {
+ keep_vertex_specified = 1;
+ keep_vertex = ref_vertex_list.get();
+ }
+ // We need to choose a vertex to keep.
+ else
+ {
+ // Arbitrarily choose start vertex.
+ keep_vertex = edge_to_collapse->start_vertex();
+ }
+
+ // Get the vertex that will go away.
+ if(keep_vertex == edge_to_collapse->start_vertex())
+ {
+ discard_vertex = edge_to_collapse->end_vertex();
+ }
+ else if(keep_vertex == edge_to_collapse->end_vertex())
+ {
+ discard_vertex = edge_to_collapse->start_vertex();
+ }
+ else
+ {
+ PRINT_ERROR("Vertex to keep was not found on the curve being collapsed.\n");
+ result = CUBIT_FAILURE;
+ finished = 1;
+ }
+ }
+
+ if(!finished)
+ {
+ // Get the valency of the keep and discard vertices.
+ discard_vertex->ref_edges(ref_edges_on_discard_vertex);
+ keep_vertex->ref_edges(ref_edges_on_keep_vertex);
+ discard_valency = ref_edges_on_discard_vertex.size();
+ keep_valency = ref_edges_on_keep_vertex.size();
+
+ // Now do some error checking and also some logic to try to
+ // pick the best vertex to keep/discard.
+
+ // If one of the valencies is 2 just composite the vertex out.
+ if(discard_valency == 2)
+ {
+ CompositeTool::instance()->composite(ref_edges_on_discard_vertex);
+ finished = 1;
+ }
+ else if (keep_valency == 2)
+ {
+ CompositeTool::instance()->composite(ref_edges_on_keep_vertex);
+ finished = 1;
+ }
+ else
+ {
+ // Make sure that at least one of the vertices is qualified to
+ // be the discard vertex (valency of 3 or 4). The keep vertex
+ // really doesn't have any restrictions.
+ if((discard_valency > 4 || discard_valency < 3) &&
+ (keep_valency > 4 || keep_valency < 3))
+ {
+ PRINT_ERROR("Cannot currently collapse curves where one of the vertices does not have a valency equal to 3 or 4.\n");
+ result = CUBIT_FAILURE;
+ finished = 1;
+ }
+ else
+ {
+ if(keep_vertex_specified)
+ {
+ if(discard_valency < 3 || discard_valency > 4)
+ {
+ PRINT_ERROR("Cannot currently collapse curves where the discard vertex valency is not 3 or 4.\n"
+ "Try specifying the keep vertex so that the discard vertex is 3 or 4.\n");
+ result = CUBIT_FAILURE;
+ finished = 1;
+ }
+ }
+ else
+ {
+ // The user didn't specify a keep vertex so we can try to choose the best one.
+
+ int swap_vertices = 0;
+ if(discard_valency < 5 && discard_valency > 2 &&
+ keep_valency < 5 && keep_valency > 2)
+ {
+ // Either vertex can be the discard/keep vertex so choose the one with the
+ // lower valency as the discard vertex because it will require fewer operations.
+ if(discard_valency > keep_valency)
+ {
+ swap_vertices = 1;
+ }
+ }
+ else
+ {
+ // Only one of the vertices can be the discard vertex so pick it.
+ if(discard_valency > 4 || discard_valency < 3)
+ {
+ swap_vertices = 1;
+ }
+ }
+
+ if(swap_vertices)
+ {
+ // Swap the vertices.
+ RefVertex *tmp = discard_vertex;
+ discard_vertex = keep_vertex;
+ keep_vertex = tmp;
+
+ // Make sure to refresh the discard vertex edge list because
+ // it is used below.
+ ref_edges_on_discard_vertex.clean_out();
+ discard_vertex->ref_edges(ref_edges_on_discard_vertex);
+ }
+ }
+ }
+ }
+ }
+
+ if(!finished && small_curve_size)
+ {
+ // Check if the edges attached to the discard vertex are longer
+ // than the small curve size.
+ DLIList<RefEdge*> tmp_edges;
+ discard_vertex->ref_edges(tmp_edges);
+ if(tmp_edges.move_to(edge_to_collapse))
+ tmp_edges.extract();
+ int y;
+ bool all_edges_long_enough = true;
+ for(y=tmp_edges.size(); y && all_edges_long_enough; y--)
+ {
+ RefEdge *cur_edge = tmp_edges.get_and_step();
+ if(cur_edge->get_arc_length() <= *small_curve_size)
+ all_edges_long_enough = false;
+ }
+ if(!all_edges_long_enough)
+ {
+ PRINT_ERROR("Cannot collapse curve %d to vertex %d--not all of the curves attached to\n"
+ "vertex %d are longer than the small_curve_size. Try collapsing to vertex %d instead.\n",
+ edge_to_collapse->id(), keep_vertex->id(), discard_vertex->id(), discard_vertex->id());
+ result = CUBIT_FAILURE;
+ finished = 1;
+ }
+ }
+
+ // Look at all of the coedges on the curve being collapsed and
+ // throw out any that are on nonmanifold surfaces. The collapse
+ // curve may be on a boundary of a merged surface. This is ok
+ // but we want to make sure we don't involve this surface
+ // in the partitions and composites so we will remove from the
+ // list any coedges that are hooked to merged surfaces.
+ if(!finished)
+ {
+ DLIList<CoEdge*> collapse_curve_coedges;
+ edge_to_collapse->get_co_edges(collapse_curve_coedges);
+
+ int initial_size = collapse_curve_coedges.size();
+ while(collapse_curve_coedges.size() > 2 && initial_size > 0)
+ {
+ for(int g=collapse_curve_coedges.size(); g--;)
+ {
+ CoEdge *cur_coedge = collapse_curve_coedges.get_and_step();
+ Loop *loop_ptr = cur_coedge->get_loop_ptr();
+ if(loop_ptr)
+ {
+ RefFace *ref_face_ptr = loop_ptr->get_ref_face_ptr();
+ if(ref_face_ptr)
+ {
+ DLIList<CoFace*> coface_list;
+ ref_face_ptr->co_faces(coface_list);
+ if(coface_list.size() > 1)
+ {
+ collapse_curve_coedges.remove(cur_coedge);
+ g = 0;
+ }
+ }
+ }
+ }
+
+ // Keep from looping infinitely.
+ initial_size--;
+ }
+
+ // If we get to this point and have more than 2 coedges left
+ // in the list we are not sure what to do.
+ if(collapse_curve_coedges.size() != 2)
+ {
+ PRINT_ERROR("Currently can only collapse curves with manifold topology.\n");
+ result = CUBIT_FAILURE;
+ finished = 1;
+ }
+ else
+ {
+ // Get the collapse curve coedges entering and leaving the discard vertex.
+ exit_coedge = collapse_curve_coedges.get_and_step();
+ enter_coedge = collapse_curve_coedges.get();
+ if(enter_coedge->end_vertex() != discard_vertex)
+ {
+ CoEdge *tmp = exit_coedge;
+ exit_coedge = enter_coedge;
+ enter_coedge = tmp;
+ }
+ }
+ }
+
+ // Next we need to explore the topology around the discard vertex
+ // so that we can get the edges and surfaces that will be involved
+ // with the partitioning and compositing. We will identify a "left"
+ // and "right" edge coming out of the discard vertex and adjacent
+ // surfacs to these edges.
+ if(!finished)
+ {
+ // Get these values for use later on.
+ discard_pos = discard_vertex->get_point_ptr()->coordinates();
+ keep_pos = keep_vertex->get_point_ptr()->coordinates();
+ CubitVector discard_to_keep = keep_pos - discard_pos;
+ arc_length = edge_to_collapse->get_arc_length();
+
+ // Depending on whether the discard vertex has valency of 3 or 4 we will
+ // either partition 1 or 2 of the curves coming into the discard vertex
+ // respectively. Set up lists so that below we can just loop through the
+ // partitioning and compositing for either the 3 or 4 valency case.
+
+ // "Left" and "right" will be defined as if you were standing on the
+ // keep vertex looking at the discard vertex.
+ Loop *left_loop = enter_coedge->get_loop_ptr();
+ Loop *right_loop = exit_coedge->get_loop_ptr();
+ DLIList<SenseEntity*> left_sense_entities, right_sense_entities;
+ left_loop->get_sense_entity_list(left_sense_entities);
+ right_loop->get_sense_entity_list(right_sense_entities);
+
+ // We need to get these two coedges because the chains defined by the "next" and
+ // "previous" pointers in the CoEdge objects are not circular (you can have a NULL
+ // "previous" or "next" pointer). We will manage the circularity manually.
+ CoEdge *left_start = dynamic_cast<CoEdge*>(left_loop->get_first_sense_entity_ptr());
+ CoEdge *right_end = dynamic_cast<CoEdge*>(right_loop->get_last_sense_entity_ptr());
+
+ CoEdge *left_coedge = dynamic_cast<CoEdge*>(enter_coedge->next());
+ if(left_coedge == NULL)
+ {
+ left_coedge = left_start;
+ }
+ CoEdge *right_coedge = dynamic_cast<CoEdge*>(exit_coedge->previous());
+ if(right_coedge == NULL)
+ {
+ right_coedge = right_end;
+ }
+
+ RefEdge *left_edge = left_coedge->get_ref_edge_ptr();
+ RefEdge *right_edge = right_coedge->get_ref_edge_ptr();
+ RefFace *left_common_face = left_edge->common_ref_face(edge_to_collapse);
+ RefFace *right_common_face = right_edge->common_ref_face(edge_to_collapse);
+
+ double left_arc_length = left_edge->get_arc_length();
+ double right_arc_length = right_edge->get_arc_length();
+ int left_ok = 1;
+ int right_ok = 1;
+
+ DLIList<RefEdge*> left_face_edges;
+ DLIList<RefEdge*> right_face_edges;
+ left_common_face->ref_edges(left_face_edges);
+ right_common_face->ref_edges(right_face_edges);
+ if(left_face_edges.size() < 3 || right_face_edges.size() < 3 ||
+ left_sense_entities.size() < 3 || right_sense_entities.size() < 3)
+ {
+ PRINT_ERROR("Cannot collapse a curve that bounds a face or loop with only two edges.\n");
+ result = CUBIT_FAILURE;
+ finished = 1;
+ }
+ else
+ {
+ // We use the length of the curve being collapsed as the distance
+ // to partition the adjacent curves connected to it. If the
+ // adjacent curves are shorter than the curve being collapsed we
+ // will bail because the user should probably be getting rid
+ // of the adjacent edges instead or at least first.
+
+ // Get the length of the adjacent curves.
+
+ // If the adjacent curve is within resabs of the length of
+ // the curve being collapsed we will just snap to the end
+ // of the adjacent curve for our partition position.
+ if(arc_length > left_arc_length + GEOMETRY_RESABS)
+ {
+ left_ok = 0;
+ }
+ if(arc_length > right_arc_length + GEOMETRY_RESABS)
+ {
+ right_ok = 0;
+ }
+
+ // If neither curve is ok we need to bail.
+ if(!left_ok && !right_ok)
+ {
+ PRINT_ERROR("Curve being collapsed is too long compared to adjacent curves.\n");
+ result = CUBIT_FAILURE;
+ finished = 1;
+ }
+ }
+
+ // If it looks like the lengths of the adjacent curves are
+ // ok we will go ahead and try to find a partition position
+ // on them.
+ if(!finished)
+ {
+ if(left_ok)
+ {
+ // First see if we can just use the end point of the
+ // adjacent curve as the partition position.
+ if(fabs(left_arc_length-arc_length) < GEOMETRY_RESABS)
+ {
+ if(left_edge->start_vertex() == discard_vertex)
+ position_on_left_curve = left_edge->end_vertex()->coordinates();
+ else
+ position_on_left_curve = left_edge->start_vertex()->coordinates();
+ }
+ else
+ {
+ result = this->position_from_length(left_edge, discard_vertex,
+ arc_length, position_on_left_curve);
+ }
+ }
+ if(result == CUBIT_SUCCESS && right_ok)
+ {
+ // First see if we can just use the end point of the
+ // adjacent curve as the partition position.
+ if(fabs(right_arc_length-arc_length) < GEOMETRY_RESABS)
+ {
+ if(right_edge->start_vertex() == discard_vertex)
+ position_on_right_curve = right_edge->end_vertex()->coordinates();
+ else
+ position_on_right_curve = right_edge->start_vertex()->coordinates();
+ }
+ else
+ {
+ result = this->position_from_length(right_edge, discard_vertex,
+ arc_length, position_on_right_curve);
+ }
+ }
+ if(result == CUBIT_FAILURE)
+ {
+ PRINT_ERROR("Was unable to locate appropriate partition points on curves adjacent to curve being collapased.\n");
+ result = CUBIT_FAILURE;
+ finished = 1;
+ }
+ }
+
+ if(!finished)
+ {
+ // Get the vectors from the discard vertex to the potential partition locations.
+ CubitVector left_vec = position_on_left_curve - discard_pos;
+ CubitVector right_vec = position_on_right_curve - discard_pos;
+
+ // Calculate the angles between the left/right edge and the
+ // edge being collapsed. I am doing it this way rather than just
+ // calling RefEdge::angle_between() because I want the angle
+ // calculation done out at the potential partition location.
+ // This will step over any small kinks in the curve near the
+ // discard vertex that might otherwise give misleading angles
+ // that don't represent what is happening out by the potential
+ // partition position.
+ left_common_face->u_v_from_position(discard_pos, u, v);
+ CubitVector left_normal = left_common_face->normal_at(discard_pos, NULL, &u, &v);
+ double left_angle = left_normal.vector_angle(left_vec, discard_to_keep);
+
+ right_common_face->u_v_from_position(discard_pos, u, v);
+ CubitVector right_normal = right_common_face->normal_at(discard_pos, NULL, &u, &v);
+ double right_angle = right_normal.vector_angle(discard_to_keep, right_vec);
+
+ // 3 valency case:
+ // We only need to partition one of the curves (left or right) and
+ // the corresponding surface.
+ if(ref_edges_on_discard_vertex.size() == 3)
+ {
+ int use_left = 0;
+ // We can use either adjacent curve.
+ if(left_ok && right_ok)
+ {
+ // Choose the side with the smaller angle as this will in general
+ // give better angles for doing the partitioning on the surface.
+ CompositeSurface *cs_left = dynamic_cast<CompositeSurface*>(left_common_face->get_surface_ptr());
+ CompositeSurface *cs_right = dynamic_cast<CompositeSurface*>(right_common_face->get_surface_ptr());
+ if(!cs_left && cs_right)
+ use_left = 1;
+ else if(cs_left && !cs_right)
+ use_left = 0;
+ else
+ {
+ if(cs_left && cs_right)
+ {
+ int edge_on_ignored_left=0, edge_on_ignored_right=0;
+ DLIList<Surface*> srfs;
+ cs_left->get_ignored_surfs(srfs);
+ int g;
+ for(g=srfs.size(); g>0 && !edge_on_ignored_left; g--)
+ {
+ Surface *srf = srfs.get_and_step();
+ DLIList<Curve*> crvs;
+ srf->curves(crvs);
+ if(crvs.is_in_list(edge_to_collapse->get_curve_ptr()))
+ edge_on_ignored_left = 1;
+ }
+ srfs.clean_out();
+ cs_right->get_ignored_surfs(srfs);
+ for(g=srfs.size(); g>0 && !edge_on_ignored_right; g--)
+ {
+ Surface *srf = srfs.get_and_step();
+ DLIList<Curve*> crvs;
+ srf->curves(crvs);
+ if(crvs.is_in_list(edge_to_collapse->get_curve_ptr()))
+ edge_on_ignored_right = 1;
+ }
+ if(edge_on_ignored_left && !edge_on_ignored_right)
+ use_left = 0;
+ else if(!edge_on_ignored_left && edge_on_ignored_right)
+ use_left = 1;
+ else
+ {
+ if(left_angle < right_angle)
+ use_left = 1;
+ }
+ }
+ else
+ {
+ if(left_angle < right_angle)
+ use_left = 1;
+ }
+ }
+ }
+ else if(left_ok)
+ use_left = 1;
+
+ if(use_left)
+ {
+ curves_to_partition.append(left_edge);
+ surfaces_to_partition.append(left_common_face);
+ angles.append(left_angle);
+ partition_positions.append(position_on_left_curve);
+ arc_lengths.append(arc_length);
+
+ // These vectors will be used in calculating a bisector direction
+ // below if necessary.
+ keep_vecs.append(-discard_to_keep);
+ partition_curve_vecs.append(left_vec);
+ }
+ else
+ {
+ curves_to_partition.append(right_edge);
+ surfaces_to_partition.append(right_common_face);
+ angles.append(right_angle);
+ partition_positions.append(position_on_right_curve);
+ arc_lengths.append(arc_length);
+
+ // These vectors will be used in calculating a bisector direction
+ // below if necessary.
+ keep_vecs.append(discard_to_keep);
+ partition_curve_vecs.append(-right_vec);
+ }
+ }
+ else if(ref_edges_on_discard_vertex.size() == 4)
+ {
+ // We have to partition both left and right curves so make
+ // sure we can.
+ if(!left_ok || !right_ok)
+ {
+ PRINT_ERROR("One of the curves adjacent to the collapse curve is not long enough for the collapse operation.\n");
+ result = CUBIT_FAILURE;
+ finished = 1;
+ }
+ else
+ {
+ // Both curves (and surfaces) adjacent to the collapse curve (left and right)
+ // will need to be partitioned so add them to the lists.
+
+ curves_to_partition.append(left_edge);
+ curves_to_partition.append(right_edge);
+ surfaces_to_partition.append(left_common_face);
+ surfaces_to_partition.append(right_common_face);
+ angles.append(left_angle);
+ angles.append(right_angle);
+ keep_vecs.append(-discard_to_keep);
+ keep_vecs.append(discard_to_keep);
+ partition_curve_vecs.append(left_vec);
+ partition_curve_vecs.append(-right_vec);
+ partition_positions.append(position_on_left_curve);
+ partition_positions.append(position_on_right_curve);
+ arc_lengths.append(arc_length);
+ arc_lengths.append(arc_length);
+ }
+ }
+ else
+ {
+ PRINT_ERROR("Currently can only collapse curves with 3 or 4 valency vertices.\n");
+ result = CUBIT_FAILURE;
+ finished = 1;
+ }
+ }
+ }
+
+ if(!finished)
+ {
+ int num_reps = curves_to_partition.size();
+ curves_to_partition.reset();
+ surfaces_to_partition.reset();
+ for(int n=0; n<num_reps && !finished; ++n)
+ {
+ RefEdge *side_edge = curves_to_partition.get_and_step();
+ RefFace *side_face = surfaces_to_partition.get_and_step();
+
+ // Now we need to find the face on the other side of the edge.
+ // Because there may be edges on the boundaries of merged surfaces
+ // we want to find the
+ // face on the left/right edge that isn't the face shared by
+ // the collapse edge and isn't nonmanifold.
+ DLIList<CoEdge*> side_edge_coedges;
+ side_edge->co_edges(side_edge_coedges);
+ DLIList<RefFace*> possible_adj_faces;
+
+ // First loop through and get all of the potential faces.
+ for(int r=side_edge_coedges.size(); r--;)
+ {
+ CoEdge *cur_coedge = side_edge_coedges.get_and_step();
+ if(cur_coedge &&
+ cur_coedge->get_loop_ptr() &&
+ cur_coedge->get_loop_ptr()->get_ref_face_ptr())
+ {
+ RefFace *cur_ref_face = cur_coedge->get_loop_ptr()->get_ref_face_ptr();
+ if(cur_ref_face != side_face)
+ {
+ DLIList<CoFace*> coface_list;
+ cur_ref_face->co_faces(coface_list);
+
+ // Along with checking for whether the face is manifold we need
+ // to check if it belongs to the same volume as the side face.
+ // We have to check this because we can't composite faces
+ // from different volumes and these faces will be involved in
+ // a composite below.
+ if(coface_list.size() == 1 &&
+ side_face->ref_volume() == cur_ref_face->ref_volume())
+ {
+ possible_adj_faces.append(cur_ref_face);
+ }
+ }
+ }
+ }
+
+ // If we ended up with more than one face in the list it isn't clear
+ // what we should do so bail out.
+ if(possible_adj_faces.size() != 1)
+ {
+ PRINT_ERROR("Couldn't figure out how to perform the collapse curve with the current topology.\n");
+ result = CUBIT_FAILURE;
+ finished = 1;
+ }
+ else
+ {
+ adjacent_surfaces.append(possible_adj_faces.get());
+ }
+ }
+ }
+
+ if(!finished)
+ {
+ // At this point we should know which curves and surfaces we need
+ // to partition.
+
+ int num_reps = curves_to_partition.size();
+ curves_to_partition.reset();
+ surfaces_to_partition.reset();
+ adjacent_surfaces.reset();
+ angles.reset();
+ keep_vecs.reset();
+ partition_curve_vecs.reset();
+ partition_positions.reset();
+ arc_lengths.reset();
+
+ for(int i=0; i<num_reps && !finished; ++i)
+ {
+ RefEdge *curve_to_partition = curves_to_partition.get_and_step();
+ RefFace *surface_to_partition = surfaces_to_partition.get_and_step();
+
+ // Sanity check to make sure a previous operation has not
+ // destroyed the current face.
+ DLIList<RefFace*> body_faces;
+ the_body->ref_faces(body_faces);
+ if(body_faces.is_in_list(surface_to_partition))
+ {
+ // As we process each curve remove it from the list so that
+ // at the end we can take the last one in the list and composite
+ // it with the curve being collapsed.
+ ref_edges_on_discard_vertex.remove(curve_to_partition);
+
+ CubitVector position_on_curve = partition_positions.get_and_step();
+ DLIList<CubitVector*> positions;
+
+ // Add the point on the curve we just partitioned. The other
+ // point we normally need to add is the keep_vertex. However,
+ // if the angle between the collapse curve and the curve we
+ // just partitioned dictates that we need to introduce more points
+ // (this would be cases where the angle is large and just partitioning the
+ // surface with one curve--two points--would result in a very skinny
+ // surface) we need to add them before adding the keep_vertex. Therefore, check
+ // that now and add the extra points if needed.
+ positions.append(new CubitVector(position_on_curve));
+
+ double cur_angle = angles.get_and_step();
+ arc_length = arc_lengths.get_and_step();
+
+ // These vectors are only used in the block below if we need to
+ // add extra points but we need to always retrieve them from the lists
+ // so that the pointer in the list stays in sync with the "for" loop.
+ CubitVector keep_vec = keep_vecs.get_and_step();
+ CubitVector partition_vec = partition_curve_vecs.get_and_step();
+
+ // Greater than 3*PI/2--add 3 interior points. Two of these
+ // points will be generated by projecting from the discard vertex
+ // into the surface normal to the vector from the discard vertex
+ // to the keep point and new partition point respectively. The third
+ // point will be obtained by projecting from the discard point in the
+ // direction of the bisector angle of the two previous projections.
+ if(cur_angle > 4.71)
+ {
+ // Get the u,v position of the discard vertex on this surface.
+ surface_to_partition->u_v_from_position(discard_pos, u, v);
+
+ // Get the normal at the discard vertex.
+ CubitVector normal = surface_to_partition->normal_at(discard_pos, NULL, &u, &v);
+ normal.normalize();
+
+ // We need to calculate a bisector direction between the
+ // collape edge and the edge we just partitioned. We will do
+ // this using the face normal at the discard vertex and the vectors
+ // we calculated previously with the partition points. Cross
+ // the face normal into the the direction vectors at the
+ // discard and partition points to get two vectors pointing
+ // into the face and then average those two to get the
+ // bisector direction. This is all approximate but should
+ // be sufficient for locating another point for partitioning
+ // the surface.
+
+ // I am not normalizing the result here because they should
+ // be roughly the same length and it shouldn't affect
+ // the average too much.
+ CubitVector vec1 = normal * partition_vec;
+ CubitVector vec2 = normal * keep_vec;
+
+ // Get the bisector direction.
+ CubitVector bisector_dir = vec1 + vec2;
+ bisector_dir.normalize();
+
+ // Now normalise these because they will be used to
+ // project two of the new interior points.
+ vec1.normalize();
+ vec2.normalize();
+
+ CubitVector new_pos1 = discard_pos + (arc_length*vec1);
+ CubitVector mid_pos = discard_pos + (arc_length * bisector_dir);
+ CubitVector new_pos2 = discard_pos + (arc_length*vec2);
+
+ // Use the u,v from the discard vertex because it is fairly
+ // close to the new position and will at least provide a
+ // meaningful starting point.
+ double save_u = u, save_v = v;
+ surface_to_partition->move_to_surface(new_pos1, &u, &v);
+ u = save_u; v = save_v;
+ surface_to_partition->move_to_surface(mid_pos, &u, &v);
+ u = save_u; v = save_v;
+ surface_to_partition->move_to_surface(new_pos2, &u, &v);
+
+ // Add the new position to the list of partition points.
+ positions.append(new CubitVector(new_pos1));
+ positions.append(new CubitVector(mid_pos));
+ positions.append(new CubitVector(new_pos2));
+ }
+ // Greater than 3*PI/4 and less than 3*PI/2--add one interior point
+ else if(cur_angle > 2.4)
+ {
+ CubitVector third_pt;
+
+ // Get the u,v position of the discard vertex on this surface.
+ surface_to_partition->u_v_from_position(discard_pos, u, v);
+
+ // Get the normal at the discard vertex.
+ CubitVector normal = surface_to_partition->normal_at(discard_pos, NULL, &u, &v);
+ normal.normalize();
+
+ // We need to calculate a bisector direction between the
+ // collape edge and the edge we just partitioned. We will do
+ // this using the face normal at the discard vertex and the vectors
+ // we calculated previously with the partition points. Cross
+ // the face normal into the the direction vectors at the
+ // discard and partition points to get two vectors pointing
+ // into the face and then average those two to get the
+ // bisector direction. This is all approximate but should
+ // be sufficient for locating another point for partitioning
+ // the surface.
+
+ // I am not normalizing the result here because they should
+ // be roughly the same length and it shouldn't affect
+ // the average too much.
+ CubitVector vec1 = normal * keep_vec;
+ CubitVector vec2 = normal * partition_vec;
+
+ // Get the bisector direction.
+ CubitVector bisector_dir = vec1 + vec2;
+ bisector_dir.normalize();
+
+ // Project from the discard vertex in the direction of the
+ // bisector direction to get a new point for partitioning
+ // the surface.
+ CubitVector new_pos = discard_pos + (arc_length * bisector_dir);
+
+ // Use the u,v from the discard vertex because it is fairly
+ // close to the new position and will at least provide a
+ // meaningful starting point.
+ surface_to_partition->move_to_surface(new_pos, &u, &v);
+
+ // Add the new position to the list of partition points.
+ positions.append(new CubitVector(new_pos));
+ }
+
+ // Finally, add the keep_vertex to the list.
+ positions.append(new CubitVector(keep_vertex->get_point_ptr()->coordinates()));
+
+ DLIList<RefEdge*> new_edges;
+ DLIList<DLIList<CubitVector*>*> vec_lists;
+ DLIList<CubitVector*> *vec_list = new DLIList<CubitVector*>;
+ positions.reset();
+ for(int m=positions.size(); m--;)
+ vec_list->append( new CubitVector( *positions.get_and_step() ) );
+ vec_lists.append( vec_list );
+
+ if(!SplitCompositeSurfaceTool::instance()->split_surface(surface_to_partition,
+ positions, vec_lists ))
+ {
+ finished = 1;
+ result = CUBIT_FAILURE;
+ }
+
+ while( vec_lists.size() )
+ {
+ DLIList<CubitVector*> *vec_list = vec_lists.pop();
+ while( vec_list->size() ) delete vec_list->pop();
+ delete vec_list;
+ }
+
+ delete positions.get_and_step();
+ delete positions.get_and_step();
+
+ if(cur_angle > 4.71)
+ {
+ delete positions.get_and_step();
+ delete positions.get_and_step();
+ delete positions.get_and_step();
+ }
+ else if(cur_angle > 2.4)
+ {
+ delete positions.get();
+ }
+
+ if(!finished)
+ {
+ RefFace *new_small_face = NULL;
+ DLIList<RefEdge*> keep_edges, discard_edges;
+ DLIList<RefFace*> faces_on_collapse_edge;
+ keep_vertex->ref_edges(keep_edges);
+ discard_vertex->ref_edges(discard_edges);
+ keep_edges.intersect_unordered(discard_edges);
+ if(keep_edges.size() != 1)
+ {
+ finished = 1;
+ result = CUBIT_FAILURE;
+ }
+ else
+ {
+ edge_to_collapse = keep_edges.get();
+ edge_to_collapse->ref_faces(faces_on_collapse_edge);
+ for(int y=faces_on_collapse_edge.size(); y && !new_small_face; y--)
+ {
+ RefFace *cur_face = faces_on_collapse_edge.get_and_step();
+ DLIList<RefVertex*> verts_in_face;
+ cur_face->ref_vertices(verts_in_face);
+ for(int p=verts_in_face.size(); p && !new_small_face; p--)
+ {
+ RefVertex *cur_vert = verts_in_face.get_and_step();
+ if(position_on_curve.about_equal(cur_vert->coordinates()))
+ new_small_face = cur_face;
+ }
+ }
+ }
+
+ if(!new_small_face || new_small_face == surface_to_partition)
+ {
+ PRINT_ERROR("Failed to do the split surface operation of the collapse curve.\n");
+ result = CUBIT_FAILURE;
+ finished = 1;
+ }
+ else
+ {
+ RefVertex *vert_at_split_pos;
+ DLIList<RefEdge*> new_face_edges;
+ new_small_face->ref_edges(new_face_edges);
+ if(new_face_edges.is_in_list(curve_to_partition))
+ {
+ // The split went right through one of the vertices of the
+ // curve_to_partition so just set the close edge to be
+ // this edge and the far edge to be NULL.
+ close_edge = curve_to_partition;
+ far_edge = NULL;
+ vert_at_split_pos = close_edge->other_vertex(discard_vertex);
+ }
+ else
+ {
+ close_edge = edge_to_collapse->get_other_curve(discard_vertex, new_small_face);
+ RefVertex *tmp_vert = close_edge->other_vertex(discard_vertex);
+ if(tmp_vert)
+ {
+ RefEdge *tmp_edge = close_edge->get_other_curve(tmp_vert, new_small_face);
+ if(tmp_edge)
+ {
+ RefFace *other_face = tmp_edge->other_face(new_small_face);
+ if(other_face)
+ {
+ far_edge = tmp_edge->get_other_curve(tmp_vert, other_face);
+ vert_at_split_pos = tmp_vert;
+ // If close_edge and far_edge are the same it may mean
+ // that the split really didn't do much other than maybe
+ // imprint one point on an edge so bail out.
+ if(far_edge == close_edge)
+ {
+ PRINT_ERROR("Failed to do the split surface operation of the collapse curve.\n");
+ result = CUBIT_FAILURE;
+ finished = 1;
+ }
+ }
+ else
+ {
+ result = CUBIT_FAILURE;
+ finished = 1;
+ }
+ }
+ else
+ {
+ result = CUBIT_FAILURE;
+ finished = 1;
+ }
+ }
+ else
+ {
+ finished = 1;
+ result = CUBIT_FAILURE;
+ }
+ }
+
+ if(!finished)
+ {
+ RefEdge *cur_edge = close_edge;
+ RefVertex *cur_vert = vert_at_split_pos;
+ while(cur_vert != keep_vertex)
+ {
+ cur_edge = cur_edge->get_other_curve(cur_vert, new_small_face);
+ cur_vert = cur_edge->other_vertex(cur_vert);
+ new_edges.append(cur_edge);
+ }
+
+ DLIList<RefFace*> result_faces;
+ DLIList<RefFace*> faces_to_composite;
+
+ // Used below if "ignore" keyword was specified.
+ int new_small_face_id = new_small_face->id();
+
+ faces_to_composite.append(new_small_face);
+ faces_to_composite.append(close_edge->other_face(new_small_face));
+
+ RefFace *new_comp_face = CompositeTool::instance()->composite(faces_to_composite);
+
+ CompositeSurface* csurf = NULL;
+
+ if(new_comp_face)
+ {
+ csurf = dynamic_cast<CompositeSurface*>(new_comp_face->get_surface_ptr());
+ }
+
+ if(!new_comp_face || !csurf)
+ {
+ PRINT_ERROR("Failed to do the composite surface operation of the collapse curve.\n");
+ result = CUBIT_FAILURE;
+ finished = 1;
+ }
+ else
+ {
+ if(ignore_surfaces)
+ {
+ csurf->ignore_surface(new_small_face_id);
+ }
+
+ if(far_edge)
+ {
+ for(int k=new_edges.size(); k--;)
+ {
+ edges_to_composite.append(new_edges.get_and_step());
+ }
+ edges_to_composite.append(far_edge);
+
+ if(edges_to_composite.size() > 1)
+ {
+ CompositeTool::instance()->composite(edges_to_composite);
+ }
+ }
+
+ edges_to_composite.clean_out();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if(!finished)
+ {
+ ref_edges_on_discard_vertex.clean_out();
+ discard_vertex->ref_edges(ref_edges_on_discard_vertex);
+ ref_edges_on_discard_vertex.remove(edge_to_collapse);
+
+ // Now there should only be one edge in the ref_edges_on_discard_vertex
+ // list. It should be the edge that hasn't had any modifications
+ // done to it. We finally want to composite it with the edge
+ // being collapsed.
+ if(ref_edges_on_discard_vertex.size() != 1)
+ {
+ PRINT_ERROR("Wasn't able to complete collapse operation.\n");
+ result = CUBIT_FAILURE;
+ finished = 1;
+ }
+ else
+ {
+ edges_to_composite.append(ref_edges_on_discard_vertex.get());
+ edges_to_composite.append(edge_to_collapse);
+ CompositeTool::instance()->composite(edges_to_composite);
+ }
+ }
+ }
+
+ CubitUndo::set_undo_enabled(undo_state);
+
return result;
}
Modified: cgm/branches/cubit/geom/virtual/CollapseCurveTool.hpp
===================================================================
--- cgm/branches/cubit/geom/virtual/CollapseCurveTool.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/CollapseCurveTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -20,8 +20,13 @@
CubitStatus collapse_curve(DLIList <RefEdge*> ref_edge_list,
DLIList<RefVertex*> ref_vertex_list,
- int ignore_surfaces);
+ int ignore_surfaces,
+ double *small_curve_size = NULL);
+ CubitStatus collapse_curve_only_virtual(DLIList <RefEdge*> ref_edge_list,
+ DLIList<RefVertex*> ref_vertex_list,
+ int ignore_surfaces,
+ double *small_curve_size = NULL);
private:
CollapseCurveTool();
// Constructor
Modified: cgm/branches/cubit/geom/virtual/CompSurfFacets.cpp
===================================================================
--- cgm/branches/cubit/geom/virtual/CompSurfFacets.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/CompSurfFacets.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -20,7 +20,6 @@
CubitStatus CompSurfFacets::setup( const SurfPtrList& surface_data )
{
GMem gmem;
- int num_points, num_facets, num_triangles;
// Set the size of this array of flags.
ignoreFlags.resize(surface_data.size());
@@ -31,37 +30,37 @@
Surface* surface = surface_data[index];
CubitStatus result = surface->get_geometry_query_engine()
- ->get_graphics( surface, num_triangles, num_points, num_facets, &gmem );
+ ->get_graphics( surface, &gmem );
if ( !result )
return CUBIT_FAILURE;
int* f_itor = gmem.facet_list();
- int* f_end = f_itor + num_facets;
+ int* f_end = f_itor + gmem.fListCount;
int tri_count = 0;
+ bool non_tri = false;
while ( f_itor < f_end )
{
// If facet is not a triangle, it will be split into
// triangles later. Update tri_count accordingly.
int pt_count = *f_itor;
+ if(pt_count != 3)
+ non_tri = true;
tri_count += pt_count - 2;
f_itor += (pt_count + 1);
}
-
- if (tri_count != num_triangles)
+
+ if(non_tri)
PRINT_WARNING("Non-triangular facets encountered in surface graphics.\n");
- assert(gmem.fListCount == num_facets);
- assert(gmem.pointListCount == num_points);
-
int offset = pointList.size();
- pointList.resize( offset + num_points );
+ pointList.resize( offset + gmem.pointListCount );
int tri_offset = triangleData.size();
triangleData.resize( tri_offset + tri_count * 4 );
PointList::iterator p_itor = pointList.begin() + offset;
GPoint* g_itor = gmem.point_list();
- GPoint* g_end = g_itor + num_points;
+ GPoint* g_end = g_itor + gmem.pointListCount;
for ( ; g_itor != g_end; ++g_itor )
{
//CubitVector vect(g_itor->x, g_itor->y, g_itor->z);
@@ -74,7 +73,7 @@
IntegerList::iterator t_itor = triangleData.begin() + tri_offset;
f_itor = gmem.facet_list();
- f_end = f_itor + num_facets;
+ f_end = f_itor + gmem.fListCount;
while ( f_itor != f_end )
{
// Copy facet into triangleData.
@@ -465,10 +464,12 @@
// Update the facet list using values from index_map.
IntegerList::iterator itor = triangleData.begin();
IntegerList::iterator end = triangleData.end();
- while( itor++ != end )
+ while( itor != end )
+ {
+ ++itor;
for( int count = 3; count--; itor++ )
*itor = index_map[*itor];
-
+ }
delete [] index_map;
pointsConsolidated = true;
}
@@ -530,10 +531,13 @@
// Use index_map to update facet list
IntegerList::iterator itor = triangleData.begin();
IntegerList::iterator end = triangleData.end();
- while (itor++ != end)
- for (int count = 3; count--; itor++)
+ while( itor != end )
+ {
+ ++itor;
+ for (int count = 3; count--; itor++)
*itor = index_map[*itor];
-
+ }
+
delete [] index_map;
pointsConsolidated = true;
}
Modified: cgm/branches/cubit/geom/virtual/CompositeEngine.cpp
===================================================================
--- cgm/branches/cubit/geom/virtual/CompositeEngine.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/CompositeEngine.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -6,6 +6,7 @@
#include "DLIList.hpp"
#include "TDUniqueId.hpp"
#include "CubitTransformMatrix.hpp"
+#include "RTree.hpp"
#include "CompositePoint.hpp"
#include "CompositeCurve.hpp"
@@ -15,6 +16,7 @@
#include "CompositeShell.hpp"
#include "CompositeLump.hpp"
#include "CompositeBody.hpp"
+#include "GfxPreview.hpp"
#include "PartitionPoint.hpp"
#include "SegmentedCurve.hpp"
@@ -23,6 +25,7 @@
#include "VGLoopTool.hpp"
#include "Body.hpp"
+#include "LumpSM.hpp"
#include "GeometryQueryTool.hpp"
@@ -32,11 +35,31 @@
CompositeCurve,
CompositePoint> CompLoopTool;
-CompositeEngine::~CompositeEngine() {}
+CompositeEngine* CompositeEngine::instance_ = NULL;
+
+CompositeEngine::~CompositeEngine()
+{
+ GeometryQueryTool::instance()->unregister_intermediate_engine(this);
+}
+
+void CompositeEngine::delete_instance()
+{
+ if( NULL != instance_ )
+ {
+ delete instance_;
+ instance_ = NULL;
+ }
+}
+
CompositeEngine& CompositeEngine::instance()
{
- static CompositeEngine* instance_ = new CompositeEngine();
+ if( instance_ == NULL )
+ {
+ instance_ = new CompositeEngine();
+ assert( instance != NULL );
+ }
+
return *instance_;
}
@@ -111,17 +134,76 @@
}
}
-// This function pushes specified named attributes onto all curves
-// and vertices.
void CompositeEngine::push_imprint_attributes_before_modify
- ( DLIList<BodySM*> &bodies )
+ ( DLIList<BodySM*> &bodies)
{
- int k, m, q, w, g, b, s, t;
- CubitString name("IMPRINT_PREEXISTING");
+}
+
+void CompositeEngine::push_named_attributes_to_curves_and_points
+// ( DLIList<BodySM*> &bodies, char *name_in)
+ ( DLIList<TopologyBridge*> &in_list, const char *name_in)
+{
+ int i/*, k, m, q, w, g, b, s, t*/;
+ CubitString name(name_in);
DLIList<CubitString*> string_list;
string_list.append( &name );
- CubitSimpleAttrib geom_attrib( &string_list, 0, 0 );
+ CubitSimpleAttrib attrib( &string_list, 0, 0 );
+ for(i=in_list.size(); i>0; i--)
+ {
+ TopologyBridge *tb = in_list.get_and_step();
+ if(dynamic_cast<BodySM*>(tb))
+ {
+ DLIList<TopologyBridge*> lumps;
+ tb->get_children_virt(lumps);
+ push_named_attributes_to_curves_and_points(lumps, name_in);
+ }
+ else if(dynamic_cast<Lump*>(tb))
+ {
+ DLIList<TopologyBridge*> shells;
+ tb->get_children_virt(shells);
+ push_named_attributes_to_curves_and_points(shells, name_in);
+ }
+ else if(dynamic_cast<ShellSM*>(tb))
+ {
+ DLIList<TopologyBridge*> surfs;
+ tb->get_children_virt(surfs);
+ push_named_attributes_to_curves_and_points(surfs, name_in);
+ }
+ else if(dynamic_cast<Surface*>(tb))
+ {
+ DLIList<TopologyBridge*> loops;
+ tb->get_children_virt(loops);
+ push_named_attributes_to_curves_and_points(loops, name_in);
+ }
+ else if(dynamic_cast<LoopSM*>(tb))
+ {
+ DLIList<TopologyBridge*> coedges;
+ tb->get_children_virt(coedges);
+ push_named_attributes_to_curves_and_points(coedges, name_in);
+ }
+ else if(dynamic_cast<CoEdgeSM*>(tb))
+ {
+ DLIList<TopologyBridge*> curves;
+ tb->get_children_virt(curves);
+ push_named_attributes_to_curves_and_points(curves, name_in);
+ }
+ else if(dynamic_cast<Curve*>(tb))
+ {
+ append_attrib( tb, &attrib );
+ DLIList<TopologyBridge*> points;
+ tb->get_children_virt(points);
+ push_named_attributes_to_curves_and_points(points, name_in);
+ }
+ else if(dynamic_cast<Point*>(tb))
+ {
+ append_attrib( tb, &attrib );
+ }
+ }
+
+/*
+
+
DLIList<TopologyBridge*> top_bridges;
CAST_LIST_TO_PARENT(bodies, top_bridges);
for(k=top_bridges.size(); k--;)
@@ -157,19 +239,13 @@
for(s=curves.size(); s--;)
{
TopologyBridge *cur_curve = curves.get_and_step();
- DLIList<CubitSimpleAttrib*> list;
- cur_curve->get_simple_attribute("COMPOSITE_GEOM",list);
- if(list.size() == 0)
- append_attrib( cur_curve, &geom_attrib );
+ append_attrib( cur_curve, &attrib );
DLIList<TopologyBridge*> pts;
cur_curve->get_children_virt(pts);
for(t=pts.size(); t--;)
{
TopologyBridge *cur_pt = pts.get_and_step();
- list.clean_out();
- cur_pt->get_simple_attribute("COMPOSITE_GEOM",list);
- if(list.size() == 0)
- append_attrib( cur_pt, &geom_attrib );
+ append_attrib( cur_pt, &attrib );
}
}
}
@@ -178,243 +254,464 @@
}
}
}
+ */
}
+void CompositeEngine::get_all_curves_and_points(DLIList<TopologyBridge*> &tb_list,
+ DLIList<Curve*> &curves,
+ DLIList<Point*> &points)
+{
+ int i;
+ Curve *crv;
+ Point *pt;
+ for(i=tb_list.size(); i>0; i--)
+ {
+ TopologyBridge *tb = tb_list.get_and_step();
+ if(dynamic_cast<BodySM*>(tb))
+ {
+ DLIList<TopologyBridge*> lumps;
+ tb->get_children_virt(lumps);
+ get_all_curves_and_points(lumps, curves, points);
+ }
+ else if(dynamic_cast<Lump*>(tb))
+ {
+ DLIList<TopologyBridge*> shells;
+ tb->get_children_virt(shells);
+ get_all_curves_and_points(shells, curves, points);
+ }
+ else if(dynamic_cast<ShellSM*>(tb))
+ {
+ DLIList<TopologyBridge*> surfs;
+ tb->get_children_virt(surfs);
+ get_all_curves_and_points(surfs, curves, points);
+ }
+ else if(dynamic_cast<Surface*>(tb))
+ {
+ DLIList<TopologyBridge*> loops;
+ tb->get_children_virt(loops);
+ get_all_curves_and_points(loops, curves, points);
+ }
+ else if(dynamic_cast<LoopSM*>(tb))
+ {
+ DLIList<TopologyBridge*> coedges;
+ tb->get_children_virt(coedges);
+ get_all_curves_and_points(coedges, curves, points);
+ }
+ else if(dynamic_cast<CoEdgeSM*>(tb))
+ {
+ DLIList<TopologyBridge*> tmp_curves;
+ tb->get_children_virt(tmp_curves);
+ get_all_curves_and_points(tmp_curves, curves, points);
+ }
+ else if((crv = dynamic_cast<Curve*>(tb)))
+ {
+ curves.append(crv);
+ DLIList<TopologyBridge*> tmp_points;
+ tb->get_children_virt(tmp_points);
+ get_all_curves_and_points(tmp_points, curves, points);
+ }
+ else if((pt = dynamic_cast<Point*>(tb)))
+ {
+ points.append(pt);
+ }
+ }
+}
+
// Function to apply/remove COMPOSITE_GEOM attributes as necessary based
// on imprinting.
void CompositeEngine::attribute_after_imprinting( DLIList<TopologyBridge*> &new_tbs,
DLIList<TopologyBridge*> &att_tbs,
- DLIList<BodySM*> &new_sms,
+ DLIList<TopologyBridge*> &tb_list,
DLIList<Body*> &old_bodies)
{
- DLIList<TopologyBridge*> old_bridges(old_bodies.size());
- DLIList<TopologyBridge*> new_bridges(new_sms.size());
- DLIList<TopologyBridge*> all_bodies;
- CAST_LIST(new_sms, new_bridges, TopologyBridge);
-
- all_bodies = new_bridges;
- int k, m, q, w, g, b, s, t;
+ DLIList<TopologyBridge*> all_bridges = tb_list;
+ int i, j, k;
for(k = old_bodies.size(); k>0; k--)
{
Body *body = old_bodies.get_and_step();
TopologyBridge *tb = body->bridge_manager()->topology_bridge();
if(tb)
- {
- old_bridges.append(tb);
- all_bodies.append_unique(tb);
- }
+ all_bridges.append_unique(tb);
}
- DLIList<DLIList<TopologyBridge*>*> lists_of_curves;
- DLIList<DLIList<TopologyBridge*>*> lists_of_points;
+ DLIList<Curve*> all_curves;
+ DLIList<Point*> all_points;
+ get_all_curves_and_points(all_bridges, all_curves, all_points);
+ all_curves.uniquify_ordered();
+ all_points.uniquify_ordered();
- // Get lists of curves and points for each body in the
- // list all_bodies.
- all_bodies.reset();
- for(k=all_bodies.size(); k--;)
+ double geom_factor = GeometryQueryTool::get_geometry_factor();
+ double merge_tol = geom_factor*GEOMETRY_RESABS;
+
+ AbstractTree<Point*> *pt_tree = new RTree<Point*>(merge_tol);
+ AbstractTree<Curve*> *crv_tree = new RTree<Curve*>(merge_tol);
+
+ DLIList<Curve*> all_curves_with_composite_att;
+ DLIList<Point*> all_points_with_composite_att;
+ for(k=all_curves.size(); k>0; k--)
{
- DLIList<TopologyBridge*> *new_curve_list = new DLIList<TopologyBridge*>;
- DLIList<TopologyBridge*> *new_point_list = new DLIList<TopologyBridge*>;
- lists_of_curves.append(new_curve_list);
- lists_of_points.append(new_point_list);
- TopologyBridge *cur_body = all_bodies.get_and_step();
- DLIList<TopologyBridge*> lumps;
- cur_body->get_children_virt(lumps);
- for(m=lumps.size(); m--;)
+ Curve *cur_curve = all_curves.get_and_step();
+ crv_tree->add(cur_curve);
+ DLIList<CubitSimpleAttrib*> list;
+ cur_curve->get_simple_attribute("COMPOSITE_GEOM",list);
+ if(list.size() > 0)
+ all_curves_with_composite_att.append(cur_curve);
+ }
+ for(k=all_points.size(); k>0; k--)
+ {
+ Point *cur_point = all_points.get_and_step();
+ pt_tree->add(cur_point);
+ DLIList<CubitSimpleAttrib*> list;
+ cur_point->get_simple_attribute("COMPOSITE_GEOM",list);
+ if(list.size() > 0)
+ all_points_with_composite_att.append(cur_point);
+ }
+
+ DLIList<CubitSimpleAttrib*> list;
+ while(all_points_with_composite_att.size())
+ {
+ DLIList<Point*> other_pts;
+ DLIList<BodySM*> other_bodies;
+ DLIList<double> other_distances;
+
+ // For the given pt we will look for "coincident" pts (those within merge tol)
+ // and categorize them as either having or not having a composite att.
+ Point *cur_pt = all_points_with_composite_att.extract();
+ pt_tree->remove(cur_pt);
+
+ BodySM *cur_body = cur_pt->bodysm();
+ DLIList<Point*> coincident_pts_with_composite_att, coincident_pts_without_composite_att;
+ DLIList<Point*> close_pts;
+ CubitBox bbox = cur_pt->bounding_box();
+ pt_tree->find(bbox, close_pts);
+
+ // Only keep the closest pt from each body.
+ for(j=close_pts.size(); j>0; j--)
{
- TopologyBridge *cur_lump = lumps.get_and_step();
- DLIList<TopologyBridge*> shells;
- cur_lump->get_children_virt(shells);
- for(q=shells.size(); q--;)
+ Point *other_pt = close_pts.get_and_step();
+ BodySM *other_body = other_pt->bodysm();
+ // Don't keep anything that is in the same body as the current pt.
+ if(other_body != cur_body)
{
- TopologyBridge *cur_shell = shells.get_and_step();
- DLIList<TopologyBridge*> surfaces;
- cur_shell->get_children_virt(surfaces);
- for(w=surfaces.size(); w--;)
+ double cur_dist_sq = cur_pt->coordinates().distance_between_squared(other_pt->coordinates());
+ if(other_bodies.move_to(other_body))
{
- TopologyBridge *cur_surface = surfaces.get_and_step();
- DLIList<TopologyBridge*> loops;
- cur_surface->get_children_virt(loops);
- for(g=loops.size(); g--;)
+ int list_index = other_bodies.get_index();
+ other_distances.reset();
+ other_distances.step(list_index);
+ double prev_dist_sq = other_distances.get();
+ if(cur_dist_sq < prev_dist_sq)
{
- TopologyBridge *cur_loop = loops.get_and_step();
- DLIList<TopologyBridge*> coedges;
- cur_loop->get_children_virt(coedges);
- for(b=coedges.size(); b--;)
+ other_distances.change_to(cur_dist_sq);
+ other_pts.reset();
+ other_pts.step(list_index);
+ other_pts.change_to(other_pt);
+ }
+ }
+ else
+ {
+ other_bodies.append(other_body);
+ other_pts.append(other_pt);
+ other_distances.append(cur_dist_sq);
+ }
+ }
+ }
+ // Make sure our current pt is added to a list.
+ coincident_pts_with_composite_att.append(cur_pt);
+ // Classify the coincident pts as either having or not
+ // having a composite att.
+ for(j=other_pts.size(); j>0; j--)
+ {
+ Point *pt = other_pts.get_and_step();
+ list.clean_out();
+ pt->get_simple_attribute("COMPOSITE_GEOM",list);
+ if(list.size() > 0)
+ {
+ coincident_pts_with_composite_att.append(pt);
+ if(all_points_with_composite_att.move_to(pt))
+ all_points_with_composite_att.extract();
+ }
+ else
+ coincident_pts_without_composite_att.append(pt);
+ }
+
+ // If we have found at least one other pt coincident with the current point...
+ if(coincident_pts_with_composite_att.size() > 1 ||
+ coincident_pts_without_composite_att.size() > 0)
+ {
+ // If there is at least one pt without a composite att that is an imprinter we
+ // will remove all composite atts from coincident pts
+ bool found = false;
+ for(j=coincident_pts_without_composite_att.size(); j>0 && !found; j--)
+ {
+ Point *tmp_pt = coincident_pts_without_composite_att.get_and_step();
+ list.clean_out();
+ tmp_pt->get_simple_attribute("IMPRINTER",list);
+ if(list.size() > 0)
+ found = true;
+ }
+ if(found)
+ {
+ // Remove all composite atts.
+ for(j=coincident_pts_with_composite_att.size(); j>0; j--)
+ {
+ Point *tmp_pt = coincident_pts_with_composite_att.get_and_step();
+ list.clean_out();
+ tmp_pt->get_simple_attribute("COMPOSITE_GEOM",list);
+ if(list.size() > 0)
+ tmp_pt->remove_simple_attribute_virt(list.get());
+ }
+ }
+ else
+ {
+ // There were no imprinter points that didn't have composite atts.
+ // Next we will look for imprinter points with composite atts. These
+ // may have resulted in a new point. If there is a non composite att
+ // point that doesn't have an ORIGINAL att we will know it is new
+ // from the imprinter composite att point and we know to put a composite
+ // att on it.
+ found = false;
+ for(j=coincident_pts_with_composite_att.size(); j>0 && !found; j--)
+ {
+ Point *tmp_pt = coincident_pts_with_composite_att.get_and_step();
+ list.clean_out();
+ tmp_pt->get_simple_attribute("IMPRINTER",list);
+ if(list.size() > 0)
+ found = true;
+ }
+ if(found)
+ {
+ // Now put a composite att on any point that doesn't have one.
+ for(j=coincident_pts_without_composite_att.size(); j>0; j--)
+ {
+ Point *tmp_pt = coincident_pts_without_composite_att.get_and_step();
+ list.clean_out();
+ tmp_pt->get_simple_attribute("ORIGINAL", list);
+ if(list.size() == 0)
{
- TopologyBridge *cur_coedge = coedges.get_and_step();
- DLIList<TopologyBridge*> curves;
- cur_coedge->get_children_virt(curves);
- for(s=curves.size(); s--;)
- {
- TopologyBridge *cur_curve = curves.get_and_step();
- new_curve_list->append_unique(cur_curve);
- DLIList<TopologyBridge*> pts;
- cur_curve->get_children_virt(pts);
- for(t=pts.size(); t--;)
- {
- TopologyBridge *cur_pt = pts.get_and_step();
- new_point_list->append_unique(cur_pt);
- }
- }
+ // The point was not in the original model and therefore was created by
+ // the imprint of a pt with a composite att. We need to put a composite
+ // att on it.
+ list.clean_out();
+ coincident_pts_with_composite_att.get()->get_simple_attribute("COMPOSITE_GEOM",list);
+ tmp_pt->append_simple_attribute_virt(new CubitSimpleAttrib(list.get()));
}
}
}
}
}
+
+ for(i=coincident_pts_with_composite_att.size(); i>0; i--)
+ {
+ Point *pt = coincident_pts_with_composite_att.get_and_step();
+ list.clean_out();
+ pt->get_simple_attribute("IMPRINTER",list);
+ if(list.size() > 0)
+ pt->remove_simple_attribute_virt(list.get());
+ list.clean_out();
+ pt->get_simple_attribute("ORIGINAL",list);
+ if(list.size() > 0)
+ pt->remove_simple_attribute_virt(list.get());
+ }
+ for(i=coincident_pts_without_composite_att.size(); i>0; i--)
+ {
+ Point *pt = coincident_pts_without_composite_att.get_and_step();
+ list.clean_out();
+ pt->get_simple_attribute("IMPRINTER",list);
+ if(list.size() > 0)
+ pt->remove_simple_attribute_virt(list.get());
+ list.clean_out();
+ pt->get_simple_attribute("ORIGINAL",list);
+ if(list.size() > 0)
+ pt->remove_simple_attribute_virt(list.get());
+ }
}
+ delete pt_tree;
-
- int i, j, h;
CubitSense rel_sense;
- double geom_factor = GeometryQueryTool::get_geometry_factor();
+ while(all_curves_with_composite_att.size())
+ {
+ DLIList<Curve*> other_crvs;
+ DLIList<BodySM*> other_bodies;
+ DLIList<double> other_distances;
- // This code will look at all of the topology bridges that have
- // COMPOSITE_GEOM attributes on them and determine whether to
- // keep these attributes, remove them, or pass them on to bridges
- // on other volumes based on the expected results from the imprinting operation.
+ Curve *cur_crv = all_curves_with_composite_att.extract();
+ crv_tree->remove(cur_crv);
- // Loop twice, once for the curves and then once for the points.
- for(h=0; h<2; h++)
- {
- for(i=att_tbs.size(); i--;)
+ BodySM *cur_body = cur_crv->bodysm();
+ DLIList<Curve*> coincident_crvs_with_composite_att, coincident_crvs_without_composite_att;
+ DLIList<Curve*> close_crvs;
+ CubitBox bbox = cur_crv->bounding_box();
+ crv_tree->find(bbox, close_crvs);
+
+ for(j=close_crvs.size(); j>0; j--)
{
- TopologyBridge *att_tb = att_tbs.get_and_step();
- Curve *att_cur = dynamic_cast<Curve*>(att_tb);
- Point *att_pt = dynamic_cast<Point*>(att_tb);
- Curve *match_cur;
- Point *match_pt;
-
- // Force curves to be done first.
- if(h==0 && att_cur)
+ Curve *other_crv = close_crvs.get_and_step();
+ BodySM *other_body = other_crv->bodysm();
+ // Only consider curves from other bodies.
+ if(cur_body != other_body)
{
- match_cur = NULL;
- CubitBox att_box = att_cur->bounding_box();
-
- // First check the list of new bridges as the corresponding
- // curve will often be there.
- for(j=new_tbs.size(); !match_cur && j; j--)
+ if(this->about_spatially_equal(cur_crv, other_crv, rel_sense, geom_factor, 0))
{
- TopologyBridge *new_tb = new_tbs.get_and_step();
- Curve *new_cur = dynamic_cast<Curve*>(new_tb);
- if(new_cur && new_cur != att_cur)
+ CubitVector pos1, pos2;
+ double cur_dist;
+ cur_crv->get_geometry_query_engine()->entity_entity_distance(
+ cur_crv, other_crv, pos1, pos2, cur_dist );
+ if(other_bodies.move_to(other_body))
{
- CubitBox new_box = new_cur->bounding_box();
- if(att_box.overlap(GEOMETRY_RESABS, new_box))
+ int list_index = other_bodies.get_index();
+ other_distances.reset();
+ other_distances.step(list_index);
+ double prev_dist = other_distances.get();
+ if(cur_dist < prev_dist)
{
- if(this->about_spatially_equal(new_cur, att_cur, rel_sense, geom_factor, 0))
- {
- match_cur = new_cur;
- process_curves_after_imprint(att_cur, new_cur, new_sms);
- }
+ other_distances.change_to(cur_dist);
+ other_crvs.reset();
+ other_crvs.step(list_index);
+ other_crvs.change_to(other_crv);
}
}
- }
-
- // If we didn't find a matching curve in the new bridge list
- // look at all of the rest of the curves.
- if(!match_cur)
- {
- BodySM *att_body = att_cur->bodysm();
- all_bodies.reset();
- lists_of_curves.reset();
- for(j=all_bodies.size(); !match_cur && j; j--)
+ else
{
- TopologyBridge *cur_body = all_bodies.get_and_step();
- DLIList<TopologyBridge*> *curves = lists_of_curves.get_and_step();
- BodySM *cur_bodysm = cur_body->bodysm();
-
- // Don't look at curves from the same body.
- if(att_body != cur_bodysm)
- {
- for(m=curves->size(); !match_cur && m; m--)
- {
- TopologyBridge *curtb = curves->get_and_step();
- Curve *cur = dynamic_cast<Curve*>(curtb);
- if(cur && cur != att_cur)
- {
- CubitBox new_box = cur->bounding_box();
- if(att_box.overlap(GEOMETRY_RESABS, new_box))
- {
- if(this->about_spatially_equal(cur, att_cur, rel_sense, geom_factor, 0))
- {
- match_cur = cur;
- process_curves_after_imprint(att_cur, cur, new_sms);
- }
- }
- }
- }
- }
+ other_bodies.append(other_body);
+ other_crvs.append(other_crv);
+ other_distances.append(cur_dist);
}
}
}
+ coincident_crvs_with_composite_att.append(cur_crv);
+ for(j=other_crvs.size(); j>0; j--)
+ {
+ Curve *crv = other_crvs.get_and_step();
+ list.clean_out();
+ crv->get_simple_attribute("COMPOSITE_GEOM", list);
+ if(list.size() > 0)
+ {
+ coincident_crvs_with_composite_att.append(other_crv);
+ if(all_curves_with_composite_att.move_to(other_crv))
+ all_curves_with_composite_att.extract();
+ }
+ else
+ coincident_crvs_without_composite_att.append(other_crv);
+ }
+ }
- // Force points to be done second.
- else if(h==1 && att_pt)
+ // If we have found at least one other crv coincident with the current crv...
+ if(coincident_crvs_with_composite_att.size() > 1 ||
+ coincident_crvs_without_composite_att.size() > 0)
+ {
+ // If there is at least one curve without a composite att that is an imprinter we
+ // will remove all composite atts from coincident curves
+ bool found = false;
+ for(j=coincident_crvs_without_composite_att.size(); j>0 && !found; j--)
{
- match_pt = NULL;
- CubitBox att_box = att_pt->bounding_box();
-
- // First check the list of new bridges as the corresponding
- // point will often be there.
- for(j=new_tbs.size(); !match_pt && j; j--)
+ Curve *tmp_crv = coincident_crvs_without_composite_att.get_and_step();
+ list.clean_out();
+ tmp_crv->get_simple_attribute("IMPRINTER",list);
+ if(list.size() > 0)
+ found = true;
+ }
+ if(found)
+ {
+ // Remove all composite atts.
+ for(j=coincident_crvs_with_composite_att.size(); j>0; j--)
{
- TopologyBridge *new_tb = new_tbs.get_and_step();
- Point *new_pt = dynamic_cast<Point*>(new_tb);
- if(new_pt && new_pt != att_pt)
- {
- CubitBox new_box = new_pt->bounding_box();
- if(att_box.overlap(GEOMETRY_RESABS, new_box))
- {
- if(GeometryQueryTool::instance()->about_spatially_equal(new_pt->coordinates(),
- att_pt->coordinates(), geom_factor))
- {
- match_pt = new_pt;
- process_points_after_imprint(att_pt, new_pt, new_sms);
- }
- }
- }
+ Curve *tmp_crv = coincident_crvs_with_composite_att.get_and_step();
+ list.clean_out();
+ tmp_crv->get_simple_attribute("COMPOSITE_GEOM",list);
+ if(list.size() > 0)
+ tmp_crv->remove_simple_attribute_virt(list.get());
}
- // If we didn't find a matching point in the new bridge list
- // look at all of the rest of the points.
- if(!match_pt)
+ }
+ else
+ {
+ // There were no imprinter crvs that didn't have composite atts.
+ // Next we will look for imprinter crvs with composite atts. These
+ // may have resulted in a new crv. If there is a non composite att
+ // crv that doesn't have an ORIGINAL att we will know it is new
+ // from the imprinter composite att crv and we know to put a composite
+ // att on it.
+ found = false;
+ for(j=coincident_crvs_with_composite_att.size(); j>0 && !found; j--)
{
- BodySM *att_body = att_pt->bodysm();
- all_bodies.reset();
- lists_of_points.reset();
- for(j=all_bodies.size(); !match_pt && j; j--)
+ Curve *tmp_crv = coincident_crvs_with_composite_att.get_and_step();
+ list.clean_out();
+ tmp_crv->get_simple_attribute("IMPRINTER",list);
+ if(list.size() > 0)
+ found = true;
+ }
+ if(found)
+ {
+ // Now put a composite att on any crv that doesn't have one.
+ for(j=coincident_crvs_without_composite_att.size(); j>0; j--)
{
- TopologyBridge *cur_body = all_bodies.get_and_step();
- DLIList<TopologyBridge*> *points = lists_of_points.get_and_step();
- BodySM *cur_bodysm = cur_body->bodysm();
-
- // Don't look at points from the same body.
- if(att_body != cur_bodysm)
+ Curve *tmp_crv = coincident_crvs_without_composite_att.get_and_step();
+ list.clean_out();
+ tmp_crv->get_simple_attribute("ORIGINAL", list);
+ if(list.size() == 0)
{
- for(m=points->size(); !match_pt && m; m--)
- {
- TopologyBridge *curtb = points->get_and_step();
- Point *pt = dynamic_cast<Point*>(curtb);
- if(pt && pt != att_pt)
- {
- CubitBox new_box = pt->bounding_box();
- if(att_box.overlap(GEOMETRY_RESABS, new_box))
- {
- if(GeometryQueryTool::instance()->about_spatially_equal(pt->coordinates(),
- att_pt->coordinates(), geom_factor))
- {
- match_pt = pt;
- process_points_after_imprint(att_pt, pt, new_sms);
- }
- }
- }
- }
+ // The crv was not in the original model and therefore was created by
+ // the imprint of a crv with a composite att. We need to put a composite
+ // att on it.
+ list.clean_out();
+ coincident_crvs_with_composite_att.get()->get_simple_attribute("COMPOSITE_GEOM",list);
+ tmp_crv->append_simple_attribute_virt(new CubitSimpleAttrib(list.get()));
}
}
}
}
}
+
+ for(i=coincident_crvs_with_composite_att.size(); i>0; i--)
+ {
+ Curve *crv = coincident_crvs_with_composite_att.get_and_step();
+ list.clean_out();
+ crv->get_simple_attribute("IMPRINTER",list);
+ if(list.size() > 0)
+ crv->remove_simple_attribute_virt(list.get());
+ list.clean_out();
+ crv->get_simple_attribute("ORIGINAL",list);
+ if(list.size() > 0)
+ crv->remove_simple_attribute_virt(list.get());
+ }
+ for(i=coincident_crvs_without_composite_att.size(); i>0; i--)
+ {
+ Curve *crv = coincident_crvs_without_composite_att.get_and_step();
+ list.clean_out();
+ crv->get_simple_attribute("IMPRINTER",list);
+ if(list.size() > 0)
+ crv->remove_simple_attribute_virt(list.get());
+ list.clean_out();
+ crv->get_simple_attribute("ORIGINAL",list);
+ if(list.size() > 0)
+ crv->remove_simple_attribute_virt(list.get());
+ }
}
+ delete crv_tree;
+ for(i=all_curves.size(); i>0; i--)
+ {
+ Curve *cur_curve = all_curves.get_and_step();
+ list.clean_out();
+ cur_curve->get_simple_attribute("IMPRINTER",list);
+ if(list.size() > 0)
+ cur_curve->remove_simple_attribute_virt(list.get());
+ list.clean_out();
+ cur_curve->get_simple_attribute("ORIGINAL",list);
+ if(list.size() > 0)
+ cur_curve->remove_simple_attribute_virt(list.get());
+ }
+ for(i=all_points.size(); i>0; i--)
+ {
+ Point *cur_point = all_points.get_and_step();
+ list.clean_out();
+ cur_point->get_simple_attribute("IMPRINTER",list);
+ if(list.size() > 0)
+ cur_point->remove_simple_attribute_virt(list.get());
+ list.clean_out();
+ cur_point->get_simple_attribute("ORIGINAL",list);
+ if(list.size() > 0)
+ cur_point->remove_simple_attribute_virt(list.get());
+ }
}
void CompositeEngine::process_curves_after_imprint(Curve *att_cur,
@@ -423,53 +720,67 @@
{
DLIList<CubitSimpleAttrib*> list;
- other_cur->get_simple_attribute("IMPRINT_PREEXISTING",list);
- if(list.size() == 0)
+ if(att_cur == other_cur)
{
- // This is a new bridge created by imprinting this hidden bridge. In
- // this case we need to add a COMPOSITE_GEOM attribute to the new bridge
- // so we don't see a resulting imprinted bridge from the hidden bridge.
- list.clean_out();
+ // This case will happen when we have manually added one of the existing
+ // curves on the surface to be imprinted to the "new_ENTITIES" list. We
+ // do this in cases where the curve to imprint on the surface exactly
+ // falls on one of the existing curves. In this case the ACIS face
+ // doesn't get new curves created but we need to consider the
+ // curve on the face as new because it may have been hidden in a
+ // composite surface and needs to be reintroduced. So, in this
+ // case we will remove the attribute so that the curve is no longer
+ // hidden.
att_cur->get_simple_attribute("COMPOSITE_GEOM",list);
- other_cur->append_simple_attribute_virt(new CubitSimpleAttrib(list.get()));
+ att_cur->remove_simple_attribute_virt(list.get());
}
else
{
- // This bridge existed before the imprint operation. Therefore it
- // could also have a COMPOSITE_GEOM attribute on it. Check this.
- list.clean_out();
- other_cur->get_simple_attribute("COMPOSITE_GEOM",list);
+ other_cur->get_simple_attribute("IMPRINT_PREEXISTING",list);
if(list.size() == 0)
{
- // It doesn't have a COMPOSITE_GEOM attribute so we need to remove
- // the COMPOSITE_GEOM from att_bridge because the hidden nature gets
- // wiped out by the imprinting process.
+ // This is a new bridge created by imprinting this hidden bridge. In
+ // this case we need to add a COMPOSITE_GEOM attribute to the new bridge
+ // so we don't see a resulting imprinted bridge from the hidden bridge.
+ list.clean_out();
att_cur->get_simple_attribute("COMPOSITE_GEOM",list);
- att_cur->remove_simple_attribute_virt(list.get());
- BodySM *bsm = att_cur->bodysm();
- if(bsm)
- new_sms.append_unique(bsm);
- TBOwner *bridge_owner = att_cur->owner();
- CompositeCurve *cc_bridge_owner = dynamic_cast<CompositeCurve*>(bridge_owner);
- if(cc_bridge_owner)
+ other_cur->append_simple_attribute_virt(new CubitSimpleAttrib(list.get()));
+ }
+ else
+ {
+ // This bridge existed before the imprint operation. Therefore it
+ // could also have a COMPOSITE_GEOM attribute on it. Check this.
+ list.clean_out();
+ other_cur->get_simple_attribute("COMPOSITE_GEOM",list);
+ if(list.size() == 0)
{
- TBOwner *cc_owner = cc_bridge_owner->owner();
- HiddenEntitySet *hes = dynamic_cast<HiddenEntitySet*>(cc_owner);
- if(hes)
+ // It doesn't have a COMPOSITE_GEOM attribute so we need to remove
+ // the COMPOSITE_GEOM from att_bridge because the hidden nature gets
+ // wiped out by the imprinting process.
+ att_cur->get_simple_attribute("COMPOSITE_GEOM",list);
+ att_cur->remove_simple_attribute_virt(list.get());
+ TBOwner *bridge_owner = att_cur->owner();
+ CompositeCurve *cc_bridge_owner = dynamic_cast<CompositeCurve*>(bridge_owner);
+ if(cc_bridge_owner)
{
- CompositeSurface *cs = dynamic_cast<CompositeSurface*>(hes->owner());
- if(cs)
- cs->HadBridgeRemoved = 1;
- // This is currently how we are notifying the owning CompositeSurface
- // that it needs to be deactivated and rebuilt. It really has
- // nothing to do with the bridge being removed though. Bad.
+ TBOwner *cc_owner = cc_bridge_owner->owner();
+ HiddenEntitySet *hes = dynamic_cast<HiddenEntitySet*>(cc_owner);
+ if(hes)
+ {
+ CompositeSurface *cs = dynamic_cast<CompositeSurface*>(hes->owner());
+ if(cs)
+ cs->HadBridgeRemoved = 1;
+ // This is currently how we are notifying the owning CompositeSurface
+ // that it needs to be deactivated and rebuilt. It really has
+ // nothing to do with the bridge being removed though. Bad.
+ }
}
}
+ else
+ {
+ // This bridge was also hidden so do nothing.
+ }
}
- else
- {
- // This bridge was also hidden so do nothing.
- }
}
}
@@ -480,92 +791,103 @@
int i;
DLIList<CubitSimpleAttrib*> list;
- other_pt->get_simple_attribute("IMPRINT_PREEXISTING",list);
- if(list.size() == 0)
+ if(att_pt == other_pt)
{
- // This is a new bridge created by imprinting this hidden bridge. In
- // this case we need to add a COMPOSITE_GEOM attribute to the new bridge
- // if possible so we don't see a resulting imprinted bridge from the hidden bridge.
- int num_visible_curves = 0;
- DLIList<TopologyBridge*> curves;
- att_pt->get_parents_virt(curves);
- for(i=curves.size(); i--;)
+ // This case will happen when we have manually added one of the existing
+ // pts on the surface to be imprinted to the "new_ENTITIES" list. We
+ // do this in cases where the pt to imprint on the surface exactly
+ // falls on one of the existing pts. In this case the ACIS face
+ // doesn't get new pts created but we need to consider the
+ // pt on the face as new because it may have been hidden in a
+ // composite curve and needs to be reintroduced. So, in this
+ // case we will remove the attribute so that the pt is no longer
+ // hidden.
+ att_pt->get_simple_attribute("COMPOSITE_GEOM",list);
+ att_pt->remove_simple_attribute_virt(list.get());
+ }
+ else
+ {
+ other_pt->get_simple_attribute("IMPRINT_PREEXISTING",list);
+ if(list.size() == 0)
{
- list.clean_out();
- TopologyBridge *c = curves.get_and_step();
- c->get_simple_attribute("COMPOSITE_GEOM", list);
- if(list.size() == 0)
- num_visible_curves++;
- }
- if(num_visible_curves > 2)
- {
- list.clean_out();
- att_pt->get_simple_attribute("COMPOSITE_GEOM",list);
- att_pt->remove_simple_attribute_virt(list.get());
- BodySM *bsm = att_pt->bodysm();
- if(bsm)
- new_sms.append_unique(bsm);
- TBOwner *bridge_owner = att_pt->owner();
- CompositePoint *cp_bridge_owner = dynamic_cast<CompositePoint*>(bridge_owner);
- if(cp_bridge_owner)
+ // This is a new bridge created by imprinting this hidden bridge. In
+ // this case we need to add a COMPOSITE_GEOM attribute to the new bridge
+ // if possible so we don't see a resulting imprinted bridge from the hidden bridge.
+ int num_visible_curves = 0;
+ DLIList<TopologyBridge*> curves;
+ att_pt->get_parents_virt(curves);
+ for(i=curves.size(); i--;)
{
- TBOwner *cp_owner = cp_bridge_owner->owner();
- HiddenEntitySet *hes = dynamic_cast<HiddenEntitySet*>(cp_owner);
- if(hes)
+ list.clean_out();
+ TopologyBridge *c = curves.get_and_step();
+ c->get_simple_attribute("COMPOSITE_GEOM", list);
+ if(list.size() == 0)
+ num_visible_curves++;
+ }
+ if(num_visible_curves > 2)
+ {
+ list.clean_out();
+ att_pt->get_simple_attribute("COMPOSITE_GEOM",list);
+ att_pt->remove_simple_attribute_virt(list.get());
+ TBOwner *bridge_owner = att_pt->owner();
+ CompositePoint *cp_bridge_owner = dynamic_cast<CompositePoint*>(bridge_owner);
+ if(cp_bridge_owner)
{
- CompositeCurve *cc = dynamic_cast<CompositeCurve*>(hes->owner());
- if(cc)
- cc->HadBridgeRemoved = 1;
- // This is currently how we are notifying the owning CompositeCurve
- // that it needs to be deactivated and rebuilt. It really has
- // nothing to do with the bridge being removed though. Bad.
+ TBOwner *cp_owner = cp_bridge_owner->owner();
+ HiddenEntitySet *hes = dynamic_cast<HiddenEntitySet*>(cp_owner);
+ if(hes)
+ {
+ CompositeCurve *cc = dynamic_cast<CompositeCurve*>(hes->owner());
+ if(cc)
+ cc->HadBridgeRemoved = 1;
+ // This is currently how we are notifying the owning CompositeCurve
+ // that it needs to be deactivated and rebuilt. It really has
+ // nothing to do with the bridge being removed though. Bad.
+ }
}
}
+ else
+ {
+ list.clean_out();
+ att_pt->get_simple_attribute("COMPOSITE_GEOM",list);
+ other_pt->append_simple_attribute_virt(new CubitSimpleAttrib(list.get()));
+ }
}
else
{
+ // This bridge existed before the imprint operation. Therefore it
+ // could also have a COMPOSITE_GEOM attribute on it. Check this.
list.clean_out();
- att_pt->get_simple_attribute("COMPOSITE_GEOM",list);
- other_pt->append_simple_attribute_virt(new CubitSimpleAttrib(list.get()));
- }
- }
- else
- {
- // This bridge existed before the imprint operation. Therefore it
- // could also have a COMPOSITE_GEOM attribute on it. Check this.
- list.clean_out();
- other_pt->get_simple_attribute("COMPOSITE_GEOM",list);
- if(list.size() == 0)
- {
- // It doesn't have a COMPOSITE_GEOM attribute so we need to remove
- // the COMPOSITE_GEOM from att_bridge because the hidden nature gets
- // wiped out by the imprinting process.
- att_pt->get_simple_attribute("COMPOSITE_GEOM",list);
- att_pt->remove_simple_attribute_virt(list.get());
- BodySM *bsm = att_pt->bodysm();
- if(bsm)
- new_sms.append_unique(bsm);
- TBOwner *bridge_owner = att_pt->owner();
- CompositePoint *cp_bridge_owner = dynamic_cast<CompositePoint*>(bridge_owner);
- if(cp_bridge_owner)
+ other_pt->get_simple_attribute("COMPOSITE_GEOM",list);
+ if(list.size() == 0)
{
- TBOwner *cp_owner = cp_bridge_owner->owner();
- HiddenEntitySet *hes = dynamic_cast<HiddenEntitySet*>(cp_owner);
- if(hes)
+ // It doesn't have a COMPOSITE_GEOM attribute so we need to remove
+ // the COMPOSITE_GEOM from att_bridge because the hidden nature gets
+ // wiped out by the imprinting process.
+ att_pt->get_simple_attribute("COMPOSITE_GEOM",list);
+ att_pt->remove_simple_attribute_virt(list.get());
+ TBOwner *bridge_owner = att_pt->owner();
+ CompositePoint *cp_bridge_owner = dynamic_cast<CompositePoint*>(bridge_owner);
+ if(cp_bridge_owner)
{
- CompositeCurve *cc = dynamic_cast<CompositeCurve*>(hes->owner());
- if(cc)
- cc->HadBridgeRemoved = 1;
- // This is currently how we are notifying the owning CompositeCurve
- // that it needs to be deactivated and rebuilt. It really has
- // nothing to do with the bridge being removed though. Bad.
+ TBOwner *cp_owner = cp_bridge_owner->owner();
+ HiddenEntitySet *hes = dynamic_cast<HiddenEntitySet*>(cp_owner);
+ if(hes)
+ {
+ CompositeCurve *cc = dynamic_cast<CompositeCurve*>(hes->owner());
+ if(cc)
+ cc->HadBridgeRemoved = 1;
+ // This is currently how we are notifying the owning CompositeCurve
+ // that it needs to be deactivated and rebuilt. It really has
+ // nothing to do with the bridge being removed though. Bad.
+ }
}
}
+ else
+ {
+ // This bridge was also hidden so do nothing.
+ }
}
- else
- {
- // This bridge was also hidden so do nothing.
- }
}
}
@@ -678,12 +1000,13 @@
// been modified and if so will deactivate them so that they can be
// rebuilt later using the COMPOSITE_GEOM attributes on the underlying
// solid model topology.
-void CompositeEngine::remove_modified(DLIList<TopologyBridge*>& geometry_list)
+void CompositeEngine::remove_modified(DLIList<Surface*> &surfaces,
+ DLIList<Curve*> &curves,
+ DLIList<Point*> &points)
{
clean_out_deactivated_geometry();
int i, j, k, m, n, w;
- int deactivate;
int something_changed = 1;
DLIList<Point*> already_deactivated_points;
DLIList<Curve*> already_deactivated_curves;
@@ -693,574 +1016,207 @@
{
something_changed = 0;
- for (i=geometry_list.size(); i--; )
+ DLIList<Point*> deactivated_points;
+ DLIList<Curve*> deactivated_curves;
+ DLIList<Surface*> deactivated_surfs;
+
+ // Look for composite points that are out of date.
+ for(w=points.size(); w--;)
{
- // This code will first look for portions of the left over virtual
- // topology layer that need to be blown away (deactivated). It
- // will put its findings in lists. Then it will loop through
- // and actualy deactivate everything.
- TopologyBridge* geom_bridge = geometry_list.get_and_step();
+ CompositePoint *p = dynamic_cast<CompositePoint*>(points.get_and_step());
+ if(p && !already_deactivated_points.is_in_list(p))
+ deactivated_points.append(p);
+ }
+ deactivated_points.uniquify_ordered();
- DLIList<Surface*> surfaces;
- DLIList<Curve*> curves;
- DLIList<Point*> points;
- DLIList<Point*> deactivated_points;
- DLIList<Curve*> deactivated_curves;
- DLIList<Surface*> deactivated_surfs;
+ // Look for composite curves that are out of date.
+ for(w=curves.size(); w--;)
+ {
+ Curve *current_curve = curves.get_and_step();
+ CompositeCurve *cur = dynamic_cast<CompositeCurve*>(current_curve);
+ if(cur && !already_deactivated_curves.is_in_list(cur))
+ deactivated_curves.append(cur);
+ }
+ deactivated_curves.uniquify_ordered();
- geom_bridge->surfaces(surfaces);
- geom_bridge->curves(curves);
- geom_bridge->points(points);
+ // Look for composite surfaces that are out of date.
+ for(w=surfaces.size(); w--;)
+ {
+ CompositeSurface* csurf = dynamic_cast<CompositeSurface*> (surfaces.get_and_step());
+ if (csurf && !already_deactivated_surfs.is_in_list(csurf))
+ deactivated_surfs.append(csurf);
+ }
+ deactivated_surfs.uniquify_ordered();
- // Look for composite points that are out of date.
- while(points.size())
- {
- CompositePoint *p = dynamic_cast<CompositePoint*>(points.pop());
- if(p && !already_deactivated_points.is_in_list(p))
- {
- Point *real_point = p->get_point();
+ already_deactivated_points += deactivated_points;
+ already_deactivated_curves += deactivated_curves;
+ already_deactivated_surfs += deactivated_surfs;
- deactivate = 0;
+ something_changed += deactivated_surfs.size() + deactivated_curves.size() +
+ deactivated_points.size();
- if(p->HadBridgeRemoved)
- deactivate = 1;
+ // Now actually deactivate the out of date composite surfs.
+ for(j=deactivated_surfs.size(); j--;)
+ {
+ CompositeSurface *csurf = dynamic_cast<CompositeSurface*>(deactivated_surfs.get_and_step());
- // Check the curve attached to this point and make sure the
- // virtual layer still matches the solid model layer.
- if(!deactivate)
- {
- // Get the curves at this point using the virtual layer.
- DLIList<Curve*> curves_referenced_by_virtual;
- DLIList<Curve*> crvs;
- p->curves(crvs);
- for(j=crvs.size(); j--;)
- {
- Curve *c = crvs.get_and_step();
- CompositeCurve *cc = dynamic_cast<CompositeCurve*>(c);
- if(cc)
- {
- int num_curves = cc->num_curves();
- for(k=0; k<num_curves; ++k)
- {
- Curve *cur_c = cc->get_curve(k);
- DLIList<TopologyBridge*> pts;
- cur_c->get_children(pts, false, 0);
- if(pts.is_in_list(real_point))
- curves_referenced_by_virtual.append_unique(cur_c);
- }
- }
- else
- curves_referenced_by_virtual.append_unique(c);
- }
+ // We have to also deactivate the boundary curves. When we deactivate
+ // the CompositeSurface it removes all of the CompositeCoEdges associated
+ // with it. However, it doesn't deactivate the composite curves associated
+ // with the composite coedges. Therefore you can end up with a regular
+ // CoEdge pointing to a CompositeCurve and if the CompositeCurve has more
+ // than 1 curve in it later calls to replace_surface (which will in turn
+ // call replace_curve) will fail.
+ DLIList<Curve*> boundary_curves;
+ csurf->curves(boundary_curves);
+ for (k=boundary_curves.size(); k--; )
+ {
+ CompositeCurve* c = dynamic_cast<CompositeCurve*>(boundary_curves.get_and_step());
+ assert(NULL != c);
+ deactivated_curves.append_unique(c);
+ already_deactivated_curves.append_unique(c);
- // Get the curves refernced by the solid model layer.
- DLIList<Curve*> curves_referenced_by_solid_model_layer;
- DLIList<TopologyBridge*> sm_crvs;
- real_point->get_parents_virt(sm_crvs);
- CAST_LIST(sm_crvs, curves_referenced_by_solid_model_layer, Curve);
+ DLIList<Point*> boundary_pts;
+ c->points(boundary_pts);
+ for (int e=boundary_pts.size(); e--; )
+ {
+ CompositePoint* p = dynamic_cast<CompositePoint*>(boundary_pts.get_and_step());
+ deactivated_points.append_unique(p);
+ already_deactivated_points.append_unique(p);
+ notify_deactivated(p);
+ }
- // Now check to make sure all of the curves referenced from the virtual
- // layer show up in the ones referenced by the solid model layer. If
- // they don't we know something has been modified and this CompositePoint
- // is no longer valid.
- for(j=curves_referenced_by_virtual.size(); j && !deactivate; j--)
- {
- Curve *c = curves_referenced_by_virtual.get_and_step();
- if(!curves_referenced_by_solid_model_layer.is_in_list(c))
- deactivate = 1;
- }
- }
-
- if(deactivate)
- deactivated_points.append_unique(p);
- }
+ notify_deactivated(c);
}
- // Look for composite curves that are out of date.
- for(w=curves.size(); w--;)
+ notify_deactivated(csurf);
+
+ DLIList<Curve*> hidden;
+ csurf->get_hidden_curves(hidden);
+ for (k=hidden.size(); k--; )
{
- Curve *current_curve = curves.get_and_step();
- CompositeCurve *cur = dynamic_cast<CompositeCurve*>(current_curve);
- if(cur && !already_deactivated_curves.is_in_list(cur))
- {
- deactivate = 0;
+ CompositeCurve* hcurve = dynamic_cast<CompositeCurve*>(hidden.pop());
+ assert(NULL != hcurve);
- if(cur->HadBridgeRemoved)
- deactivate = 1;
+ deactivated_curves.append_unique(hcurve);
+ already_deactivated_curves.append_unique(hcurve);
+ notify_deactivated(hcurve);
- // Deactivate this curve if any of its points have been
- // deactivated.
- if(!deactivate)
+ if(hcurve->num_curves() == 1)
+ {
+ Curve *c = hcurve->get_curve(0);
+ DLIList<TopologyBridge*> end_pts;
+ c->get_children(end_pts, false, 0);
+ for(m=end_pts.size(); m--;)
{
- DLIList<Point*> hidden_pts;
- DLIList<Point*> boundary_pts;
-
- cur->get_hidden_points(hidden_pts);
- for(j=hidden_pts.size(); j && !deactivate; j--)
+ Point *cur_p = dynamic_cast<Point*>(end_pts.get_and_step());
+ if(cur_p)
{
- Point *pt = hidden_pts.get_and_step();
- if(deactivated_points.is_in_list(pt))
- deactivate = 1;
- }
-
- cur->points(boundary_pts);
- for(j=boundary_pts.size(); j && !deactivate; j--)
- {
- Point *pt = boundary_pts.get_and_step();
- if(deactivated_points.is_in_list(pt))
- deactivate = 1;
- }
- }
-
- // Deactivate this curve if the coedges stored at the
- // virtual layer are out of sync with the solid model layer.
- if(!deactivate)
- {
- // Get all of the coedges seen from the virtual layer.
- DLIList<CoEdgeSM*> virt_coedges;
- DLIList<TopologyBridge*> coedge_list;
- cur->get_parents(coedge_list);
- for(j=coedge_list.size(); j--;)
- {
- CoEdgeSM *csm = dynamic_cast<CoEdgeSM*>(coedge_list.get_and_step());
- if(csm)
+ CompositePoint* cp = dynamic_cast<CompositePoint*>(cur_p->owner());
+ if(cp)
+ cur_p = (Point*)cp;
+ TBOwner *own = cur_p->owner();
+ HiddenEntitySet *hes = dynamic_cast<HiddenEntitySet*>(own);
+ if(hes)
{
- CompositeCoEdge *cce = dynamic_cast<CompositeCoEdge*>(csm);
- if(cce)
+ CompositeCurve *cc = dynamic_cast<CompositeCurve*>(hes->owner());
+ if(cc)
{
- int num_coedges = cce->num_coedges();
- for(k=0; k<num_coedges; k++)
+ deactivated_curves.append_unique(cc);
+ already_deactivated_curves.append_unique(cc);
+ notify_deactivated(cc);
+
+ DLIList<Point*> hidden_pts;
+ cc->get_hidden_points(hidden_pts);
+ for (n=hidden_pts.size(); n--; )
{
- CoEdgeSM *cur_coedge = cce->get_coedge(k);
- virt_coedges.append_unique(cur_coedge);
+ CompositePoint *hpoint = dynamic_cast<CompositePoint*>(hidden_pts.pop());
+ assert(NULL != hpoint);
+ deactivated_points.append_unique(hpoint);
+ already_deactivated_points.append_unique(hpoint);
+ notify_deactivated(hpoint);
}
}
- else
- virt_coedges.append_unique(csm);
}
}
-
- // Get all of the coedges seen from the solid model layer.
- DLIList<CoEdgeSM*> real_coedges;
- int num_curves = cur->num_curves();
- for(j=0; j<num_curves; j++)
- {
- Curve *cur_c = cur->get_curve(j);
- DLIList<TopologyBridge*> tb_list;
- cur_c->get_parents_virt(tb_list);
- for(k=tb_list.size(); k--;)
- {
- CoEdgeSM *cur_ce = dynamic_cast<CoEdgeSM*>(tb_list.get_and_step());
- if(cur_ce)
- real_coedges.append_unique(cur_ce);
- }
- }
-
- // Now make sure all of the coedges seen from the virtual layer actually
- // still exist in the solid model layer.
- for(j=virt_coedges.size(); j && !deactivate; j--)
- {
- if(!real_coedges.is_in_list(virt_coedges.get_and_step()))
- deactivate = 1;
- }
}
-
- // Deactivate this curve if any of the points seen from the virtual
- // layer are out of date.
- if(!deactivate)
- {
- DLIList<Point*> points_referenced_by_virtual;
- DLIList<Point*> points_referenced_by_solid_model_layer;
-
- // Get all of the hidden points in virtual layer.
- DLIList<Point*> hidden_pts;
- cur->get_hidden_points(hidden_pts);
- for(j=hidden_pts.size(); j--;)
- {
- Point *cur_point = hidden_pts.get_and_step();
- CompositePoint *cur_cpoint = dynamic_cast<CompositePoint*>(cur_point);
- if(cur_cpoint)
- cur_point = cur_cpoint->get_point();
- points_referenced_by_virtual.append_unique(cur_point);
- }
-
- // Get the end points in virtual layer.
- DLIList<Point*> end_pts;
- cur->points(end_pts);
- for(j=end_pts.size(); j--;)
- {
- Point *cur_point = end_pts.get_and_step();
- CompositePoint *cur_cpoint = dynamic_cast<CompositePoint*>(cur_point);
- if(cur_cpoint)
- cur_point = cur_cpoint->get_point();
- points_referenced_by_virtual.append_unique(cur_point);
- }
-
- // Get the points of all of the curves from the solid model layer.
- int num_curves = cur->num_curves();
- for(j=0; j<num_curves; ++j)
- {
- DLIList<TopologyBridge*> pts;
- Curve *c = cur->get_curve(j);
- c->get_children(pts, false, 0);
- for(k=pts.size(); k--;)
- points_referenced_by_solid_model_layer.
- append_unique(dynamic_cast<Point*>(pts.get_and_step()));
- }
-
- // Now that we have gathered all of the info we can check to make sure
- // that all of the points in the virtual layer actually exist in the
- // solid model layer.
- for(j=points_referenced_by_virtual.size(); j && !deactivate; j--)
- {
- Point *cur_point = points_referenced_by_virtual.get_and_step();
- if(!points_referenced_by_solid_model_layer.is_in_list(cur_point))
- deactivate = 1;
- }
- }
-
- // Check to see if there is a hidden entity that doesn't have a
- // COMPOSITE_GEOM attribute. This can happen if the geometry
- // modification operation cut the body right through a hidden
- // entity without splitting it. In this case a merge_owner event
- // gets triggered and the COMPOSITE_GEOM attribute gets removed
- // from the hidden entity. In this case we want to remove the
- // composite.
- if(!deactivate)
- {
- DLIList<Point*> hidden_points;
- cur->get_hidden_points(hidden_points);
- for(j=hidden_points.size(); j>0 && !deactivate; j--)
- {
- DLIList<CubitSimpleAttrib*> att_list;
- hidden_points.get_and_step()->get_simple_attribute("COMPOSITE_GEOM", att_list);
- if(att_list.size() == 0)
- deactivate = 1;
- }
- }
-
- // This block checks to see if any of the hidden points in
- // a composite curve are the endpoints of an actual curve of
- // the passed in geometry list. This can happen if the hidden
- // curve of a composite surface was cut by a real operation and
- // an end point of the original hidden curve was a hidden point
- // in a composite curve. In this case we want to deactivate the
- // composite curve. If the composite curve is still valid it will
- // get reconstructed by the composite attributes later.
- if(!deactivate)
- {
- DLIList<Point*> hidden;
- cur->get_hidden_points(hidden);
- for (j=hidden.size(); j && !deactivate; j--)
- {
- Point *pt = hidden.pop();
- DLIList<TopologyBridge*> point_curves;
- pt->get_parents_virt(point_curves);
- for(k=point_curves.size(); k && !deactivate; k--)
- {
- Curve *c = dynamic_cast<Curve*>(point_curves.get_and_step());
- if(c && c != current_curve && curves.is_in_list(c))
- deactivate = 1;
- }
- }
- }
-
- // Check to see if the existing CompositeCurve end points match the
- // underlying geometry end points. In some geometry modification
- // operations I found that a curve can be modified in place so that
- // the underlying entity was changed but owner attribute wasn't blown
- // away. As a result you end up with the same toplogy bridge which can
- // be out of date. The case I saw was where the Point in the CompositePoint
- // at one of the ends of the CompositeCurve was out of date and didn't
- // match the new Point that was created during the geometry modification.
- if(!deactivate)
- {
- // Not quite sure how to handle multiple curve cases yet so we
- // will do our best for now.
- if(cur->num_curves() == 1)
- {
- DLIList<TopologyBridge*> underlying_points;
- cur->get_curve(0)->get_children_virt(underlying_points);
- if(underlying_points.size() == 2)
- {
- Point *p1 = dynamic_cast<Point*>(underlying_points.get_and_step());
- Point *p2 = dynamic_cast<Point*>(underlying_points.get());
-
- CompositePoint *cp1 = cur->start_point();
- CompositePoint *cp2 = cur->end_point();
-
- if(!cp1 || !cp2)
- deactivate = 1;
- else
- {
- Point *cpp1 = cp1->get_point();
- Point *cpp2 = cp2->get_point();
- if((p1 != cpp1 && p2 != cpp1) || (p1 != cpp2 && p2 != cpp2))
- deactivate = 1;
- }
- }
- }
- }
-
- if(deactivate)
- deactivated_curves.append_unique(cur);
-
}
}
+ }
- // Look for composite surfaces that are out of date.
- while (surfaces.size())
+ // Now actually deactivate the out of date composite curves.
+ for(j=deactivated_curves.size(); j--;)
+ {
+ CompositeCurve *ccurve = dynamic_cast<CompositeCurve*>(deactivated_curves.get_and_step());
+
+ DLIList<Point*> boundary_pts;
+ ccurve->points(boundary_pts);
+ for (k=boundary_pts.size(); k--; )
{
- CompositeSurface* csurf = dynamic_cast<CompositeSurface*> (surfaces.pop());
- if (csurf && !already_deactivated_surfs.is_in_list(csurf))
- {
- deactivate = 0;
+ CompositePoint* p = dynamic_cast<CompositePoint*>(boundary_pts.get_and_step());
+ deactivated_points.append_unique(p);
+ already_deactivated_points.append_unique(p);
+ notify_deactivated(p);
+ }
- // If one of the surfaces was removed from the compGeom list we
- // suspect this composite surface was modified so we need to remove it.
- if(csurf->HadBridgeRemoved)
- deactivate = 1;
+ notify_deactivated(ccurve);
- // Deactivate this surface if any of its curves were deactivated.
- if(!deactivate)
- {
- DLIList<Curve*> hidden_curves;
- DLIList<Curve*> boundary_curves;
-
- csurf->get_hidden_curves(hidden_curves);
- for(j=hidden_curves.size(); j && !deactivate; j--)
- {
- Curve *curve = hidden_curves.get_and_step();
- if(deactivated_curves.is_in_list(curve))
- deactivate = 1;
- }
-
- csurf->curves(boundary_curves);
- for(j=boundary_curves.size(); j && !deactivate; j--)
- {
- Curve *curve = boundary_curves.get_and_step();
- if(deactivated_curves.is_in_list(curve))
- deactivate = 1;
- }
- }
-
- // Deactivate this surface if any of its curves seen from the
- // virtual layer are out of date.
- if(!deactivate)
- {
- DLIList<Curve*> curves_referenced_by_virtual;
- DLIList<Curve*> curves_referenced_by_solid_model_layer;
-
- // Get all of the hidden curves in virtual layer.
- DLIList<Curve*> hidden_curves;
- csurf->get_hidden_curves(hidden_curves);
- for(j=hidden_curves.size(); j--;)
- {
- Curve *cur_curve = hidden_curves.get_and_step();
- CompositeCurve *cur_ccurve = dynamic_cast<CompositeCurve*>(cur_curve);
- if(cur_ccurve)
- {
- for(k=cur_ccurve->num_curves()-1; k>-1; k--)
- {
- Curve *cur = cur_ccurve->get_curve(k);
- curves_referenced_by_virtual.append_unique(cur);
- }
- }
- else
- curves_referenced_by_virtual.append_unique(cur_curve);
- }
-
- // Get the boundary curves in virtual layer.
- DLIList<Curve*> end_curves;
- csurf->curves(end_curves);
- for(j=end_curves.size(); j--;)
- {
- Curve *cur_curve = end_curves.get_and_step();
- CompositeCurve *cur_ccurve = dynamic_cast<CompositeCurve*>(cur_curve);
- if(cur_ccurve)
- {
- for(k=cur_ccurve->num_curves()-1; k>-1; k--)
- {
- Curve *cur = cur_ccurve->get_curve(k);
- curves_referenced_by_virtual.append_unique(cur);
- }
- }
- else
- curves_referenced_by_virtual.append_unique(cur_curve);
- }
-
- // Get the curves of all of the surfaces from the solid model layer.
- int num_surfs = csurf->num_surfs();
- for(j=0; j<num_surfs; ++j)
- {
- Surface *s = csurf->get_surface(j);
- DLIList<TopologyBridge*> loops;
- s->get_children(loops, false, 0);
- for(k=loops.size(); k--;)
- {
- LoopSM *cur_loop = dynamic_cast<LoopSM*>(loops.get_and_step());
- DLIList<TopologyBridge*> coedges;
- cur_loop->get_children(coedges, false, 0);
- for(m=coedges.size(); m--;)
- {
- CoEdgeSM *cur_coedge = dynamic_cast<CoEdgeSM*>(coedges.get_and_step());
- DLIList<TopologyBridge*> crvs;
- cur_coedge->get_children(crvs, false, 0);
- for(n=crvs.size(); n--;)
- {
- Curve *cur_curve = dynamic_cast<Curve*>(crvs.get_and_step());
- curves_referenced_by_solid_model_layer.append_unique(cur_curve);
- }
- }
- }
- }
-
- // Now that we have gathered all of the info we can check to make sure
- // that all of the curves in the virtual layer actually exist in the
- // solid model layer.
- if(curves_referenced_by_virtual.size() !=
- curves_referenced_by_solid_model_layer.size())
- {
- deactivate = 1;
- }
- else
- {
- for(j=curves_referenced_by_virtual.size(); j && !deactivate; j--)
- {
- Curve *cur_curve = curves_referenced_by_virtual.get_and_step();
- if(!curves_referenced_by_solid_model_layer.is_in_list(cur_curve))
- deactivate = 1;
- }
- }
- }
-
- // Check to see if there is a hidden entity that doesn't have a
- // COMPOSITE_GEOM attribute. This can happen if the geometry
- // modification operation cut the body right through a hidden
- // entity without splitting it. In this case a merge_owner event
- // gets triggered and the COMPOSITE_GEOM attribute gets removed
- // from the hidden entity. In this case we want to remove the
- // composite.
- if(!deactivate)
- {
- DLIList<Curve*> hidden_curves;
- csurf->get_hidden_curves(hidden_curves);
- for(j=hidden_curves.size(); j>0 && !deactivate; j--)
- {
- DLIList<CubitSimpleAttrib*> att_list;
- hidden_curves.get_and_step()->get_simple_attribute("COMPOSITE_GEOM", att_list);
- if(att_list.size() == 0)
- deactivate = 1;
- }
- }
-
- if(deactivate)
- deactivated_surfs.append_unique(csurf);
- }
+ int j;
+ DLIList<Point*> hidden;
+ ccurve->get_hidden_points(hidden);
+ for (j=hidden.size(); j--; )
+ {
+ CompositePoint *hpoint = dynamic_cast<CompositePoint*>(hidden.pop());
+ assert(NULL != hpoint);
+ deactivated_points.append_unique(hpoint);
+ already_deactivated_points.append_unique(hpoint);
+ notify_deactivated(hpoint);
}
+ }
- already_deactivated_points += deactivated_points;
- already_deactivated_curves += deactivated_curves;
- already_deactivated_surfs += deactivated_surfs;
+ // Now actually deactivate the out of date composite points.
+ for(j=deactivated_points.size(); j--;)
+ {
+ CompositePoint* cpoint = dynamic_cast<CompositePoint*> (deactivated_points.pop());
+ notify_deactivated(cpoint);
+ }
+ }
- something_changed += deactivated_surfs.size() + deactivated_curves.size() +
- deactivated_points.size();
-
- // Now actually deactivate the out of date composite surfs.
- for(j=deactivated_surfs.size(); j--;)
+ int remove_point_atts = 1;
+ if(remove_point_atts)
+ {
+ // Remove any COMPOSITE_GEOM attributes on points that
+ // have a valence of more than two (real curves - hidden curves).
+ for(i=points.size(); i>0; i--)
+ {
+ Point *pt = points.get_and_step();
+ CompositePoint *cp = dynamic_cast<CompositePoint*>(pt);
+ if(cp)
+ pt = cp->get_point();
+ DLIList<CubitSimpleAttrib*> attribs;
+ pt->get_simple_attribute("COMPOSITE_GEOM", attribs);
+ if(attribs.size() > 0)
{
- CompositeSurface *csurf = dynamic_cast<CompositeSurface*>(deactivated_surfs.get_and_step());
-
- // We have to also deactivate the boundary curves. When we deactivate
- // the CompositeSurface it removes all of the CompositeCoEdges associated
- // with it. However, it doesn't deactivate the composite curves associated
- // with the composite coedges. Therefore you can end up with a regular
- // CoEdge pointing to a CompositeCurve and if the CompositeCurve has more
- // than 1 curve in it later calls to replace_surface (which will in turn
- // call replace_curve) will fail.
- DLIList<Curve*> boundary_curves;
- csurf->curves(boundary_curves);
- for (k=boundary_curves.size(); k--; )
+ DLIList<TopologyBridge*> tmp_curves;
+ pt->get_parents_virt(tmp_curves);
+ int num_curves = 0;
+ for(j=tmp_curves.size(); j>0; j--)
{
- CompositeCurve* c = dynamic_cast<CompositeCurve*>(boundary_curves.get_and_step());
- assert(NULL != c);
-
- notify_deactivated(c);
+ TopologyBridge *crv = tmp_curves.get_and_step();
+ DLIList<CubitSimpleAttrib*> attribs;
+ crv->get_simple_attribute("COMPOSITE_GEOM", attribs);
+ if(attribs.size() == 0)
+ num_curves++;
}
-
- notify_deactivated(csurf);
-
- DLIList<Curve*> hidden;
- csurf->get_hidden_curves(hidden);
- for (k=hidden.size(); k--; )
+ if(num_curves != 2)
{
- CompositeCurve* hcurve = dynamic_cast<CompositeCurve*>(hidden.pop());
- assert(NULL != hcurve);
-
- notify_deactivated(hcurve);
-
- if(hcurve->num_curves() == 1)
+ for(j=attribs.size(); j>0; j--)
{
- Curve *c = hcurve->get_curve(0);
- DLIList<TopologyBridge*> end_pts;
- c->get_children(end_pts, false, 0);
- for(m=end_pts.size(); m--;)
- {
- Point *cur_p = dynamic_cast<Point*>(end_pts.get_and_step());
- if(cur_p)
- {
- CompositePoint* cp = dynamic_cast<CompositePoint*>(cur_p->owner());
- if(cp)
- cur_p = (Point*)cp;
- TBOwner *own = cur_p->owner();
- HiddenEntitySet *hes = dynamic_cast<HiddenEntitySet*>(own);
- if(hes)
- {
- CompositeCurve *cc = dynamic_cast<CompositeCurve*>(hes->owner());
- if(cc)
- {
- notify_deactivated(cc);
-
- DLIList<Point*> hidden_pts;
- cc->get_hidden_points(hidden_pts);
- for (n=hidden_pts.size(); n--; )
- {
- CompositePoint *hpoint = dynamic_cast<CompositePoint*>(hidden_pts.pop());
- assert(NULL != hpoint);
- notify_deactivated(hpoint);
- }
- }
- }
- }
- }
+ CubitSimpleAttrib *csa = attribs.get_and_step();
+ pt->remove_simple_attribute_virt(csa);
}
}
}
-
- // Now actually deactivate the out of date composite curves.
- for(j=deactivated_curves.size(); j--;)
- {
- CompositeCurve *ccurve = dynamic_cast<CompositeCurve*>(deactivated_curves.get_and_step());
-
- notify_deactivated(ccurve);
-
- int j;
- DLIList<Point*> hidden;
- ccurve->get_hidden_points(hidden);
- for (j=hidden.size(); j--; )
- {
- CompositePoint *hpoint = dynamic_cast<CompositePoint*>(hidden.pop());
- assert(NULL != hpoint);
- notify_deactivated(hpoint);
- }
- }
-
- // Now actually deactivate the out of date composite points.
- for(j=deactivated_points.size(); j--;)
- {
- CompositePoint* cpoint = dynamic_cast<CompositePoint*> (deactivated_points.pop());
- notify_deactivated(cpoint);
- }
}
}
}
@@ -4789,8 +4745,9 @@
surfaces += temp_surfaces;
lumps += temp_lumps;
}
-
- // assert that lists do not contain duplicates
+
+
+ // assert that lists do not contain duplicates
//assert( (i = points.size(), points.uniquify_ordered(), i == points.size() ) );
//assert( (i = curves.size(), curves.uniquify_ordered(), i == curves.size() ) );
points.uniquify_ordered(); // can have duplicates in some non-manifold cases
@@ -4835,17 +4792,15 @@
if( !create_composites( curves ) ) result = CUBIT_FAILURE;
if( !create_composites( points ) ) result = CUBIT_FAILURE;
}
- else
- {
- for ( i = bodies.size(); i--; )
- strip_attributes( bodies.get_and_step() );
- for ( i = surfaces.size(); i--; )
- strip_attributes( surfaces.get_and_step() );
- for ( i = curves.size(); i--; )
- strip_attributes( curves.get_and_step() );
- for ( i = points.size(); i--; )
- strip_attributes( points.get_and_step() );
- }
+
+ for ( i = bodies.size(); i--; )
+ strip_attributes( bodies.get_and_step() );
+ for ( i = surfaces.size(); i--; )
+ strip_attributes( surfaces.get_and_step() );
+ for ( i = curves.size(); i--; )
+ strip_attributes( curves.get_and_step() );
+ for ( i = points.size(); i--; )
+ strip_attributes( points.get_and_step() );
// update imported_geom list to contain composites rather than
// entities used to create the composites
@@ -4864,7 +4819,6 @@
// entity. need to remove the duplicates.
imported_geom.uniquify_unordered();
*/
-
// that's all folks
return result;
}
@@ -4887,6 +4841,24 @@
return ret;
}
+bool CompositeEngine::is_composite(TopologyBridge *bridge)
+{
+ bool ret = false;
+ if(bridge)
+ {
+ if(dynamic_cast<CompositeBody*>(bridge) ||
+ dynamic_cast<CompositeLump*>(bridge) ||
+ dynamic_cast<CompositeSurface*>(bridge) ||
+ dynamic_cast<CompositeCurve*>(bridge) ||
+ dynamic_cast<CompositeCoEdge*>(bridge) ||
+ dynamic_cast<CompositePoint*>(bridge))
+ {
+ ret = true;
+ }
+ }
+ return ret;
+}
+
bool CompositeEngine::is_partition(TBOwner *bridge_owner)
{
return false;
@@ -4941,35 +4913,47 @@
surface_list += temp_surfaces;
}
- DLIList<CompositeCurve*> ccurve_list;
- DLIList<CompositeSurface*> csurf_list;
+// DLIList<CompositeCurve*> ccurve_list;
+// DLIList<CompositeSurface*> csurf_list;
- CAST_LIST( curve_list, ccurve_list, CompositeCurve );
- CAST_LIST( surface_list, csurf_list, CompositeSurface );
+// CAST_LIST( curve_list, ccurve_list, CompositeCurve );
+// CAST_LIST( surface_list, csurf_list, CompositeSurface );
- ccurve_list.uniquify_unordered();
- csurf_list.uniquify_unordered();
+// ccurve_list.uniquify_unordered();
+// csurf_list.uniquify_unordered();
+ curve_list.uniquify_unordered();
+ surface_list.uniquify_unordered();
int j,k;
- for( i = ccurve_list.size(); i--; )
+ for( i = curve_list.size(); i--; )
{
- CompositeCurve* tmp_comp_curve = ccurve_list.get_and_step();
- for( j = 0; j < tmp_comp_curve->num_curves(); j++ )
+ Curve *tmp_curve = curve_list.get_and_step();
+ strip_attributes(tmp_curve);
+ CompositeCurve* tmp_comp_curve = dynamic_cast<CompositeCurve*>(tmp_curve);
+ if(tmp_comp_curve)
{
- strip_attributes( tmp_comp_curve->get_curve(j) );
+ for( j = 0; j < tmp_comp_curve->num_curves(); j++ )
+ {
+ strip_attributes( tmp_comp_curve->get_curve(j) );
- //remove attributes off underlying points too
- DLIList<Point*> hidden_points;
- tmp_comp_curve->get_hidden_points( hidden_points );
- for( k=hidden_points.size(); k--; )
- strip_attributes( hidden_points.get_and_step() );
+ //remove attributes off underlying points too
+ DLIList<Point*> hidden_points;
+ tmp_comp_curve->get_hidden_points( hidden_points );
+ for( k=hidden_points.size(); k--; )
+ strip_attributes( hidden_points.get_and_step() );
+ }
}
}
- for( i = csurf_list.size(); i--; )
+ for( i = surface_list.size(); i--; )
{
- CompositeSurface *tmp_comp_surf = csurf_list.get_and_step();
- for( int j = 0; j < tmp_comp_surf->num_surfs(); j++ )
- strip_attributes( tmp_comp_surf->get_surface(j) );
+ Surface *tmp_surf = surface_list.get_and_step();
+ strip_attributes(tmp_surf);
+ CompositeSurface *tmp_comp_surf = dynamic_cast<CompositeSurface*>(tmp_surf);
+ if(tmp_comp_surf)
+ {
+ for( int j = 0; j < tmp_comp_surf->num_surfs(); j++ )
+ strip_attributes( tmp_comp_surf->get_surface(j) );
+ }
}
//remove attrigutes off of bridges passed in
@@ -5145,15 +5129,6 @@
CubitSimpleAttrib* attrib = find_attribute_by_name( curve, "COMPOSITE_GEOM" );
if( attrib )
{
- // The attribute contains the ids of surfaces in the composite
- // that should be ignored during evaluation. Get these ids
- // and put them in a list to be used below.
- DLIList<int> surfs_to_ignore;
- for(int k=attrib->int_data_list()->size(); k--;)
- {
- surfs_to_ignore.append(*(attrib->int_data_list()->get_and_step()));
- }
-
curve->remove_simple_attribute_virt( attrib );
/*
@@ -5202,9 +5177,15 @@
{
// Tell the composite surface which surfaces to ignore during
// evaluation.
- for(int k=surfs_to_ignore.size(); k--;)
+ for(int j=0; j<surf->num_surfs(); j++)
{
- surf->ignore_surface(surfs_to_ignore.get_and_step());
+ Surface *srf = surf->get_surface(j);
+ CubitSimpleAttrib* ignore_attrib = find_attribute_by_name( srf, "COMPOSITE_IGNORE" );
+ if( ignore_attrib )
+ {
+ surf->ignore_surface(srf);
+ srf->remove_simple_attribute_virt( ignore_attrib );
+ }
}
surf->read_attributes();
}
@@ -5331,7 +5312,9 @@
// Creation Date : 06/18/02
//-------------------------------------------------------------------------
CubitStatus CompositeEngine::create_composites( DLIList<BodySM*>& )
- { return CUBIT_SUCCESS; }
+{
+ return CUBIT_SUCCESS;
+}
//-------------------------------------------------------------------------
// Purpose : Save composite geometry
@@ -5438,20 +5421,11 @@
geom_attrib.int_data_list()->append(&tb_id);
append_attrib(tb, &geom_attrib);
geom_attrib.int_data_list()->clean_out();
+
}
}
}
- /* Do the same for curves here.
- ccurve_list.reset();
- for(i=ccurve_list.size(); i--;)
- {
- CompositeCurve *cur_curve = ccurve_list.get_and_step();
- cur_curve->add_topology_id_attributes();
- cur_curve->add_ignore_attributes();
- }
- */
-
for( i = ccurve_list.size(); i--; )
save( ccurve_list.get_and_step() );
for( i = csurf_list.size(); i--; )
@@ -5630,16 +5604,8 @@
for( j = 0; j < ccurve->num_curves(); j++ )
{
- // Add to the attribute information about surfaces
- // to ignore during evaluation.
- for(int k=surf->surfacesToIgnore.size(); k--;)
- {
- int *id = new int(surf->surfacesToIgnore.get_and_step());
- geom_attrib.int_data_list()->append(id);
- }
Curve* tb = ccurve->get_curve(j);
append_attrib( tb, &geom_attrib );
- geom_attrib.int_data_list()->clean_out();
}
}
@@ -5682,6 +5648,19 @@
}
}
+ name = "COMPOSITE_IGNORE";
+ CubitSimpleAttrib ignore_attrib( &string_list, 0, 0 );
+
+ DLIList<Surface*> srfs;
+ surf->get_ignored_surfs(srfs);
+ for( i = 0; i < surf->num_surfs(); i++ )
+ {
+ Surface *srf = surf->get_surface(i);
+ if(srfs.is_in_list(srf))
+ srf->append_simple_attribute_virt(&ignore_attrib);
+ }
+
+
return CUBIT_SUCCESS;
}
@@ -5911,7 +5890,7 @@
Point *result = 0;
CubitVector position;
DLIList<Point*> pts;
- const double tolsqr = GEOMETRY_RESABS*GEOMETRY_RESABS;
+ double tolsqr = GEOMETRY_RESABS*GEOMETRY_RESABS;
Point *start, *end;
DLIList<TopologyBridge*> pt_list;
Curve *rcurve = 0;
@@ -5933,8 +5912,28 @@
for(i=pts.size(); i--;)
{
Point *cur_pt = pts.get_and_step();
- if( (cur_pt->coordinates() - position).length_squared() < tolsqr )
+
+ // Don't use GEOMETRY_RESABS if we can get a
+ // value from the solid modeling engine.
+ double tmp_tol = tolsqr;
+ CompositePoint *cp = dynamic_cast<CompositePoint*>(cur_pt);
+ GeometryQueryEngine *gqe = NULL;
+ if(cp)
{
+ Point *real_pt = cp->get_point();
+ gqe = real_pt->get_geometry_query_engine();
+ }
+ else
+ gqe = cur_pt->get_geometry_query_engine();
+ if(gqe)
+ {
+ double tmp_tol = gqe->get_sme_resabs_tolerance();
+ tmp_tol *= tmp_tol;
+ if(tmp_tol > tolsqr)
+ tolsqr = tmp_tol;
+ }
+ if( (cur_pt->coordinates() - position).length_squared() < tmp_tol )
+ {
result = cur_pt;
i = 0;
}
@@ -6552,3 +6551,10 @@
delete comp2;
return comp1;
}
+
+void CompositeEngine::get_tbs_with_bridge_manager_as_owner( TopologyBridge *source_bridge,
+ DLIList<TopologyBridge*> &tbs )
+{
+ //do nothing.
+}
+
Modified: cgm/branches/cubit/geom/virtual/CompositeEngine.hpp
===================================================================
--- cgm/branches/cubit/geom/virtual/CompositeEngine.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/CompositeEngine.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -39,17 +39,23 @@
class CompositeEngine : public IntermediateGeomEngine
{
public:
+ void get_all_curves_and_points(DLIList<TopologyBridge*> &tb_list,
+ DLIList<Curve*> &curves,
+ DLIList<Point*> &points);
bool is_composite(TBOwner *bridge_owner);
+ bool is_composite(TopologyBridge *bridge);
bool is_partition(TBOwner *bridge_owner);
virtual void remove_imprint_attributes_after_modify
( DLIList<BodySM*> &old_sms,
DLIList<BodySM*> &new_sms );
+ virtual void push_named_attributes_to_curves_and_points
+ ( DLIList<TopologyBridge*> &tb_list, const char *name_in);
virtual void push_imprint_attributes_before_modify
( DLIList<BodySM*> &body_sms );
virtual void attribute_after_imprinting( DLIList<TopologyBridge*> &new_tbs,
DLIList<TopologyBridge*> &att_tbs,
- DLIList<BodySM*> &new_sms,
+ DLIList<TopologyBridge*> &tb_list,
DLIList<Body*> &old_bodies);
// This is a copy of the function in MergeTool with the difference that it
@@ -64,7 +70,8 @@
virtual ~CompositeEngine();
static CompositeEngine& instance();
-
+ static void delete_instance();
+
int level() const { return COMPOSITE_LAYER; }
CubitStatus import_geometry( DLIList<TopologyBridge*>& imported_geometry );
@@ -202,8 +209,13 @@
void remove_attributes( DLIList<TopologyBridge*> &bridge_list );
//remove Composite attributes off of topology bridges
- void remove_modified(DLIList<TopologyBridge*>& geometry_list);
+ virtual void remove_modified(DLIList<Surface*> &all_surfs,
+ DLIList<Curve*> &all_curves, DLIList<Point*> &all_pts);
+
+ void get_tbs_with_bridge_manager_as_owner( TopologyBridge *source_bridge,
+ DLIList<TopologyBridge*> &tbs );
+
protected:
Point* remove_composite( CompositePoint* point );
Modified: cgm/branches/cubit/geom/virtual/CompositeGeom.cpp
===================================================================
--- cgm/branches/cubit/geom/virtual/CompositeGeom.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/CompositeGeom.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -60,7 +60,12 @@
//-------------------------------------------------------------------------
CompositeGeom::~CompositeGeom()
{
- rem_all_attributes();
+ while(listHead)
+ {
+ CompositeAttrib* dead = listHead;
+ listHead = listHead->next;
+ delete dead;
+ }
}
//-------------------------------------------------------------------------
@@ -609,8 +614,8 @@
delete dead;
}
- // if (entityList.size() == 1)
- // entityList[0].entity->remove_all_simple_attribute_virt();
+ if (entityList.size() == 1)
+ entityList[0].entity->remove_all_simple_attribute_virt();
}
@@ -820,6 +825,20 @@
assert(attrib->int_data_list()->size());
if (*attrib->int_data_list()->get() == entityList.size())
{
+ // Take the attributes off of the current entity and put them on the first entity
+ // in this list. I believe this is ok to do because the attributes should apply to
+ // the whole composite surface and not just the underlying entity they are on
+ // (the one exception to this might be UNIQUE_ID but I haven't seen any problems
+ // with this yet). The reason for doing this is that there is some code (I believe
+ // in uncomposite() that assumes any attributes will be on the first entity
+ // in the list. Previous code actually moved the entity to the beginning
+ // of the list but this reordering of the list does not fly with composite
+ // curves because there is code depending on the curves in the list being
+ // ordered so that they connect end to end in a contiguous manner (the
+ // faceting code, for one, relies on this). BWC 1/7/07.
+ entityList[i].entity->remove_simple_attribute_virt(attrib);
+ entityList[0].entity->append_simple_attribute_virt(attrib);
+
delete attrib->int_data_list()->remove();
attrib->string_data_list()->reset();
delete attrib->string_data_list()->remove();
@@ -828,14 +847,6 @@
}
}
}
-
- if( index_of_entity_with_attribs != 0 && index_of_entity_with_attribs != -1 )
- {
- //Swap entities around so that one with attribs is first
- CompositeEntry should_be_first = entityList[ index_of_entity_with_attribs ];
- entityList.remove( index_of_entity_with_attribs );
- entityList.insert( should_be_first, 0 );
- }
}
//-------------------------------------------------------------------------
Modified: cgm/branches/cubit/geom/virtual/CompositeGeom.hpp
===================================================================
--- cgm/branches/cubit/geom/virtual/CompositeGeom.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/CompositeGeom.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -21,6 +21,7 @@
class GeometryEntity;
class CubitSimpleAttrib;
class CompositeAttrib;
+class TopologyBridge;
struct CompositeEntry
{
Modified: cgm/branches/cubit/geom/virtual/CompositeLoop.cpp
===================================================================
--- cgm/branches/cubit/geom/virtual/CompositeLoop.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/CompositeLoop.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -171,6 +171,27 @@
}
//-------------------------------------------------------------------------
+// Purpose : The purpose of this function is to see if a loop is an external
+// or internal loop of a surface.
+//
+// Special Notes :
+//
+// Creator : Jonathan Bugman
+//
+// Creation Date : 9/9/2008
+//-------------------------------------------------------------------------
+CubitBoolean CompositeLoop::is_external()
+{
+ PRINT_ERROR( "This command is not supported with this engine.\n");
+ return CUBIT_FAILURE;
+}
+
+LoopType CompositeLoop::loop_type()
+{
+ return LOOP_TYPE_UNKNOWN;
+}
+
+//-------------------------------------------------------------------------
// Purpose : get parent bridges
//
// Special Notes : pure virtual in TopologyBridge
Modified: cgm/branches/cubit/geom/virtual/CompositeLoop.hpp
===================================================================
--- cgm/branches/cubit/geom/virtual/CompositeLoop.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/CompositeLoop.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -44,6 +44,13 @@
GeometryQueryEngine* get_geometry_query_engine() const;
int layer() const { return COMPOSITE_LAYER; }
+ virtual LoopType loop_type() ;
+ virtual CubitBoolean is_external() ;
+ //R CubitBoolean
+ //R- CUBIT_TRUE/CUBIT_FALSE
+ //- Returns CUBIT_TRUE if the Loop is an external Loop and CUBIT_FALSE
+ //- otherwise.
+
void append_simple_attribute_virt( CubitSimpleAttrib* );
void remove_simple_attribute_virt( CubitSimpleAttrib* );
void remove_all_simple_attribute_virt();
Modified: cgm/branches/cubit/geom/virtual/CompositeSurface.cpp
===================================================================
--- cgm/branches/cubit/geom/virtual/CompositeSurface.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/CompositeSurface.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -320,6 +320,21 @@
return CUBIT_SUCCESS;
}
+void CompositeSurface::get_ignored_surfs(DLIList<Surface*> &surfs)
+{
+ int i;
+
+ if(surfacesToIgnore.size() > 0)
+ {
+ for(i=0; i<num_surfs(); i++)
+ {
+ Surface *srf = get_surface(i);
+ if(surfacesToIgnore.is_in_list(srf))
+ surfs.append(srf);
+ }
+ }
+}
+
//-------------------------------------------------------------------------
// Purpose : Return the bounding box
//
@@ -629,11 +644,10 @@
facetTool->set_ignore_flag(i, 0);
Surface *cur_surf = get_surface(i);
- int id = cur_surf->get_saved_id();
surfacesToIgnore.reset();
for(int j=surfacesToIgnore.size(); j--;)
{
- if(id == surfacesToIgnore.get_and_step())
+ if(cur_surf == surfacesToIgnore.get_and_step())
{
facetTool->set_ignore_flag(i, 1);
j=0;
@@ -658,13 +672,30 @@
Surface *cur_surf = get_surface(i);
if(cur_surf->get_saved_id() == surface_id)
{
- break;
+ surfacesToIgnore.append_unique(cur_surf);
+ i = num_surfs_in_composite;
+ update_facets_to_ignore();
}
}
- if(i < num_surfs_in_composite)
+ }
+}
+
+void CompositeSurface::ignore_surface(Surface *surf)
+{
+ update_facet_tool();
+ if(facetTool)
+ {
+ int i;
+ int num_surfs_in_composite = num_surfs();
+ for (i=0; i<num_surfs_in_composite; i++)
{
- surfacesToIgnore.append_unique(surface_id);
- update_facets_to_ignore();
+ Surface *cur_surf = get_surface(i);
+ if(cur_surf == surf)
+ {
+ surfacesToIgnore.append_unique(cur_surf);
+ i = num_surfs_in_composite;
+ update_facets_to_ignore();
+ }
}
}
}
@@ -683,14 +714,11 @@
Surface *cur_surf = get_surface(i);
if(cur_surf->get_saved_id() == surface_id)
{
- break;
+ surfacesToIgnore.remove(cur_surf);
+ update_facets_to_ignore();
+ i = num_surfs_in_composite;
}
}
- if(i < num_surfs_in_composite)
- {
- surfacesToIgnore.remove(surface_id);
- update_facets_to_ignore();
- }
}
}
@@ -847,6 +875,7 @@
curvature1, curvature2 );
update_facet_tool();
+
if ( facetTool )
{
CubitStatus result;
@@ -861,30 +890,39 @@
CubitVector normal(0.0, 0.0, 0.0);
int i;
- for (i = 0; i < num_found; i++) {
+ for (i = 0; i < num_found; i++)
+ {
int index = index_list[i];
- Surface* surf = get_surface(index);
-
- result = surf->closest_point( facet_closest, closest_location,
- &normal, curvature1, curvature2 );
-
- if (get_sense(index) == CUBIT_REVERSED)
- *unit_normal += (-normal);
- else
- *unit_normal += normal;
+ if(index > -1)
+ {
+ Surface* surf = get_surface(index);
+
+ result = surf->closest_point( facet_closest, closest_location,
+ &normal, curvature1, curvature2 );
+
+ if (get_sense(index) == CUBIT_REVERSED)
+ *unit_normal += (-normal);
+ else
+ *unit_normal += normal;
+ }
}
unit_normal->normalize();
}
else
{
int index = facetTool->closest_index( location, &facet_closest );
- Surface* surf = get_surface(index);
+ if(index > -1)
+ {
+ Surface* surf = get_surface(index);
+
+ result = surf->closest_point( facet_closest, closest_location,
+ unit_normal, curvature1, curvature2 );
- result = surf->closest_point( facet_closest, closest_location,
- unit_normal, curvature1, curvature2 );
-
-// if (unit_normal && get_sense(index) == CUBIT_REVERSED)
-// *unit_normal = -*unit_normal;
+ // if (unit_normal && get_sense(index) == CUBIT_REVERSED)
+ // *unit_normal = -*unit_normal;
+ }
+ else
+ result = CUBIT_FAILURE;
}
return result;
@@ -1550,7 +1588,7 @@
for(int k=surfacesToIgnore.size(); k--;)
{
PRINT_INFO("%sSurface: %d\n",
- new_prefix, surfacesToIgnore.get_and_step());
+ new_prefix, surfacesToIgnore.get_and_step()->get_saved_id());
}
}
if( hiddenSet ) hiddenSet->print_debug_info( new_prefix );
@@ -1886,7 +1924,7 @@
if (!facetTool)
return CUBIT_FAILURE;
- facetTool->graphics( GEOMETRY_RESABS*10, gmem);
+ facetTool->graphics( GEOMETRY_RESABS, gmem);
return CUBIT_SUCCESS;
}
Modified: cgm/branches/cubit/geom/virtual/CompositeSurface.hpp
===================================================================
--- cgm/branches/cubit/geom/virtual/CompositeSurface.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/CompositeSurface.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -46,6 +46,7 @@
//CubitStatus add( Surface* surface, CubitSense relative_sense );
//CubitStatus remove( Surface* surface );
+ void get_ignored_surfs(DLIList<Surface*> &surfs);
int num_surfs() const;
int index_of( Surface* surface ) const;
void update();
@@ -53,6 +54,7 @@
CubitSense get_sense( int index ) const;
Surface* remove_surface( int index );
void ignore_surface(int surface_id);
+ void ignore_surface(Surface *surf);
void unignore_surface(int surface_id);
CompositeLoop* first_loop() const;
CompositeLoop* next_loop( CompositeLoop* after_this = 0 ) const;
@@ -216,7 +218,7 @@
private:
int HadBridgeRemoved;
- DLIList<int> surfacesToIgnore;
+ DLIList<Surface*> surfacesToIgnore;
// these have no implementation, just private delcarations
// to prevent the compiler from generating default implementations
Modified: cgm/branches/cubit/geom/virtual/CompositeTool.cpp
===================================================================
--- cgm/branches/cubit/geom/virtual/CompositeTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/CompositeTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -128,7 +128,7 @@
PRINT_ERROR("Cannot create any composites from passed curves.\n");
return 0;
}
-
+
vertex_list.reset();
RefEdge* result = 0;
DLIList<RefEdge*> vtx_edges;
@@ -163,6 +163,7 @@
modified_edges.remove_all_with_value(0);
result = modified_edges.size() ? modified_edges.get() : 0;
+
DLIList<Surface*> update_surfaces, curve_surfaces;
DLIList<TopologyBridge*> curve_bridges;
for ( i = modified_edges.size(); i--; )
@@ -205,9 +206,6 @@
bool update_dag , /* = true */
RefEdge* keep_edge /* = NULL */ )
{
-#ifdef BOYD17
- DLIList<RefEdge*> free_edges, vertex_edges;
-#endif
DLIList<RefEdge*> vertex_edges;
int i;
@@ -277,7 +275,11 @@
} // end if (curves.size() == 1)
- assert(curves.size() == 2);
+ // assert(curves.size() == 2);
+ if(curves.size() != 2)
+ {
+ break;
+ }
TopologyEntity* topo = curves.get()->topology_entity();
refedge1 = CAST_TO(topo, RefEdge);
@@ -339,13 +341,18 @@
end_result = result_curve;
}
- RefEdge* result = dynamic_cast<RefEdge*>(end_result->topology_entity());
-
-
+ RefEdge* result = NULL;
+ if(end_result)
+ result = dynamic_cast<RefEdge*>(end_result->topology_entity());
+
+ RefEdge* dead = NULL;
+ if(result)
+ {
// notify observers that one edge is being composited into another
// TODO - make a simple function for this notification since it is times????
- RefEdge* dead = result != refedge1 ? refedge1 : result != refedge2 ? refedge2 : 0;
- update_combined_edges( result, dead );
+ dead = result != refedge1 ? refedge1 : result != refedge2 ? refedge2 : 0;
+ update_combined_edges( result, dead );
+ }
if ( result && update_dag )
{
@@ -451,7 +458,11 @@
{
RefFace* face1 = coedges.get()->get_ref_face();
RefFace* face2 = coedges.next()->get_ref_face();
- if (face_list.is_in_list(face1) && face_list.is_in_list(face2))
+ // Check to make sure both faces are in the faces we are compositing
+ // and also make sure the faces are not the same otherwise we
+ // will composite out hardlines in one of the faces.
+ if (face1 != face2 &&
+ face_list.is_in_list(face1) && face_list.is_in_list(face2))
continue;
}
@@ -464,7 +475,7 @@
PRINT_ERROR("Cannot create composites from the specified surfaces.\n");
return 0;
}
-
+
edge_list.reset();
for( i = edge_list.size(); i--; )
{
@@ -1525,9 +1536,8 @@
if(DEBUG_FLAG(87))
{
GMem gmem;
- int count;
- curve->get_geometry_query_engine()->get_graphics(curve,count,&gmem);
- GfxDebug::draw_polyline(gmem.point_list(),count,CUBIT_RED);
+ curve->get_geometry_query_engine()->get_graphics(curve,&gmem);
+ GfxDebug::draw_polyline(gmem.point_list(),gmem.pointListCount,CUBIT_RED);
GfxDebug::flush();
}
@@ -2163,7 +2173,7 @@
for ( i = s_itor->size(); i--; )
s_itor->get_and_step()->marked(0);
}
-
+
// composite faces
for ( s_itor = face_sets.begin(); s_itor != face_sets.end(); ++s_itor )
{
@@ -2176,7 +2186,7 @@
else
result = CUBIT_FAILURE;
}
-
+
return result;
}
Modified: cgm/branches/cubit/geom/virtual/FacetProjectTool.cpp
===================================================================
--- cgm/branches/cubit/geom/virtual/FacetProjectTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/FacetProjectTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -70,29 +70,36 @@
// make the PST edges and faces from the coordinates and connections.
PST_Edge::make_facets( coordinates, connections, GEOMETRY_RESABS, facet_edges );
DLIList<PST_Face*> faces;
- PST_Edge::faces( facet_edges, faces );
- populate_data(faces);
- // Order the orignal points by sequence number. New points
- // will be appended in order.
- pointList.sort(&sequence_compare_pts);
-
- // Do the work
- CubitBoolean point_changed;
- do_projection(segments, point_changed, tolerance_length);
-
- // fill in segmentPoints
- assert (segPoints.size() == segments.size());
- segmentPoints.resize( segPoints.size() );
- segPoints.reset();
CubitStatus success = CUBIT_SUCCESS;
- for ( i = 0; i < segPoints.size(); i++ )
+ if(facet_edges.size() > 0)
{
- PST_Point* pt = segPoints.get_and_step();
- segmentPoints[i] = pt ? pt->sequence : -1;
- if (point_changed)
- success = CUBIT_FAILURE;
+
+ PST_Edge::faces( facet_edges, faces );
+ populate_data(faces);
+
+ // Order the orignal points by sequence number. New points
+ // will be appended in order.
+ pointList.sort(&sequence_compare_pts);
+
+ // Do the work
+ CubitBoolean point_changed;
+ success = do_projection(segments, point_changed, tolerance_length);
+
+ // fill in segmentPoints
+// assert (segPoints.size() == segments.size());
+ segmentPoints.resize( segPoints.size() );
+ segPoints.reset();
+ for ( i = 0; i < segPoints.size(); i++ )
+ {
+ PST_Point* pt = segPoints.get_and_step();
+ segmentPoints[i] = pt ? pt->sequence : -1;
+ if (point_changed)
+ success = CUBIT_FAILURE;
+ }
}
+ else
+ success = CUBIT_FAILURE;
if (!success)
{
@@ -808,20 +815,24 @@
PST_Point* start_point = last_point;
PST_Point* end_point = end_pt;
- project( last_point, end_pt );
- if ((*start_point - *last_point).length_squared() > TOL_SQR)
+ if(project( last_point, end_pt ) == CUBIT_SUCCESS)
{
- segPoints.move_to(start_point);
- segPoints.change_to(last_point);
- point_changed = CUBIT_TRUE;
+ if ((*start_point - *last_point).length_squared() > TOL_SQR)
+ {
+ segPoints.move_to(start_point);
+ segPoints.change_to(last_point);
+ point_changed = CUBIT_TRUE;
+ }
+ if ((*end_pt - *end_point).length_squared() > TOL_SQR)
+ {
+ segPoints.move_to(end_point);
+ segPoints.change_to(end_pt);
+ point_changed = CUBIT_TRUE;
+ }
+ last_point = end_pt;
}
- if ((*end_pt - *end_point).length_squared() > TOL_SQR)
- {
- segPoints.move_to(end_point);
- segPoints.change_to(end_pt);
- point_changed = CUBIT_TRUE;
- }
- last_point = end_pt;
+ else
+ return CUBIT_FAILURE;
} // end for( i = segments )
@@ -846,7 +857,7 @@
//-------------------------------------------------------------------------
CubitStatus FacetProjectTool::project( PST_Point* &start, PST_Point* &end )
{
- PST_Edge* edge,* closest_edge;
+ PST_Edge* edge,* closest_edge, *last_closest_edge=NULL;
PST_Face* closest_face;
PST_Point* point;
PST_Point* start_point = start;
@@ -891,10 +902,14 @@
// Get face or edge adjacent to start and closest to the polyline segment
stat = next_around_point( start_point, *end, closest_face, closest_edge,
- is_boundary_edge );
+ is_boundary_edge, last_closest_edge);
+
+ if(closest_edge)
+ last_closest_edge = closest_edge;
+
if (!stat || (closest_face && closest_edge))
{
- assert(false);
+ // assert(false);
return stat;
}
@@ -1003,7 +1018,12 @@
// Otherwise closest point to segment end is in the interior
// of the edge -- split the edge.
else
- point = split_edge( closest_edge, t_edge );
+ {
+ if(start_point != closest_edge->start_point())
+ point = split_edge( closest_edge, 1.0 - t_edge );
+ else
+ point = split_edge( closest_edge, t_edge );
+ }
}
} // if(closest_edge)
@@ -1070,7 +1090,8 @@
const CubitVector& seg_end,
PST_Face*& closest_face,
PST_Edge*& closest_edge,
- CubitBoolean & is_boundary_edge )
+ CubitBoolean & is_boundary_edge,
+ PST_Edge *last_closest_edge)
{
DLIList<PST_Face*> face_list;
DLIList<PST_Edge*> boundary_edges;
@@ -1176,7 +1197,7 @@
const double dist_sqr =
tangent.length_squared() - dot_prod * dot_prod / prev.length_squared();
- if (dist_sqr <= shortest_dist_sqr)
+ if (dist_sqr <= shortest_dist_sqr && coedge->edge() != last_closest_edge)
{
closest_face = 0;
closest_edge = coedge->edge();
@@ -1219,7 +1240,7 @@
const double dist_sqr =
tangent.length_squared() - dot_prod * dot_prod / edge_tan.length_squared();
- if (dist_sqr < shortest_dist_sqr)
+ if (dist_sqr < shortest_dist_sqr && edge != last_closest_edge)
{
closest_edge = edge;
is_boundary_edge = CUBIT_TRUE;
Modified: cgm/branches/cubit/geom/virtual/FacetProjectTool.hpp
===================================================================
--- cgm/branches/cubit/geom/virtual/FacetProjectTool.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/FacetProjectTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -216,7 +216,8 @@
const CubitVector& segment_end,
PST_Face*& closest_face,
PST_Edge*& closest_edge,
- CubitBoolean & is_boundary_edge );
+ CubitBoolean & is_boundary_edge,
+ PST_Edge *last_closest_edge);
private:
Modified: cgm/branches/cubit/geom/virtual/Faceter.cpp
===================================================================
--- cgm/branches/cubit/geom/virtual/Faceter.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/Faceter.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -583,10 +583,8 @@
GMem curve_graphics;
const double dist_tol = GEOMETRY_RESABS;
const double dist_tol_sqr = dist_tol*dist_tol;
- int n;
Curve* curve_ptr = curve->get_curve_ptr();
- curve_ptr->get_geometry_query_engine()->get_graphics(
- curve_ptr, n, &curve_graphics );
+ curve_ptr->get_geometry_query_engine()->get_graphics( curve_ptr, &curve_graphics );
GPoint* gp = curve_graphics.point_list();
CubitPoint* last = (CubitPoint*) new FaceterPointData( gp->x, gp->y, gp->z );
Modified: cgm/branches/cubit/geom/virtual/ImprintBoundaryTool.cpp
===================================================================
--- cgm/branches/cubit/geom/virtual/ImprintBoundaryTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/ImprintBoundaryTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -394,9 +394,8 @@
//make sure the segments are larger than the tolerance.
const double dist_tol = 2*myTolerance + .5*myTolerance;// + .05*myTolerance;
//const double dist_tol_sqr = dist_tol*dist_tol;
- int n;
Curve* curve_ptr = curve->get_curve_ptr();
- curve_ptr->get_geometry_query_engine()->get_graphics( curve_ptr, n, &curve_graphics );
+ curve_ptr->get_geometry_query_engine()->get_graphics( curve_ptr, &curve_graphics );
GPoint* gp = curve_graphics.point_list();
ImprintPointData* last = new ImprintPointData( gp[0].x, gp[0].y, gp[0].z );
@@ -6006,6 +6005,14 @@
return NULL;
}
+ bool start_vertex_is_free = true;
+ if( start->num_parent_ref_entities() )
+ start_vertex_is_free = false;
+
+ bool end_vertex_is_free = true;
+ if( end->num_parent_ref_entities() )
+ end_vertex_is_free = false;
+
DLIList<CoEdgeSM*> coedgesms;
GeometryEntity *ge = start->get_geometry_entity_ptr();
Point *start_psm = CAST_TO(ge, Point);
@@ -6022,6 +6029,12 @@
return (RefEdge*)NULL;
}
+ //if vertices are consumed....notify that they are gone.
+ if( start_vertex_is_free )
+ start->notify_all_observers( TOP_LEVEL_ENTITY_DESTRUCTED );
+ if( end_vertex_is_free )
+ end->notify_all_observers( TOP_LEVEL_ENTITY_DESTRUCTED );
+
Curve *new_curve_ptr = (Curve*) new_facet_curve;
return GeometryQueryTool::instance()->make_RefEdge(new_curve_ptr);
}
Modified: cgm/branches/cubit/geom/virtual/Makefile.am
===================================================================
--- cgm/branches/cubit/geom/virtual/Makefile.am 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/Makefile.am 2010-01-06 19:22:14 UTC (rev 3423)
@@ -60,6 +60,7 @@
PartSurfFacetTool.cpp \
PST_Data.cpp \
SegmentedCurve.cpp \
+ SplitCompositeSurfaceTool.cpp \
SubCurve.cpp \
SubEntitySet.cpp \
SubSurface.cpp \
@@ -115,6 +116,7 @@
PartitionSurface.hpp \
PartitionTool.hpp \
SegmentedCurve.hpp \
+ SplitCompositeSurfaceTool.hpp \
SplitSurfaceVirtual.hpp \
SubCurve.hpp \
SubEntitySet.hpp \
Modified: cgm/branches/cubit/geom/virtual/PST_Data.cpp
===================================================================
--- cgm/branches/cubit/geom/virtual/PST_Data.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/PST_Data.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -960,11 +960,13 @@
{
PST_Face* new_face
= PST_Edge::create_face( ptlist[i1], ptlist[i2], ptlist[i3] );
- if( new_face )
+ if( new_face ){
face_list.append(new_face);
- else
+ new_face->sequence = i;
+ }
+ else{
fail_count++;
- new_face->sequence = i;
+ }
}
}
@@ -975,11 +977,14 @@
delete [] ptindex_list;
delete [] ptlist;
- PST_Edge::edges( face_list, edge_list );
- validate( edge_list, true );
- bool debug1 = false;
- if (debug1)
- debug_draw_edges( edge_list, CUBIT_BLUE, CUBIT_RED, true );
+ if(fail_count == 0)
+ {
+ PST_Edge::edges( face_list, edge_list );
+ validate( edge_list, true );
+ bool debug1 = false;
+ if (debug1)
+ debug_draw_edges( edge_list, CUBIT_BLUE, CUBIT_RED, true );
+ }
}
int PST_Point::validate(CubitBoolean print)
Modified: cgm/branches/cubit/geom/virtual/PartSurfFacetTool.cpp
===================================================================
--- cgm/branches/cubit/geom/virtual/PartSurfFacetTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/PartSurfFacetTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -569,10 +569,21 @@
// Get real points on surface boundary
mySurface->get_points(geom_points);
- geom_points.last();
- for (i = geom_points.size(); i--; )
- if (!geom_points.step_and_get()->real_point())
- geom_points.change_to(0);
+ for (i = 0; i < geom_points.size(); i++ )
+ {
+ if (!geom_points[i]->real_point())
+ geom_points[i] = 0;
+ // also process for hardpoints
+ if (geom_points[i])
+ {
+ PartitionCurve* curve = geom_points[i]->next_curve();
+ if ( curve->measure() < GEOMETRY_RESABS &&
+ curve->start_point() == curve->end_point() )
+ {
+ geom_points[i] = 0;
+ }
+ }
+ }
geom_points.remove_all_with_value(0);
// Group geometric points into boundary and interior sets
@@ -648,6 +659,13 @@
PartitionPoint* start_point = coedge->start_point();
PartitionPoint* end_point = coedge->end_point();
+ // Hardpoints (meeting all cases below) are a special
+ // case loop that should not be handled in the partitioning.
+ if (loop->num_coedges() == 1 &&
+ first_curve->measure() < GEOMETRY_RESABS &&
+ start_point == end_point)
+ break;
+
// Get list of curves until next real vertex
curve_set.clean_out();
curve_set.append(first_curve);
@@ -665,9 +683,8 @@
for (i = curve_set.size(); i--; )
{
GMem gmem;
- int junk;
PartitionCurve* c = curve_set.get_and_step();
- c->get_geometry_query_engine()->get_graphics( c, junk, &gmem );
+ c->get_geometry_query_engine()->get_graphics( c, &gmem );
GfxDebug::draw_polyline(gmem.point_list(), gmem.pointListCount, CUBIT_RED );
}
GfxDebug::flush();
@@ -1482,7 +1499,6 @@
{
if (!collapse_edge(new_point, prev_point, &old_facets))
{
- assert(0);
return CUBIT_FAILURE;
}
std::swap(prev_point, new_point);
@@ -1576,7 +1592,6 @@
{
if (!collapse_edge(curve_point, prev_point, &old_facets))
{
- assert(0);
return CUBIT_FAILURE;
}
std::swap(curve_point, prev_point);
Modified: cgm/branches/cubit/geom/virtual/PartitionEngine.cpp
===================================================================
--- cgm/branches/cubit/geom/virtual/PartitionEngine.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/PartitionEngine.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -49,6 +49,7 @@
#include "CompositeCurve.hpp"
#include "PartitionLumpImprint.hpp"
#include "GfxDebug.hpp"
+#include "BridgeManager.hpp"
#include "CADefines.hpp"
@@ -64,8 +65,25 @@
std::vector<CubitFacetData*> &facet_list,
std::vector<CubitFacetEdgeData*> replacement_edges[3]);
-PartitionEngine::~PartitionEngine() {}
+PartitionEngine* PartitionEngine::instance_ = NULL;
+
+
+PartitionEngine::~PartitionEngine()
+{
+ GeometryQueryTool::instance()->unregister_intermediate_engine(this);
+}
+
+void PartitionEngine::delete_instance()
+{
+ if( NULL != instance_ )
+ {
+ delete instance_;
+ instance_ = NULL;
+ }
+}
+
+
//-------------------------------------------------------------------------
// Purpose : Constructor
//
@@ -92,7 +110,12 @@
//-------------------------------------------------------------------------
PartitionEngine& PartitionEngine::instance()
{
- static PartitionEngine* instance_ = new PartitionEngine();
+ if( instance_ == NULL )
+ {
+ instance_ = new PartitionEngine();
+ assert( instance != NULL );
+ }
+
return *instance_;
}
@@ -717,6 +740,11 @@
return false;
}
+bool PartitionEngine::is_composite(TopologyBridge *bridge)
+{
+ return false;
+}
+
//-------------------------------------------------------------------------
// Purpose : Destroy a shell
//
@@ -1629,6 +1657,12 @@
loop2->remove( coedge2 );
assert( loop2->first_coedge() == 0 );
surf2->remove( loop2 );
+ if( loop1->num_coedges() == 0 )
+ {
+ surf1->remove( loop1 );
+ delete loop1;
+ }
+
delete loop2;
}
@@ -1943,14 +1977,32 @@
{
edges.clean_out();
curve->get_facet_data( edges );
- edges.reset();
- edge = edges.get();
- CubitPoint* start_pt = curve->start_point()->facet_point();
- bool forward = edge->point(0) == start_pt;
- assert( forward || edge->point(1) == start_pt );
- if ( coe->sense() == CUBIT_REVERSED )
- forward = !forward;
- face = find_facet( edge, forward, new_surf );
+ if (edges.size() > 0) // normal facet
+ {
+ edges.reset();
+ edge = edges.get();
+ CubitPoint* start_pt = curve->start_point()->facet_point();
+ bool forward = edge->point(0) == start_pt;
+ assert( forward || edge->point(1) == start_pt );
+ if ( coe->sense() == CUBIT_REVERSED )
+ forward = !forward;
+ face = find_facet( edge, forward, new_surf );
+ }
+ else // this is a hardpoint there is a curve with no facets (length)
+ // and the start and end points are the same
+ {
+ Point* hardpoint = curve->start_point()->real_point();
+ if (hardpoint && curve->start_point() == curve->end_point() )
+ {
+ CubitVector hardpoint_coord = hardpoint->coordinates();
+ CubitVector new_closest, old_closest;
+ new_surf->closest_point_trimmed( hardpoint_coord, new_closest );
+ surface->closest_point_trimmed( hardpoint_coord, old_closest );
+ // It appears that the new_surf is really the original surface
+ if ( new_closest.length_squared() > old_closest.length_squared() )
+ face = reinterpret_cast<CubitFacetData*>(1); // just set the point to non-zero (true)
+ }
+ }
}
if( face )
@@ -2285,8 +2337,17 @@
if (count < polyline_pts.size())
{
- for (i = 0; i < polyline_pts.size(); i++)
- *(segment_points[i]) = polyline_pts[i]->coordinates();
+ for( i = 0; i < polyline_pts.size(); i++ )
+ {
+ if( polyline_pts[i] )
+ {
+ *(segment_points[i]) = polyline_pts[i]->coordinates();
+ }
+ else
+ {
+ return CUBIT_FAILURE;
+ }
+ }
}
}
@@ -2951,10 +3012,12 @@
}
else
{
- assert(pt_index >= 0 && pt_index < cubit_points.size());
- CubitPoint* pt = cubit_points.next( pt_index );
- CubitPointData* ptd = dynamic_cast<CubitPointData*>(pt);
- assert(!!ptd);
+ CubitPointData* ptd = NULL;
+ if(pt_index >= 0 && pt_index < cubit_points.size())
+ {
+ CubitPoint* pt = cubit_points.next( pt_index );
+ ptd = dynamic_cast<CubitPointData*>(pt);
+ }
polyline_points.append(ptd);
}
}
@@ -3350,9 +3413,9 @@
Lump* PartitionEngine::insert_surface( Surface* surface, Lump* lump)
{
GMem gmem;
- int i, num_tri, num_pts, num_facets;
+ int i;
CubitStatus status = surface->get_geometry_query_engine()->
- get_graphics( surface, num_tri, num_pts, num_facets, &gmem );
+ get_graphics( surface, &gmem );
if( !status )
{
@@ -3360,8 +3423,9 @@
"get_graphics failed for surface.\n");
return 0;
}
+
+ int num_pts = gmem.pointListCount;
- assert(gmem.pointListCount == num_pts && gmem.fListCount == num_facets );
CubitPointData** ptarray = new CubitPointData*[num_pts];
GPoint *p_itor = gmem.point_list();
GPoint *p_end = p_itor + num_pts;
@@ -3371,7 +3435,7 @@
DLIList<CubitFacetData*> facets;
int* f_itor = gmem.facet_list();
- int* f_end = f_itor + num_facets;
+ int* f_end = f_itor + gmem.fListCount;
i = 0;
for( ; f_itor < f_end ; f_itor += (1 + *f_itor) )
{
@@ -4820,11 +4884,14 @@
polyline_edges, polyline_pts );
while( positions.size() )
{
- assert(polyline_pts.size());
CubitVector* position = positions.pop();
- CubitPointData* point = polyline_pts.pop();
- if (point->check_inverted_facets(*position))
- point->set(*position);
+ if(s)
+ {
+ // assert(polyline_pts.size());
+ CubitPointData* point = polyline_pts.pop();
+ if (point && point->check_inverted_facets(*position))
+ point->set(*position);
+ }
delete position;
}
delete attrib;
@@ -6215,8 +6282,31 @@
void PartitionEngine::clean_out_deactivated_geometry()
{
}
-void PartitionEngine::remove_modified(DLIList<TopologyBridge*>& geometry_list)
+void PartitionEngine::remove_modified(DLIList<Surface*> &all_surfs,
+ DLIList<Curve*> &all_curves, DLIList<Point*> &all_pts)
{
}
+void PartitionEngine::get_tbs_with_bridge_manager_as_owner( TopologyBridge *source_bridge,
+ DLIList<TopologyBridge*> &tbs )
+{
+ SubEntitySet* set = dynamic_cast<SubEntitySet*>(source_bridge->owner());
+ if( !set )
+ return;
+
+ DLIList<PartitionEntity*> entity_list;
+ set->get_sub_entities( entity_list );
+ DLIList<TopologyBridge*> temp_list;
+ CAST_LIST( entity_list, temp_list, TopologyBridge );
+
+ int i;
+ for( i=temp_list.size(); i--; )
+ {
+ if( temp_list.get()->bridge_manager() )
+ tbs.append( temp_list.get() );
+ temp_list.step();
+ }
+ return;
+}
+
Modified: cgm/branches/cubit/geom/virtual/PartitionEngine.hpp
===================================================================
--- cgm/branches/cubit/geom/virtual/PartitionEngine.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/PartitionEngine.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -65,14 +65,17 @@
public:
bool is_partition(TBOwner *bridge_owner);
bool is_composite(TBOwner *bridge_owner);
+ bool is_composite(TopologyBridge *bridge);
virtual void remove_imprint_attributes_after_modify
( DLIList<BodySM*> &old_sms,
DLIList<BodySM*> &new_sms ){};
virtual void push_imprint_attributes_before_modify
( DLIList<BodySM*> &body_sms ){};
- virtual void attribute_after_imprinting( DLIList<TopologyBridge*> &new_tbs,
+ virtual void push_named_attributes_to_curves_and_points
+ ( DLIList<TopologyBridge*> &tb_list, const char *name_in ){};
+ virtual void attribute_after_imprinting( DLIList<TopologyBridge*> &new_tbs,
DLIList<TopologyBridge*> &att_tbs,
- DLIList<BodySM*> &new_sms,
+ DLIList<TopologyBridge*> &tb_list,
DLIList<Body*> &old_bodies){};
virtual void remove_attributes_from_unmodifed_virtual(DLIList<TopologyBridge*> &bridges){};
@@ -82,6 +85,7 @@
/** Get singleton instance */
static PartitionEngine& instance();
+ static void delete_instance();
int level() const { return SUBCOMP_PARTITION_LAYER; }
@@ -290,8 +294,11 @@
void remove_attributes( DLIList<TopologyBridge*> &bridge_list );
//remove Composite attributes off of topology bridges
- void remove_modified(DLIList<TopologyBridge*>& geometry_list);
+ virtual void remove_modified(DLIList<Surface*> &all_surfs,
+ DLIList<Curve*> &all_curves, DLIList<Point*> &all_pts);
+ void get_tbs_with_bridge_manager_as_owner( TopologyBridge *source_bridge,
+ DLIList<TopologyBridge*> &tbs );
private:
CubitStatus notify_transform_internal( TopologyBridge* bridge,
@@ -600,6 +607,8 @@
/** Restore lump partitions from attributes */
CubitStatus restore_from_attrib( Lump* partitioned_lump );
+ static PartitionEngine* instance_;
+
/** Map for getting a SubEntitySet given its unique ID */
std::map<int,SubEntitySet*> uniqueIdMap;
Modified: cgm/branches/cubit/geom/virtual/PartitionLoop.cpp
===================================================================
--- cgm/branches/cubit/geom/virtual/PartitionLoop.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/PartitionLoop.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -20,6 +20,27 @@
}
//-------------------------------------------------------------------------
+// Purpose : The purpose of this function is to see if a loop is an external
+// or internal loop of a surface.
+//
+// Special Notes :
+//
+// Creator : Jonathan Bugman
+//
+// Creation Date : 9/9/2008
+//-------------------------------------------------------------------------
+CubitBoolean PartitionLoop::is_external()
+{
+ PRINT_ERROR( "This command is not supported with this engine.\n");
+ return CUBIT_FAILURE;
+}
+
+LoopType PartitionLoop::loop_type()
+{
+ return LOOP_TYPE_UNKNOWN;
+}
+
+//-------------------------------------------------------------------------
// Purpose : Destructor
//
// Special Notes :
Modified: cgm/branches/cubit/geom/virtual/PartitionLoop.hpp
===================================================================
--- cgm/branches/cubit/geom/virtual/PartitionLoop.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/PartitionLoop.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -27,6 +27,14 @@
PartitionSurface* get_surface() const;
//void surface( PartitionSurface* );
+ virtual CubitBoolean is_external() ;
+ //R CubitBoolean
+ //R- CUBIT_TRUE/CUBIT_FALSE
+ //- Returns CUBIT_TRUE if the Loop is an external Loop and CUBIT_FALSE
+ //- otherwise.
+
+ virtual LoopType loop_type() ;
+
PartitionCoEdge* first_coedge( );
PartitionCoEdge* next_coedge( PartitionCoEdge* after_this );
PartitionCoEdge* prev_coedge( PartitionCoEdge* before_this );
Modified: cgm/branches/cubit/geom/virtual/PartitionSurface.cpp
===================================================================
--- cgm/branches/cubit/geom/virtual/PartitionSurface.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/PartitionSurface.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -173,7 +173,8 @@
if( point && !point->num_adj_facets() ) {
if ( TDVGFacetOwner::get(point) ) {
ppoint = dynamic_cast<PartitionPoint*>(TDVGFacetOwner::get(point));
- ppoint->facet_point(0);
+ if( ppoint )
+ ppoint->facet_point(0);
}
delete point;
}
@@ -320,6 +321,7 @@
do
{
PartitionCurve* curve = coedge->get_curve();
+
list.append( curve->start_point() );
list.append( curve->end_point() );
@@ -985,14 +987,11 @@
//assert(are_marks_cleared());
CubitStatus res = CUBIT_SUCCESS;
- int num_triangles;
- int num_points;
- int num_facets;
GMem gMem;
// TODO - tolerance arguments are defaulted. Do we need to specify?
res = real_surf->get_geometry_query_engine()->
- get_graphics(real_surf, num_triangles, num_points, num_facets, &gMem);
+ get_graphics(real_surf, &gMem);
if( !res )
return CUBIT_FAILURE;
@@ -1003,7 +1002,6 @@
if( old_count != gMem.pointListCount ) {
PRINT_WARNING("Possible invalid facetting for surface. "
"Coincident points found.\n");
- num_points = gMem.pointListCount;
}
DLIList<CubitFacetData*> surf_facets;
@@ -1021,8 +1019,23 @@
}
int junk = 0;
- for ( i = 0; i < gMem.fListCount; i += 4 ) {
- if(gMem.facet_list()[i] != 3) {
+ bool fail_out = false;
+ CubitPoint *p1, *p2, *p3;
+ for ( i = 0; i < gMem.fListCount; i += 4 )
+ {
+ if(gMem.facet_list()[i] != 3)
+ fail_out = true;
+ else
+ {
+ p1 = point_array[ gMem.facet_list()[i+1] ];
+ p2 = point_array[ gMem.facet_list()[i+2] ];
+ p3 = point_array[ gMem.facet_list()[i+3] ];
+
+ if(p1 == p2 || p1 == p3 || p2 == p3)
+ fail_out = true;
+ }
+ if(fail_out == true)
+ {
PRINT_ERROR("Non-triangular facet encountered. Aborting.\n");
while (surf_facets.size())
delete surf_facets.pop();
@@ -1031,12 +1044,11 @@
delete [] point_array;
return CUBIT_FAILURE;
}
-
- CubitFacetData* facet = new CubitFacetData(
- point_array[ gMem.facet_list()[i+1] ],
- point_array[ gMem.facet_list()[i+2] ],
- point_array[ gMem.facet_list()[i+3] ], &junk );
- surf_facets.append(facet);
+ else
+ {
+ CubitFacetData* facet = new CubitFacetData(p1, p2, p3, &junk );
+ surf_facets.append(facet);
+ }
}
delete [] point_array;
Modified: cgm/branches/cubit/geom/virtual/PartitionTool.cpp
===================================================================
--- cgm/branches/cubit/geom/virtual/PartitionTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/PartitionTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -64,6 +64,7 @@
#include "RefEntityFactory.hpp"
#include "GeometryQueryTool.hpp"
#include "MergeTool.hpp"
+#include "CubitUndo.hpp"
#include "TDUPtr.hpp"
#include <vector>
@@ -378,9 +379,8 @@
DLIList<RefEdge*> new_edges;
GMem edge_facets;
- int numpts;
Curve* curve = edge_ptr->get_curve_ptr();
- if( ! curve->get_geometry_query_engine()->get_graphics( curve, numpts, &edge_facets ) )
+ if( ! curve->get_geometry_query_engine()->get_graphics( curve, &edge_facets ) )
{
return CUBIT_FAILURE;
}
@@ -436,7 +436,7 @@
for (j = 0; j < edge_list.size(); j++)
{
the_edge = edge_list.get_and_step();
- the_edge->closest_point(pos, closest);
+ the_edge->closest_point_trimmed(pos, closest);
if ( (pos - closest).length_squared() > TOL_SQR )
continue;
@@ -522,6 +522,13 @@
pos = *segments.step_and_get();
}
}
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<RefFace*> tmp_face_list(1);
+ tmp_face_list.append( face_ptr );
+ CubitUndo::save_state_with_cubit_file( tmp_face_list );
+ }
DLIList<TopologyBridge*> bridge_list;
face_ptr->bridge_manager()->get_bridge_list( bridge_list );
@@ -548,7 +555,12 @@
if (!new_surf && level_of_recursion == 0)
{
level_of_recursion++;
- return insert_edge( face_ptr, segments, CUBIT_FALSE, new_edges, level_of_recursion);
+ RefFace *return_face = insert_edge( face_ptr, segments, CUBIT_FALSE, new_edges, level_of_recursion);
+
+ if( CubitUndo::get_undo_enabled() && return_face == NULL )
+ CubitUndo::remove_last_undo();
+
+ return return_face;
}
if(!new_surf)
@@ -556,6 +568,9 @@
CompositeSurface* cs = dynamic_cast<CompositeSurface*>(old_surf);
if(cs)
{
+ Surface *tmp_srf = cs->get_surface(0);
+ GeometryQueryEngine *gqe = tmp_srf->get_geometry_query_engine();
+ double tmp_tol = gqe->get_sme_resabs_tolerance();
DLIList<Curve*> hidden_curves;
cs->get_hidden_curves(hidden_curves);
int k;
@@ -568,12 +583,12 @@
int curve_on_polyline = 1;
cur_curve->get_param_range(min, max);
cur_curve->position_from_u(min, start_vec);
- if(!int_tool.point_on_polyline(start_vec, segments))
+ if(!int_tool.point_on_polyline(start_vec, segments, &tmp_tol))
curve_on_polyline = 0;
if(curve_on_polyline)
{
cur_curve->position_from_u(max, end_vec);
- if(!int_tool.point_on_polyline(end_vec, segments))
+ if(!int_tool.point_on_polyline(end_vec, segments, &tmp_tol))
curve_on_polyline = 0;
}
if(curve_on_polyline)
@@ -586,7 +601,7 @@
for(n=0; n<num_mid_pts && curve_on_polyline; ++n)
{
cur_curve->position_from_u(cur_t, cur_vec);
- if(!int_tool.point_on_polyline(cur_vec, segments))
+ if(!int_tool.point_on_polyline(cur_vec, segments, &tmp_tol))
curve_on_polyline = 0;
cur_t += dt;
}
@@ -695,12 +710,20 @@
}
if ( !removed_composite_curve && !new_edges.size() )
+ {
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
+
return 0;
+ }
DLIList<RefEntity*> ref_list;
CAST_LIST_TO_PARENT(new_edges, ref_list);
notify_partition( ref_list, face_ptr, result, face_ptr );
+ if( CubitUndo::get_undo_enabled() && status == CUBIT_FAILURE )
+ CubitUndo::remove_last_undo();
+
return status ? result : 0;
}
@@ -987,6 +1010,13 @@
CAST_LIST(bridge_list, surface_list, Surface);
assert(bridge_list.size() == surface_list.size());
surface_list.reset();
+
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<RefFace*> tmp_faces(1);
+ tmp_faces.append( face_ptr );
+ CubitUndo::save_state_with_cubit_file( tmp_faces );
+ }
// For each position in the list
positions.reset();
@@ -1082,6 +1112,10 @@
if (new_vertices.size() > 1)
new_vertices.uniquify_ordered();
+
+ if( CubitUndo::get_undo_enabled() && new_points.size() == 0 )
+ CubitUndo::remove_last_undo();
+
return rval;
}
@@ -1101,10 +1135,18 @@
DLIList<CubitVector> positions(1);
DLIList<RefVertex*> results(1);
positions.append(position);
+
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::save_state_with_cubit_file( face_ptr );
+
if (make_point_curves(face_ptr, positions, results) && results.size())
return results.get();
else
+ {
+ if( CubitUndo::get_undo_enabled() )
+ CubitUndo::remove_last_undo();
return 0;
+ }
}
@@ -1329,63 +1371,17 @@
{
RefEdge* edge = refedge_list.step_and_get();
PartPTCurve* point_curve = dynamic_cast<PartPTCurve*>(edge->get_curve_ptr());
- if ( !(point_curve || edge->marked() == 2) || !can_remove(edge) )
- refedge_list.change_to(0);
- else
+ SegmentedCurve* seg_curve = dynamic_cast<SegmentedCurve*>(edge->get_curve_ptr());
+ if((point_curve || (seg_curve && edge->marked() == 2)) &&
+ can_remove(edge))
{
- // If we got to this point we think this is an "interior" edge that
- // was introduced to partition a surface and we want to keep it
- // in the list for unpartitioning. However,
- // we need to do one final check. There are cases where
- // two surfaces share an edge before either one is partitioned.
- // Then both of them are partitioned in some way and so the
- // original shared edge gets replaced with partition edges and
- // partition coedges and when we get to this function it looks like
- // an "interior" edge and that it should be unpartitioned
- // even though it was an original edge in the model and should not
- // get unpartitioned. True "interior" partition edges will have the
- // same entitySet ptr for both of its coedges. Check if this is the
- // case and if it isn't mark the edge for removal from the list.
- DLIList<CoEdge*> cur_coedges;
- edge->get_co_edges(cur_coedges);
- int coedge_size = cur_coedges.size();
- Loop *loop_ptr;
- RefFace *face_ptr;
- Surface *surf_ptr;
- PartitionSurface *part_surf_ptr;
- SubEntitySet *common_sub_entity_set = NULL;
- SubEntitySet *cur_sub_entity_set;
- for(int g=0; g<coedge_size; g++)
- {
- CoEdge *cur_co_edge = cur_coedges.get_and_step();
- if(g==0)
- {
- if((loop_ptr = cur_co_edge->get_loop_ptr()) &&
- (face_ptr = loop_ptr->get_ref_face_ptr()) &&
- (surf_ptr = face_ptr->get_surface_ptr()) &&
- (part_surf_ptr = dynamic_cast<PartitionSurface*>(surf_ptr)))
- {
- common_sub_entity_set = &(part_surf_ptr->sub_entity_set());
- }
- }
- else
- {
- cur_sub_entity_set = NULL;
- if((loop_ptr = cur_co_edge->get_loop_ptr()) &&
- (face_ptr = loop_ptr->get_ref_face_ptr()) &&
- (surf_ptr = face_ptr->get_surface_ptr()) &&
- (part_surf_ptr = dynamic_cast<PartitionSurface*>(surf_ptr)))
- {
- cur_sub_entity_set = &(part_surf_ptr->sub_entity_set());
- }
- if(cur_sub_entity_set != common_sub_entity_set)
- {
- refedge_list.change_to(0);
- g = coedge_size;
- }
- }
- }
+ // Try to remove this partition.
}
+ else
+ {
+ // Don't try to remove this partition.
+ refedge_list.change_to(0);
+ }
edge->marked(0);
}
refedge_list.remove_all_with_value(0);
@@ -1449,18 +1445,26 @@
DLIList<CubitVector*> segments;
GMem gmem;
+ if( CubitUndo::get_undo_enabled() )
+ {
+ DLIList<RefFace*> tmp_ref_face_list(1);
+ tmp_ref_face_list.append( face_to_split );
+ CubitUndo::save_state_with_cubit_file( tmp_ref_face_list );
+ }
+
faces[0].append( face_to_split );
for (i = 0; i < split_curves.size(); i++ )
{
Curve* curve = split_curves.next(i);
GeometryQueryEngine* engine = curve->get_geometry_query_engine();
- if (!engine->get_graphics( curve, numpts, &gmem ))
+ if (!engine->get_graphics( curve, &gmem ))
{
status = CUBIT_FAILURE;
continue;
}
- assert( numpts == gmem.pointListCount);
+
+ numpts = gmem.pointListCount;
/*
This code causes a failure in virtual imprint because it compares
against the number of graphics curve facets. I think this is wrong but
@@ -1521,13 +1525,13 @@
if (curve->bridge_sense() == CUBIT_REVERSED)
{
CubitVector* p1 = new CubitVector;
- CubitStatus sta = curve->position_from_u( curve->end_param(), *p1 );
+ curve->position_from_u( curve->end_param(), *p1 );
segments.append( p1 );
}
else
{
CubitVector* p1 = new CubitVector;
- CubitStatus sta = curve->position_from_u( curve->start_param(), *p1 );
+ curve->position_from_u( curve->start_param(), *p1 );
segments.append( p1 );
}
@@ -1541,13 +1545,13 @@
if (curve->bridge_sense() == CUBIT_REVERSED)
{
CubitVector* p1 = new CubitVector;
- CubitStatus sta = curve->position_from_u( curve->start_param(), *p1 );
+ curve->position_from_u( curve->start_param(), *p1 );
segments.append( p1 );
}
else
{
CubitVector* p1 = new CubitVector;
- CubitStatus stat = curve->position_from_u( curve->end_param(), *p1 );
+ curve->position_from_u( curve->end_param(), *p1 );
segments.append( p1 );
}
}
@@ -1567,8 +1571,13 @@
while (segments.size())
delete segments.pop();
}
+
+ result_set = faces[split_curves.size()%2];
+
+ //surface might not have gotton split
+ if( CubitUndo::get_undo_enabled() && result_set.size() == 1)
+ CubitUndo::remove_last_undo();
- result_set = faces[split_curves.size()%2];
return status;
}
Modified: cgm/branches/cubit/geom/virtual/RemoveBlends.cpp
===================================================================
--- cgm/branches/cubit/geom/virtual/RemoveBlends.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/RemoveBlends.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -51,7 +51,7 @@
vec_lists.append( vec_list );
- sst.calculate_split_curves(the_face, locations, vec_lists, curve_list);
+ sst.calculate_split_curves(the_face, vec_lists, curve_list);
//int num_segs = 2;
//double fraction =.5;
@@ -76,6 +76,16 @@
DLIList<RefFace*> result_faces;
result = PartitionTool::instance()->
partition_face_by_curves( the_face, curve_list, result_faces, CUBIT_TRUE, &new_edges );
+ // clean up curves
+ while (curve_list.size())
+ {
+ Curve* curve = curve_list.pop();
+ if (curve)
+ {
+ GeometryQueryEngine* gqe = curve->get_geometry_query_engine();
+ gqe->delete_solid_model_entities(curve);
+ }
+ }
if( result == CUBIT_FAILURE )
{
PRINT_ERROR("Failed to partition surface %d into 2 distinct pieces\n", the_face->id());
Modified: cgm/branches/cubit/geom/virtual/SimplifyTool.cpp
===================================================================
--- cgm/branches/cubit/geom/virtual/SimplifyTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/SimplifyTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -43,6 +43,7 @@
DLIList<RefEdge*> respect_edge_list,
CubitBoolean respect_rounds,
CubitBoolean respect_imprints,
+ CubitBoolean local_normals,
CubitBoolean preview)
{
ref_volume_list.uniquify_unordered();
@@ -54,6 +55,7 @@
respect_edge_list,
respect_rounds,
respect_imprints,
+ local_normals,
preview);
if(preview)
@@ -68,6 +70,7 @@
DLIList<RefEdge*> respect_edge_list,
CubitBoolean respect_rounds,
CubitBoolean respect_imprints,
+ CubitBoolean local_normals,
CubitBoolean preview)
{
CubitStatus status = CUBIT_FAILURE;
@@ -95,6 +98,7 @@
respect_edge_list,
respect_rounds,
respect_imprints,
+ local_normals,
preview);
}
ref_face_list -= ref_faces_in_volume;
@@ -106,12 +110,57 @@
return CUBIT_SUCCESS;
}
+CubitStatus SimplifyTool::simplify_curves(DLIList<RefEdge*> ref_edge_list,
+ double angle_in,
+ DLIList<RefEdge*> respect_edge_list,
+ DLIList<RefVertex*> respect_vertex_list,
+ CubitBoolean respect_imprints,
+ CubitBoolean local_normals,
+ CubitBoolean preview)
+{
+ CubitStatus status = CUBIT_FAILURE;
+ ref_edge_list.uniquify_unordered();
+ while(ref_edge_list.size())
+ {
+ DLIList<RefEdge*> ref_edges_in_volume;
+ ref_edge_list.reset();
+ RefEdge* cur_edge = ref_edge_list.get_and_step();
+ RefVolume* cur_vol = cur_edge->ref_volume();
+ ref_edges_in_volume.append(cur_edge);
+ for(int i =1;i<ref_edge_list.size();i++)
+ {
+ RefEdge* edge = ref_edge_list.get_and_step();
+ if(edge->ref_volume() == cur_vol)
+ ref_edges_in_volume.append(edge);
+ }
+
+ if(ref_edges_in_volume.size()>1)
+ {
+ status = simplify_curves_in_volume(
+ ref_edges_in_volume,
+ angle_in,
+ respect_edge_list,
+ respect_vertex_list,
+ respect_imprints,
+ local_normals,
+ preview);
+ }
+ ref_edge_list -= ref_edges_in_volume;
+ }
+
+ if(preview)
+ GfxDebug::flush();
+
+ return CUBIT_SUCCESS;
+}
+
CubitStatus SimplifyTool::simplify_volume(RefVolume* ref_volume,
double angle_in,
DLIList<RefFace*> respect_face_list,
DLIList<RefEdge*> respect_edge_list,
CubitBoolean respect_rounds,
CubitBoolean respect_imprints,
+ CubitBoolean local_normals,
CubitBoolean preview)
{
DLIList<RefFace*> ref_face_list;
@@ -123,6 +172,7 @@
respect_edge_list,
respect_rounds,
respect_imprints,
+ local_normals,
preview);
}
@@ -135,6 +185,7 @@
DLIList<RefEdge*> respect_edge_list,
CubitBoolean respect_rounds,
CubitBoolean respect_imprints,
+ CubitBoolean local_normals,
CubitBoolean preview)
{
if(ref_face_list.size()==0)
@@ -238,12 +289,22 @@
if( !ref_volumes.size() || ref_volumes.size()==1 )
{
// Only add the ref_face if it meets the feature angle criteria
- if(composite_surfaces(seed_ref_face,ref_face_ptr,angle_in))
+ if(local_normals){
+ if(composite_surfaces_test_at_curves(seed_ref_face,ref_face_ptr,angle_in))
{
ref_face_ptr->marked( CUBIT_TRUE );
seed_faces.append(ref_face_ptr);
composite_faces.append(ref_face_ptr);
}
+ }
+ else{
+ if(composite_surfaces(seed_ref_face,ref_face_ptr,angle_in))
+ {
+ ref_face_ptr->marked( CUBIT_TRUE );
+ seed_faces.append(ref_face_ptr);
+ composite_faces.append(ref_face_ptr);
+ }
+ }
}
}
}
@@ -256,7 +317,7 @@
{
DLIList<RefEdge*> result_edges;
DLIList<RefFace*> result_faces;
- CubitStatus new_face = CompositeTool::instance()->composite(
+ CompositeTool::instance()->composite(
composite_faces,
result_faces,
result_edges);
@@ -313,8 +374,210 @@
PRINT_INFO("Simplified %d surfaces into %d surfaces\n",
combined_face_count,
new_face_count);
+ }
+
+ // make sure to set all of the surface markers to false
+ DLIList<RefFace*> marked_face_list;
+ ref_volume->ref_faces(marked_face_list);
+ for(int i =0;i<marked_face_list.size();i++)
+ marked_face_list[i]->marked(CUBIT_FALSE);
+
+ return CUBIT_SUCCESS;
+}
+
+CubitStatus SimplifyTool::simplify_curves_in_volume(
+ DLIList<RefEdge*> ref_edge_list,
+ double angle_in,
+ DLIList<RefEdge*> respect_edge_list,
+ DLIList<RefVertex*> respect_vertex_list,
+ CubitBoolean respect_imprints,
+ CubitBoolean local_normals,
+ CubitBoolean preview)
+{
+ if(local_normals){
+ PRINT_WARNING("When simplifying curves, 'local_normals' is currently ignored.\n");
+ }
+
+ if(ref_edge_list.size()==0)
+ {
+ PRINT_ERROR("No curves specified for simplification\n");
+ return CUBIT_FAILURE;
}
+ else if(ref_edge_list.size() == 1)
+ {
+ PRINT_ERROR("Only one curve specified for simplification\n");
+ return CUBIT_FAILURE;
+ }
+ RefVolume* ref_volume = ref_edge_list.get()->ref_volume();
+ if (NULL == ref_volume)
+ {
+ PRINT_WARNING("Simplifying free curves is not supported.\n");
+ return CUBIT_FAILURE;
+ }
+
+ DLIList<RefEdge*> seed_edges;
+ DLIList<RefVertex*> preview_vertices;
+ DLIList<RefVertex*> preview_removed;
+
+ if(preview)
+ ref_volume->ref_vertices(preview_vertices);
+
+ int j,k;
+
+ int new_edge_count = 0;
+ int combined_edge_count = 0;
+ ProgressTool *prog_ptr = 0;
+ if(ref_edge_list.size() > 100 )
+ {
+ char title[200];
+ if(preview)
+ sprintf(title, "Previewing Volume %d",ref_volume->id());
+ else
+ sprintf(title, "Simplifying Curves in Volume %d",ref_volume->id());
+
+ prog_ptr = AppUtil::instance()->progress_tool();
+ assert(prog_ptr != NULL);
+ prog_ptr->start(0,100, title);
+ }
+ int start_edge_count = ref_edge_list.size();
+ while(ref_edge_list.size())
+ {
+ DLIList<RefEdge*> composite_edges;
+ seed_edges.append_unique(ref_edge_list.pop());
+
+ for ( j = ref_edge_list.size(); j--; )
+ ref_edge_list.get_and_step()->marked( CUBIT_FALSE );
+
+ while(seed_edges.size())
+ {
+ RefEdge *seed_ref_edge = seed_edges.pop();
+ seed_ref_edge->marked(CUBIT_TRUE);
+
+ composite_edges.append(seed_ref_edge);
+
+ // Get the vertices
+ DLIList<RefVertex*> ref_vertex_list;
+ seed_ref_edge->ref_vertices( ref_vertex_list );
+ RefVertex *ref_vertex_ptr;
+ RefEdge *ref_edge_ptr;
+ for( k = ref_vertex_list.size(); k--; )
+ {
+ ref_vertex_ptr = ref_vertex_list.get_and_step();
+
+ // Don't go propagate across surface splits if the user asks for it
+ GeometryFeatureTool* gft = GeometryFeatureTool::instance();
+ if( respect_imprints &&
+ gft->feature_type(ref_vertex_ptr) == GeometryFeatureEngine::FEATURE_IMPRINT)
+ continue;
+
+ // Don't cross a curve if we want it respected
+ if(respect_vertex_list.is_in_list(ref_vertex_ptr))
+ continue;
+
+ DLIList<RefEdge*> attached_ref_edges;
+ ref_vertex_ptr->ref_edges( attached_ref_edges );
+
+ attached_ref_edges.remove(seed_ref_edge);
+ ref_edge_ptr = attached_ref_edges.size()!=0?attached_ref_edges.get():0;
+
+ // keep the face if we want it respected
+ if(attached_ref_edges.size() == 1 &&
+ respect_edge_list.is_in_list(attached_ref_edges.get()))
+ continue;
+
+ // Don't consider ref_faces that are already in the list
+ if( attached_ref_edges.size() == 1 &&
+ !ref_edge_ptr->marked())
+ {
+ DLIList<RefVolume*> ref_volumes;
+ ref_edge_ptr->ref_volumes( ref_volumes );
+ if( !ref_volumes.size() || ref_volumes.size()==1 )
+ {
+ // Only add the ref_face if it meets the feature angle criteria
+ if(composite_curves(seed_ref_edge,ref_edge_ptr,angle_in))
+ {
+ ref_edge_ptr->marked( CUBIT_TRUE );
+ seed_edges.append(ref_edge_ptr);
+ composite_edges.append(ref_edge_ptr);
+ }
+ }
+ }
+ }
+ }
+ composite_edges.uniquify_unordered();
+ ref_edge_list -= composite_edges;
+
+ if(!preview &&
+ composite_edges.size()>1)
+ {
+ DLIList<RefVertex*> result_vertices;
+ DLIList<RefEdge*> result_edges;
+ CompositeTool::instance()->composite(
+ composite_edges,
+ result_edges,
+ &result_vertices);
+
+ combined_edge_count +=composite_edges.size();
+ for(int m = result_edges.size();m--;)
+ result_edges.get_and_step()->marked(CUBIT_TRUE);
+
+ new_edge_count+=result_edges.size();
+ }
+ else if(preview)
+ {
+ int edge_count = composite_edges.size();
+ for(int i =0;i<edge_count;i++)
+ {
+ RefEdge* cur_comp_edge = composite_edges[i];
+ DLIList<RefVertex*> refvertices;
+ for(int j =0;j<edge_count;j++)
+ {
+ if(i==j) continue;
+ composite_edges[j]->ref_vertices(refvertices);
+ }
+
+ refvertices.uniquify_unordered();
+
+ DLIList<RefVertex*> temp_refvertices;
+ cur_comp_edge->ref_vertices(temp_refvertices);
+ refvertices.intersect_unordered(temp_refvertices);
+ preview_removed+=refvertices;
+ }
+ }
+
+ if(prog_ptr)
+ {
+ double frac = 1.0-(double)ref_edge_list.size()/(double)start_edge_count;
+ prog_ptr->percent(frac);
+ }
+ }
+
+ if(prog_ptr)
+ {
+ prog_ptr->end();
+ prog_ptr = 0;
+ }
+
+ if(preview)
+ {
+ preview_vertices -=preview_removed;
+ for(int c = preview_vertices.size();c--;)
+ GfxDebug::draw_ref_vertex(preview_vertices.get_and_step(),7);
+ }
+ else if(combined_edge_count>new_edge_count)
+ {
+ PRINT_INFO("Simplified %d curves into %d curves\n",
+ combined_edge_count,
+ new_edge_count);
+ }
+
+ // make sure to set all of the surface markers to false
+ DLIList<RefEdge*> marked_edge_list;
+ ref_volume->ref_edges(marked_edge_list);
+ for(int i =0;i<marked_edge_list.size();i++)
+ marked_edge_list[i]->marked(CUBIT_FALSE);
+
return CUBIT_SUCCESS;
}
@@ -339,6 +602,37 @@
return CUBIT_FALSE;
}
+CubitBoolean SimplifyTool::composite_curves(
+ RefEdge* seed_ref_edge,
+ RefEdge* ref_edge_ptr,
+ double angle_in)
+{
+ double angle;
+ CubitVector pos, norm1, norm2;
+
+ // Only add the ref_face if it meets the feature angle criteria
+ RefVertex* shared_vert = seed_ref_edge->common_ref_vertex( ref_edge_ptr );
+
+ CubitVector seed_tangent;
+ seed_ref_edge->tangent( shared_vert->coordinates(), seed_tangent );
+ // make this vector point away from the vertex along the edge
+ if( shared_vert == seed_ref_edge->end_vertex() )
+ seed_tangent *= -1;
+
+ CubitVector edge2_tangent;
+ ref_edge_ptr->tangent( shared_vert->coordinates(), edge2_tangent );
+ // make this vector point into the vertex along the edge
+ if( shared_vert == ref_edge_ptr->start_vertex() )
+ edge2_tangent *= -1;
+
+ angle = seed_tangent.interior_angle( edge2_tangent );
+
+ if( angle < angle_in)
+ return CUBIT_TRUE;
+
+ return CUBIT_FALSE;
+}
+
void SimplifyTool::process_rounds(RefVolume* ref_volume,
double min_radius,
double max_radius)
@@ -396,26 +690,22 @@
CubitVector &normal,
double &weight )
{
- int i;
- int num_tris, num_pnts, num_facets;
GMem g_mem;
unsigned short norm_tol = 30;
double dist_tol = -1.0;
ref_face->get_geometry_query_engine()->
- get_graphics(ref_face->get_surface_ptr(),num_tris, num_pnts, num_facets,
- &g_mem, norm_tol, dist_tol );
+ get_graphics(ref_face->get_surface_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;
ref_face->get_geometry_query_engine()->
- get_graphics(ref_face->get_surface_ptr(),num_tris, num_pnts, num_facets,
- &g_mem, norm_tol, dist_tol );
+ get_graphics(ref_face->get_surface_ptr(), &g_mem, norm_tol, dist_tol );
}
- if(num_tris < 1)
+ if(g_mem.fListCount < 1)
{
// Lets give up
PRINT_ERROR( "Unable to find average normal of a surface\n" );
@@ -432,7 +722,7 @@
GPoint* plist = g_mem.point_list();
int* facet_list = g_mem.facet_list();
int c = 0;
- for( i=0; i<num_tris; i++ )
+ for( ;c<g_mem.fListCount; )
{
p[0] = plist[facet_list[++c]];
p[2] = plist[facet_list[++c]];
@@ -472,3 +762,91 @@
return CUBIT_SUCCESS;
}
+
+
+
+CubitBoolean SimplifyTool::composite_surfaces_test_at_curves(
+ RefFace* seed_ref_face,
+ RefFace* ref_face_ptr,
+ double angle_in)
+{
+ double angle;
+
+ if(!maximum_angle_deviation(seed_ref_face, ref_face_ptr, angle_in, angle))
+ return CUBIT_FALSE;
+
+ if( angle < angle_in)
+ return CUBIT_TRUE;
+
+ return CUBIT_FALSE;
+}
+
+
+CubitBoolean SimplifyTool::maximum_angle_deviation(
+ RefFace* seed_ref_face,
+ RefFace* ref_face_ptr,
+ double angle_in,
+ double &angle_out)
+{
+ double max_angle = -360;
+ RefEdge* ref_edge = NULL;
+
+ double tol = angle_in / 2.0;
+
+
+ DLIList<RefEdge*> common_edges;
+ int num_edges = seed_ref_face->common_ref_edges(ref_face_ptr, common_edges);
+ if(num_edges != common_edges.size()){
+ PRINT_ERROR("Unexpected results. List size incorrect.\n");
+ return CUBIT_FALSE;
+ }
+
+ int i, j;
+ for(i=0; i<num_edges; i++){
+
+ GMem g_mem;
+ ref_edge = common_edges.get_and_step();
+
+ ref_edge->get_geometry_query_engine()->
+ get_graphics(ref_edge->get_curve_ptr(), &g_mem, tol);
+
+ if(g_mem.pointListCount < 2)
+ {
+ // Decrease tolerance and try again (we can get this for small features)
+ tol /= 2.;
+
+ ref_edge->get_geometry_query_engine()->
+ get_graphics(ref_edge->get_curve_ptr(), &g_mem, tol);
+ }
+
+ if(g_mem.pointListCount < 2)
+ {
+ // Lets give up
+ PRINT_ERROR( "Unable to find average normal of a curve\n" );
+ return CUBIT_FAILURE;
+ }
+
+ GPoint* plist = g_mem.point_list();
+
+ for( j=0; j<g_mem.pointListCount; j++ )
+ {
+ CubitVector p1(plist[j].x, plist[j].y, plist[j].z);
+
+
+ CubitVector norm1(ref_face_ptr->normal_at(p1));
+ CubitVector norm2(seed_ref_face->normal_at(p1));
+
+ double angle = norm1.interior_angle( norm2 );
+ if(angle > max_angle)
+ max_angle=angle;
+ }
+ }
+ if(max_angle < -.000001){
+ return CUBIT_FAILURE;
+ }
+ angle_out = max_angle;
+
+ return CUBIT_SUCCESS;
+}
+
+
Modified: cgm/branches/cubit/geom/virtual/SimplifyTool.hpp
===================================================================
--- cgm/branches/cubit/geom/virtual/SimplifyTool.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/SimplifyTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -22,6 +22,7 @@
class RefVolume;
class RefFace;
class RefEdge;
+class RefVertex;
template <class X> class DLIList;
/// Tool to automatically simplify geometry
@@ -43,6 +44,7 @@
DLIList<RefEdge*> respect_edge_list,
CubitBoolean respect_rounds,
CubitBoolean respect_imprints,
+ CubitBoolean local_normals,
CubitBoolean preview);
CubitStatus simplify_surfaces(
@@ -52,8 +54,32 @@
DLIList<RefEdge*> respect_edge_list,
CubitBoolean respect_rounds,
CubitBoolean respect_imprints,
+ CubitBoolean local_normals,
CubitBoolean preview);
+ CubitStatus simplify_curves(
+ DLIList<RefEdge*> ref_edge_list,
+ double angle_in,
+ DLIList<RefEdge*> respect_edge_list,
+ DLIList<RefVertex*> respect_vertex_list,
+ CubitBoolean respect_imprints,
+ CubitBoolean local_normals,
+ CubitBoolean preview);
+
+ CubitStatus simplify_curves_in_volume(
+ DLIList<RefEdge*> ref_edge_list,
+ double angle_in,
+ DLIList<RefEdge*> respect_edge_list,
+ DLIList<RefVertex*> respect_vertex_list,
+ CubitBoolean respect_imprints,
+ CubitBoolean local_normals,
+ CubitBoolean preview);
+
+ CubitBoolean composite_curves(
+ RefEdge* seed_ref_edge,
+ RefEdge* ref_edge_ptr,
+ double angle_in);
+
private:
CubitStatus simplify_volume(
@@ -63,6 +89,7 @@
DLIList<RefEdge*> respect_edge_list,
CubitBoolean respect_rounds,
CubitBoolean respect_imprints,
+ CubitBoolean local_normals,
CubitBoolean preview);
CubitStatus simplify_surfaces_in_volume(
@@ -72,6 +99,7 @@
DLIList<RefEdge*> respect_edge_list,
CubitBoolean respect_rounds,
CubitBoolean respect_imprints,
+ CubitBoolean local_normals,
CubitBoolean preview);
CubitBoolean composite_surfaces(
@@ -89,6 +117,19 @@
CubitVector &normal,
double &weight );
+
+ CubitBoolean composite_surfaces_test_at_curves(RefFace* seed_ref_face,
+ RefFace* ref_face_ptr,
+ double angle_in);
+
+
+
+ CubitBoolean maximum_angle_deviation(RefFace* seed_ref_face,
+ RefFace* ref_face_ptr,
+ double angle_in,
+ double &angle_out);
+
+
};
#endif
Added: cgm/branches/cubit/geom/virtual/SplitCompositeSurfaceTool.cpp
===================================================================
--- cgm/branches/cubit/geom/virtual/SplitCompositeSurfaceTool.cpp (rev 0)
+++ cgm/branches/cubit/geom/virtual/SplitCompositeSurfaceTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,252 @@
+#include "SplitCompositeSurfaceTool.hpp"
+#include "GeometryModifyTool.hpp"
+#include "RefFace.hpp"
+#include "CompositeSurface.hpp"
+#include "CompositeCurve.hpp"
+#include "Curve.hpp"
+#include "Point.hpp"
+#include "GeometryModifyEngine.hpp"
+#include "GeometryQueryTool.hpp"
+
+SplitCompositeSurfaceTool *SplitCompositeSurfaceTool::instance_ = NULL;
+
+SplitCompositeSurfaceTool *SplitCompositeSurfaceTool::instance()
+{
+ if (instance_ == NULL)
+ instance_ = new SplitCompositeSurfaceTool();
+
+ return instance_;
+}
+
+CubitStatus SplitCompositeSurfaceTool::split_surface(RefFace *ref_face_ptr,
+ DLIList<CubitVector*> &locations,
+ DLIList<DLIList<CubitVector*>*> &vec_lists,
+ CubitBoolean preview_flg,
+ CubitBoolean create_ref_edges_flg,
+ CubitBoolean clear_previous_previews)
+{
+ get_additional_split_points(ref_face_ptr->get_surface_ptr(), vec_lists);
+
+ return GeometryModifyTool::instance()->split_surface(ref_face_ptr,
+ locations, vec_lists, preview_flg, create_ref_edges_flg, clear_previous_previews);
+}
+
+CubitStatus SplitCompositeSurfaceTool::split_surface(DLIList<RefFace*> &ref_face_list,
+ DLIList<CubitVector*> &locations,
+ DLIList<DLIList<DLIList<CubitVector*>*>*> &list_of_vec_lists,
+ CubitBoolean preview_flg,
+ CubitBoolean create_ref_edges_flg,
+ CubitBoolean clear_previous_previews)
+{
+ for( int jj = ref_face_list.size() ; jj > 0 ; jj--)
+ {
+ DLIList<DLIList<CubitVector*>*> vec_lists = *( list_of_vec_lists.get_and_step() );
+
+ get_additional_split_points(ref_face_list.get_and_step()->get_surface_ptr(), vec_lists );
+ }
+
+ return GeometryModifyTool::instance()->split_surface(ref_face_list,
+ locations, list_of_vec_lists, preview_flg, create_ref_edges_flg, clear_previous_previews);
+}
+
+void SplitCompositeSurfaceTool::find_faces_for_pos(CubitVector &pos, DLIList<Surface*> surf_list,
+ CubitPointContainment &containment,
+ DLIList<Surface*> &out_list)
+{
+ int j;
+
+ for(j=surf_list.size(); j>0; j--)
+ {
+ Surface *surf_ptr = surf_list.get_and_step();
+ containment = surf_ptr->point_containment(pos);
+ if(containment == CUBIT_PNT_INSIDE || containment == CUBIT_PNT_BOUNDARY)
+ out_list.append_unique(surf_ptr);
+ }
+}
+
+void SplitCompositeSurfaceTool::get_additional_split_points(Surface *surf,
+ DLIList<DLIList<CubitVector*>*> &vec_lists)
+{
+ int i, j, k, num_surfs;
+ DLIList<Surface*> surf_list;
+
+ CompositeSurface *cs = dynamic_cast<CompositeSurface*>(surf);
+ if(cs && (num_surfs = cs->num_surfs()) > 1)
+ {
+ for(i=0; i<num_surfs; i++)
+ {
+ Surface *surf = cs->get_surface(i);
+ if(surf)
+ surf_list.append(surf);
+ }
+
+ DLIList<Curve*> hidden_curves;
+ cs->get_hidden_curves(hidden_curves);
+
+ for(i=vec_lists.size(); i--;)
+ {
+ // Remove any hidden curves that already have points on them.
+ DLIList<Curve*> hidden_curves_without_pts = hidden_curves;
+ DLIList<CubitVector*> *vec_list = vec_lists.get_and_step();
+ for(j=vec_list->size(); j--;)
+ {
+ CubitVector *cur_vec = vec_list->get_and_step();
+ DLIList<Curve*> crvs_to_remove;
+ for(k=hidden_curves_without_pts.size(); k>0; k--)
+ {
+ Curve *crv = hidden_curves_without_pts.get_and_step();
+ CubitVector foot;
+ crv->closest_point_trimmed(*cur_vec, foot);
+ if(foot.about_equal(*cur_vec))
+ crvs_to_remove.append_unique(crv);
+ }
+ hidden_curves_without_pts -= crvs_to_remove;
+ }
+
+ // Now we should only have hidden curves with no points on them.
+ if(hidden_curves_without_pts.size() > 0)
+ {
+ vec_list->reset();
+ CubitVector *cur_vec = vec_list->get();
+ CubitVector *last_vec = vec_list->prev();
+ while(cur_vec != last_vec)
+ {
+ vec_list->move_to(cur_vec);
+ CubitVector *next_vec = vec_list->next();
+ DLIList<CubitVector*> tmp_list;
+ DLIList<double> vals;
+ tmp_list.append(cur_vec);
+ tmp_list.append(next_vec);
+ vals.append(0.0);
+ vals.append(1.0);
+ Curve *hidden_curve = hidden_curves_without_pts.get();
+ CompositeCurve *cc = dynamic_cast<CompositeCurve*>(hidden_curve);
+ if(cc)
+ hidden_curve = cc->get_curve(0);
+ GeometryModifyEngine *gme = GeometryModifyTool::instance()->
+ get_engine(hidden_curve);
+ Point *pt1 = gme->make_Point(*cur_vec);
+ Point *pt2 = gme->make_Point(*last_vec);
+ Curve *tmp_crv = gme->make_Curve(STRAIGHT_CURVE_TYPE, pt1, pt2, NULL, CUBIT_FORWARD);
+ if(tmp_crv)
+ {
+ double arc_length = tmp_crv->get_arc_length();
+ for(j=hidden_curves_without_pts.size(); j--;)
+ {
+ CubitVector pos1, pos2;
+ double dist;
+ Curve *crv = hidden_curves_without_pts.get_and_step();
+ GeometryQueryTool::instance()->entity_entity_distance(crv, tmp_crv, pos1, pos2, dist);
+ CubitVector v1 = *cur_vec - pos1;
+ CubitVector v2 = *last_vec - pos1;
+ v1.normalize();
+ v2.normalize();
+ if(v1 % v2 < .3)
+ {
+ CubitVector *new_vec = new CubitVector(pos1);
+ v1 = (pt1->coordinates() - pos2);
+ double percent = v1.length()/arc_length;
+ if(percent > 1.0)
+ percent = 1.0;
+ if(percent < 0.0)
+ percent = 0.0;
+ tmp_list.reset();
+ vals.reset();
+ while(percent > vals.get())
+ {
+ vals.step();
+ tmp_list.step();
+ }
+ vals.back();
+ tmp_list.back();
+ vals.insert(percent);
+ tmp_list.insert(new_vec);
+ }
+ }
+ delete tmp_crv;
+ }
+ delete pt1;
+ delete pt2;
+ if(tmp_list.size() > 2)
+ {
+ vec_list->move_to(cur_vec);
+ tmp_list.reset();
+ tmp_list.step();
+ for(j=tmp_list.size(); j>2; j--)
+ {
+ vec_list->insert(tmp_list.get());
+ tmp_list.step();
+ }
+ }
+ cur_vec = next_vec;
+ }
+ }
+ }
+ }
+}
+
+// Passed in direction should be normalized by calling function.
+void SplitCompositeSurfaceTool::find_face_with_non_zero_param_dir(DLIList<Surface*> &surf_list,
+ CubitVector &dir,
+ CubitVector &pos,
+ Surface *&ret_surf,
+ double &du, double &dv,
+ double &step)
+{
+ int i;
+ ret_surf = NULL;
+ for(i=surf_list.size(); i>0 && !ret_surf; i--)
+ {
+ Surface *surf = surf_list.get_and_step();
+ CubitPointContainment cont = surf->point_containment(pos);
+ if(cont == CUBIT_PNT_INSIDE)
+ {
+ double ulow, uhigh, vlow, vhigh;
+ surf->param_dir(dir, pos, du, dv);
+ surf->get_param_range_U(ulow, uhigh);
+ surf->get_param_range_V(vlow, vhigh);
+ double u_len = fabs(ulow-uhigh);
+ double v_len = fabs(vlow-vhigh);
+ double par_tol;
+ if(u_len > v_len)
+ par_tol = v_len/100.0;
+ else
+ par_tol = u_len/100.0;
+ par_tol *= par_tol;
+ double len = du*du + dv*dv;
+ if(len > par_tol)
+ {
+ step = sqrt(u_len*u_len + v_len*v_len)/20.0;
+ ret_surf = surf;
+ }
+ }
+ else if(cont == CUBIT_PNT_BOUNDARY)
+ {
+ double ulow, uhigh, vlow, vhigh;
+ surf->param_dir(dir, pos, du, dv);
+ surf->get_param_range_U(ulow, uhigh);
+ surf->get_param_range_V(vlow, vhigh);
+ double u_len = fabs(ulow-uhigh);
+ double v_len = fabs(vlow-vhigh);
+ double par_tol;
+ if(u_len > v_len)
+ par_tol = v_len/100.0;
+ else
+ par_tol = u_len/100.0;
+ par_tol *= par_tol;
+ double len = du*du + dv*dv;
+ if(len > par_tol)
+ {
+ double u, v;
+ surf->u_v_from_position(pos, u, v);
+ CubitVector new_pos = surf->position_from_u_v(u+du, v+dv);
+ CubitPointContainment new_cont = surf->point_containment(new_pos);
+ if(new_cont == CUBIT_PNT_INSIDE)
+ {
+ step = sqrt(u_len*u_len + v_len*v_len)/20.0;
+ ret_surf = surf;
+ }
+ }
+ }
+ }
+}
Added: cgm/branches/cubit/geom/virtual/SplitCompositeSurfaceTool.hpp
===================================================================
--- cgm/branches/cubit/geom/virtual/SplitCompositeSurfaceTool.hpp (rev 0)
+++ cgm/branches/cubit/geom/virtual/SplitCompositeSurfaceTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,49 @@
+#ifndef SPLITCOMPOSITESURFACETOOL_HPP
+#define SPLITCOMPOSITESURFACETOOL_HPP
+
+#include "CubitDefines.h"
+#include "Surface.hpp"
+
+class Surface;
+class RefFace;
+class CubitVector;
+template<class X> class DLIList;
+
+
+class SplitCompositeSurfaceTool
+{
+ public:
+ static SplitCompositeSurfaceTool *instance();
+ CubitStatus split_surface( RefFace *ref_face_ptr,
+ DLIList<CubitVector*> &locations,
+ DLIList<DLIList<CubitVector*>*> &vec_lists,
+ CubitBoolean preview_flg = CUBIT_FALSE,
+ CubitBoolean create_ref_edges_flg = CUBIT_FALSE,
+ CubitBoolean clear_previous_previews = CUBIT_TRUE );
+
+ CubitStatus split_surface( DLIList<RefFace*> &ref_face_list,
+ DLIList<CubitVector*> &locations,
+ DLIList<DLIList<DLIList<CubitVector*>*>*> &list_of_vec_lists,
+ CubitBoolean preview_flg = CUBIT_FALSE,
+ CubitBoolean create_ref_edges_flg =CUBIT_FALSE,
+ CubitBoolean clear_previous_previews = CUBIT_TRUE );
+
+ private:
+
+ void find_faces_for_pos(CubitVector &pos, DLIList<Surface*> surf_list,
+ CubitPointContainment &containment,
+ DLIList<Surface*> &out_list);
+ void get_additional_split_points(Surface *surf,
+ DLIList<DLIList<CubitVector*>*> &vec_lists);
+ static SplitCompositeSurfaceTool *instance_;
+ void find_face_with_non_zero_param_dir(DLIList<Surface*> &surf_list,
+ CubitVector &dir,
+ CubitVector &pos,
+ Surface *&ret_surf,
+ double &du, double &dv,
+ double &step);
+
+};
+
+#endif
+
Modified: cgm/branches/cubit/geom/virtual/SubCurve.cpp
===================================================================
--- cgm/branches/cubit/geom/virtual/SubCurve.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/SubCurve.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -435,9 +435,9 @@
return CUBIT_SUCCESS;
}
- int i, junk;
+ int i;
if( !real_curve()->get_geometry_query_engine()->
- get_graphics( real_curve(), junk, &result ) )
+ get_graphics( real_curve(), &result ) )
return CUBIT_FAILURE;
if (0 == result.pointListCount)
Modified: cgm/branches/cubit/geom/virtual/SubSurface.cpp
===================================================================
--- cgm/branches/cubit/geom/virtual/SubSurface.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/SubSurface.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -35,8 +35,8 @@
new SubEntitySet( real_surf, this );
// ensure that the sense is the same on both entities
- if( real_surf->bridge_sense() != this->bridge_sense() )
- reverse_bridge_sense();
+ //if( real_surf->bridge_sense() != this->bridge_sense() )
+ // reverse_bridge_sense();
geometry_sense = CUBIT_FORWARD;
}
Modified: cgm/branches/cubit/geom/virtual/VGLoopTool.cpp
===================================================================
--- cgm/branches/cubit/geom/virtual/VGLoopTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/VGLoopTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -681,10 +681,9 @@
list.resize(0);
do {
- int num_pts;
coedge->get_curve()->get_geometry_query_engine()->
- get_graphics( coedge->get_curve(), num_pts, &gmem );
- assert( num_pts == gmem.pointListCount );
+ get_graphics( coedge->get_curve(), &gmem );
+ int num_pts = gmem.pointListCount;
if ( num_pts > 1 ) {
int start = list.size();
Modified: cgm/branches/cubit/geom/virtual/VirtualQueryEngine.cpp
===================================================================
--- cgm/branches/cubit/geom/virtual/VirtualQueryEngine.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/VirtualQueryEngine.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -72,6 +72,9 @@
#include "CAPartitionVG.hpp"
#include "CAVirtualVG.hpp"
+#include "HiddenEntitySet.hpp"
+#include "SubEntitySet.hpp"
+
// ********** END CUBIT INCLUDES **********
// ********** BEGIN STATIC DECLARATIONS **********
@@ -109,10 +112,23 @@
// PRINT_WARNING("Not all virtual geometry has been removed. "
// "This is a bug (memory leak). Please report it.\n");
// assert( virtual_entity_list_.size() == 0 );
+
+ PartitionEngine::delete_instance();
+ CompositeEngine::delete_instance();
+
instance_ = NULL;
}
+void VirtualQueryEngine::delete_instance()
+{
+ if( NULL != instance_ )
+ {
+ delete instance_;
+ instance_ = NULL;
+ }
+}
+
//-------------------------------------------------------------------------
// Purpose : Return a description of this ModelingEngine
//
@@ -170,8 +186,7 @@
// Creation Date :
//-------------------------------------------------------------------------
CubitStatus VirtualQueryEngine::get_graphics(
- Surface* surf_ptr, int& number_triangles,
- int& number_points, int& number_facets,
+ Surface* surf_ptr,
GMem* gMem,
unsigned short normal_tol,
double dist_tol,
@@ -181,24 +196,19 @@
PartitionSurface* ps_ptr = CAST_TO(surf_ptr, PartitionSurface );
if( cs_ptr != NULL )
{
- return get_composite_surface_facetting( cs_ptr,
- number_triangles, number_points,
- number_facets, gMem,
+ return get_composite_surface_facetting( cs_ptr, gMem,
normal_tol, dist_tol, max_edge_length );
}
else if( ps_ptr != NULL )
{
- return get_partition_surface_facetting( ps_ptr,
- number_triangles, number_points,
- number_facets, gMem,
+ return get_partition_surface_facetting( ps_ptr, gMem,
normal_tol, dist_tol, max_edge_length );
}
else
{
PRINT_INFO("VirtualQueryEngine::get_graphics_facets"
- "( s%p, %d, %d, %d, %p, %d, %f ) = CUBIT_FAILURE\n",
- surf_ptr, number_triangles,
- number_points, number_facets, gMem, normal_tol, dist_tol);
+ "( s%p, %p, %d, %f ) = CUBIT_FAILURE\n",
+ surf_ptr, gMem, normal_tol, dist_tol);
return CUBIT_FAILURE;
}
}
@@ -214,7 +224,6 @@
// Creation Date : 10/10/97
//-----------------------------------------------------------------------
CubitStatus VirtualQueryEngine::get_graphics( Curve* curve_ptr,
- int& num_points,
GMem* gMem,
double ) const
{
@@ -225,11 +234,11 @@
if( ccurve != NULL )
{
- result = get_composite_curve_facetting( ccurve, num_points, gMem );
+ result = get_composite_curve_facetting( ccurve, gMem );
}
else if( pcurve != NULL )
{
- result = get_partition_curve_facetting( pcurve, num_points, gMem );
+ result = get_partition_curve_facetting( pcurve, gMem );
}
else
{
@@ -278,13 +287,11 @@
//-----------------------------------------------------------------------
CubitStatus VirtualQueryEngine::get_composite_curve_facetting(
CompositeCurve* ccurve_ptr,
- int& num_points,
GMem* gMem ) const
{
// Just return if gMem is NULL
if (gMem == NULL)
{
- num_points = 0;
return CUBIT_SUCCESS;
}
@@ -304,11 +311,12 @@
curve_ptr->get_geometry_query_engine();
// Get the GME to facet the curve
- int this_point_count = 0;
CubitStatus current_status =
- GQE_ptr->get_graphics (curve_ptr, this_point_count, ¤t_gmem);
+ GQE_ptr->get_graphics (curve_ptr, ¤t_gmem);
if( current_status == CUBIT_FAILURE )
return CUBIT_FAILURE;
+
+ int this_point_count = current_gmem.pointListCount;
// Make sure the passed in gmem is big enough
gMem->allocate_more_polylines(this_point_count-1);
@@ -355,7 +363,6 @@
gMem->pointListCount = point_count;
}
- num_points = point_count;
gMem->pointListCount = point_count;
return CUBIT_SUCCESS;
}
@@ -374,11 +381,10 @@
// Creation Date : 10/10/97
//-----------------------------------------------------------------------
CubitStatus VirtualQueryEngine::get_partition_curve_facetting(
- PartitionCurve* pcurve_ptr, int& num_steps, GMem* gMem ) const
+ PartitionCurve* pcurve_ptr, GMem* gMem ) const
{
assert( gMem != NULL );
CubitStatus result = pcurve_ptr->get_graphics( *gMem );
- num_steps = gMem->pointListCount;
return result;
}
@@ -394,9 +400,6 @@
//-------------------------------------------------------------------------
CubitStatus VirtualQueryEngine::get_composite_surface_facetting(
CompositeSurface* surf_ptr,
- int& number_triangles,
- int& number_points,
- int& number_facets,
GMem* gMem,
unsigned short normal_tol,
double dist_tol,
@@ -407,20 +410,17 @@
if (surf_ptr->get_graphics(*gMem))
{
- number_triangles = gMem->fListCount / 4;
- number_points = gMem->pointListCount;
- number_facets = gMem->fListCount;
return CUBIT_SUCCESS;
}
- number_triangles = 0;
- number_points = 0;
- number_facets = 0;
// Get the underlying Surfaces
GeometryQueryEngine* gqe_ptr;
GMem *gMem_list = new GMem[ surf_ptr->num_surfs() ];
+ int total_number_points = 0;
+ int total_number_facets = 0;
+
// Get the facets of each Surface
int i;
for(i = 0; i < surf_ptr->num_surfs(); i++)
@@ -431,21 +431,19 @@
gqe_ptr = surface_ptr->get_geometry_query_engine();
tri_count = pt_count = facet_count = 0;
- gqe_ptr->get_graphics( surface_ptr, tri_count,
- pt_count, facet_count, &(gMem_list[i]),
+ gqe_ptr->get_graphics( surface_ptr, &(gMem_list[i]),
normal_tol, dist_tol, longest_edge );
- number_triangles += tri_count;
- number_facets += gMem_list[i].fListCount;
- number_points += gMem_list[i].pointListCount;
+ total_number_facets += gMem_list[i].fListCount;
+ total_number_points += gMem_list[i].pointListCount;
}
int point_offset = 0;
int face_offset = 0;
- gMem->replace_point_list(new GPoint[number_points],
- number_points, number_points);
- gMem->replace_facet_list(new int[number_facets],
- number_facets, number_facets);
+ gMem->replace_point_list(new GPoint[total_number_points],
+ total_number_points, total_number_points);
+ gMem->replace_facet_list(new int[total_number_facets],
+ total_number_facets, total_number_facets);
for( i = 0; i < surf_ptr->num_surfs(); i++ )
{
@@ -480,7 +478,6 @@
}
gMem->consolidate_points(10*GEOMETRY_RESABS);
- number_points = gMem->pointListCount;
// // Debug!!!
// int q;
// for (q = 0; q < bte_list.size(); q++)
@@ -533,9 +530,6 @@
//-------------------------------------------------------------------------
CubitStatus VirtualQueryEngine::get_partition_surface_facetting(
PartitionSurface* surf_ptr,
- int& num_triangles,
- int& num_points,
- int& num_facets,
GMem* gMem,
unsigned short ,
double,
@@ -576,11 +570,6 @@
gMem->fListCount = surf_facets.size() * 4;
gMem->pointListCount = surf_points.size();
- // set return values and if gMem is NULL return
- num_triangles = surf_facets.size();
- num_facets = gMem->fListCount;
- num_points = gMem->pointListCount;
-
// put points in GMem and mark each point with
// its index in the array
surf_points.reset();
@@ -1019,6 +1008,55 @@
return CUBIT_FALSE;
}
+CubitBoolean VirtualQueryEngine::is_partition( RefEntity *ref_entity )
+{
+ RefEdge *ref_edge = CAST_TO( ref_entity, RefEdge );
+
+ if( ref_edge )
+ {
+ Curve *curve_ptr = ref_edge->get_curve_ptr();
+ PartitionCurve *part_curve = CAST_TO(curve_ptr, PartitionCurve);
+
+ if( part_curve )
+ return CUBIT_TRUE;
+ }
+
+ return CUBIT_FALSE;
+}
+
+CubitStatus VirtualQueryEngine::get_sister_partitions( RefEntity *ref_entity,
+ DLIList<RefEntity*> &sisters)
+{
+ RefEdge *ref_edge = CAST_TO( ref_entity, RefEdge );
+
+ if( ref_edge )
+ {
+ Curve *curve_ptr = ref_edge->get_curve_ptr();
+ PartitionCurve *part_curve = CAST_TO(curve_ptr, PartitionCurve);
+
+ if( part_curve )
+ {
+ DLIList<TopologyBridge*> tb_list;
+ part_curve->sub_entity_set().get_owners( tb_list );
+
+ int k;
+ for( k=tb_list.size(); k--; )
+ {
+ TopologyBridge *tmp_bridge = tb_list.get_and_step();
+ TopologyEntity *te = tmp_bridge->topology_entity();
+ if( te )
+ {
+ RefEntity *sister = CAST_TO(te, RefEntity );
+ if( sister )
+ sisters.append( sister );
+ }
+ }
+ }
+ }
+
+ return CUBIT_SUCCESS;
+}
+
//-------------------------------------------------------------------------
// Purpose : Sort a DLList of RefEdges to be used in the construction
// of a CompositeCurve.
@@ -1190,6 +1228,28 @@
return CUBIT_FAILURE;
}
+int VirtualQueryEngine::curve_is_on_ignored_surface(Curve *curve_in, Surface *surf)
+{
+ int i, ret = 0;
+
+ CompositeSurface *cs = dynamic_cast<CompositeSurface*>(surf);
+ if(cs && curve_in)
+ {
+ DLIList<Surface*> ignored_surfs;
+ cs->get_ignored_surfs(ignored_surfs);
+ for(i=ignored_surfs.size(); i>0 && !ret; i--)
+ {
+ Surface *surf = ignored_surfs.get_and_step();
+ DLIList<Curve*> crvs;
+ surf->curves(crvs);
+ if(crvs.is_in_list(curve_in))
+ ret = 1;
+ }
+ }
+
+ return ret;
+}
+
//-------------------------------------------------------------------------
// Purpose : This function get underlying curves for virtual curves
//
@@ -1261,6 +1321,77 @@
return CUBIT_SUCCESS;
}
+CubitStatus VirtualQueryEngine::get_underlying_bridges(TopologyBridge* bridge_ptr,
+ DLIList<TopologyBridge*>& bridge_list)
+{
+ assert (bridge_ptr);
+ CompositeSurface *comp_surf = CAST_TO(bridge_ptr, CompositeSurface);
+ PartitionSurface *part_surf = CAST_TO(bridge_ptr, PartitionSurface);
+ CompositeCurve *comp_curve = CAST_TO(bridge_ptr, CompositeCurve);
+ PartitionCurve *part_curve = CAST_TO(bridge_ptr, PartitionCurve);
+ CompositePoint *comp_point = CAST_TO(bridge_ptr, CompositePoint);
+ PartitionPoint *part_point = CAST_TO(bridge_ptr, PartitionPoint);
+
+ if ( comp_surf )
+ {
+ int i;
+ for (i = 0; i < comp_surf->num_surfs(); i ++)
+ {
+ part_surf = CAST_TO(comp_surf->get_surface(i), PartitionSurface);
+ if (!part_surf)
+ bridge_list.append_unique(CAST_TO(comp_surf->get_surface(i),
+ TopologyBridge));
+ else
+ {
+ if(dynamic_cast<Surface*>(part_surf->partitioned_entity()))
+ {
+ bridge_list.append_unique(CAST_TO(part_surf->partitioned_entity(),
+ TopologyBridge));
+ }
+ }
+ }
+ }
+ else if ( part_surf )
+ bridge_list.append(CAST_TO(part_surf->partitioned_entity(),
+ TopologyBridge));
+ else if ( comp_curve )
+ {
+ int i;
+ for (i = 0; i < comp_curve->num_curves(); i ++)
+ {
+ part_curve = CAST_TO(comp_curve->get_curve(i), PartitionCurve);
+ if (!part_curve)
+ bridge_list.append_unique(CAST_TO(comp_curve->get_curve(i),
+ TopologyBridge));
+ else
+ {
+ if(dynamic_cast<Curve*>(part_curve->partitioned_entity()))
+ {
+ bridge_list.append_unique(CAST_TO(part_curve->partitioned_entity(),
+ TopologyBridge));
+ }
+ }
+ }
+ }
+ else if ( part_curve )
+ bridge_list.append(CAST_TO(part_curve->partitioned_entity(),
+ TopologyBridge));
+ else if ( part_point )
+ {
+ TopologyBridge *tb_point = part_point->real_point();
+ if( tb_point )
+ bridge_list.append( tb_point );
+ }
+ else if ( comp_point )
+ {
+ TopologyBridge *tb_point = comp_point->get_point();
+ if( tb_point )
+ bridge_list.append( tb_point );
+ }
+
+ return CUBIT_SUCCESS;
+}
+
//================================================================================
// Description: Find extrema position on an entity list
// Author :
@@ -1393,7 +1524,7 @@
for(j=geometry_entities_2.size(); j--;)
{
GeometryEntity *ge2 = geometry_entities_2.get_and_step();
- GeometryQueryEngine *gqe2 = gqes_2.get_and_step();
+ //GeometryQueryEngine *gqe2 = gqes_2.get_and_step();
CubitVector cur_pos1, cur_pos2;
double cur_distance;
@@ -1654,16 +1785,163 @@
return CUBIT_FAILURE;
}
-CubitStatus VirtualQueryEngine::fire_ray(BodySM *,
- const CubitVector &,
- const CubitVector &,
- DLIList<double>& ,
- DLIList<GeometryEntity*> *) const
+CubitStatus VirtualQueryEngine::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_ptr) const
{
- PRINT_INFO("VirtualQueryEngine::fire_ray\n");
-
- default_error_message( "fire_ray()");
- return CUBIT_FAILURE;
+ // Note: for now assume we will only get curves or surfaces
+
+ int i;
+ int prev_num_hits = ray_params.size();
+ GeometryQueryEngine *gqe = 0;
+ TopologyBridge *bridge_ptr;
+
+ // This is only needed because this function is "const"
+ VirtualQueryEngine *vqe = VirtualQueryEngine::instance();
+
+ at_entity_list.reset();
+ for( i=at_entity_list.size(); i--; )
+ {
+ prev_num_hits = ray_params.size();
+ bridge_ptr = at_entity_list.get_and_step();
+
+ gqe = bridge_ptr->get_geometry_query_engine();
+ if( !gqe )
+ {
+ PRINT_ERROR( "Unable to find geometry engine associated with an entity!\n" );
+ return CUBIT_FAILURE;
+ }
+
+ Curve *curve_ptr = CAST_TO( bridge_ptr, Curve );
+ if( curve_ptr )
+ {
+ DLIList<TopologyBridge*> tb_curve_list;
+ vqe->get_underlying_curves( curve_ptr, tb_curve_list );
+
+ if( tb_curve_list.size() > 0 )
+ {
+ gqe = tb_curve_list.get()->get_geometry_query_engine();
+
+ gqe->fire_ray( origin, direction, tb_curve_list, ray_params, max_hits,
+ ray_radius, hit_entity_list_ptr );
+
+ // If curve_ptr is a PartitionCurve, it could be smaller than the underlying curve.
+ // This means we have to check to make sure any hit points lie inside the curve. Remove if they don't.
+ if (CAST_TO(curve_ptr, PartitionCurve))
+ {
+ // start iterating at the first new ray_param
+ ray_params.reset();
+ ray_params.step(prev_num_hits);
+ hit_entity_list_ptr->reset();
+ hit_entity_list_ptr->step(prev_num_hits);
+
+ int j;
+ for (j=prev_num_hits; j<ray_params.size(); j++)
+ {
+ CubitVector *loc_ptr;
+ double param = ray_params.get();
+
+ loc_ptr = new CubitVector;
+ origin.next_point( direction, param, *loc_ptr );
+
+ CubitPointContainment containment = CUBIT_PNT_UNKNOWN;
+ containment = curve_ptr->point_containment(*loc_ptr);
+ if ( (containment != CUBIT_PNT_ON) && (containment != CUBIT_PNT_BOUNDARY) )
+ {
+ //remove from the hit list
+ ray_params.remove();
+ hit_entity_list_ptr->remove();
+ }
+ else
+ {
+ ray_params.step();
+ hit_entity_list_ptr->step();
+ }
+ }
+ }
+
+ }
+ }
+
+ Surface *surface_ptr = CAST_TO( bridge_ptr, Surface );
+ if( surface_ptr )
+ {
+ DLIList<TopologyBridge*> tb_surface_list;
+ vqe->get_underlying_surfaces( surface_ptr, tb_surface_list );
+
+ if( tb_surface_list.size() > 0 )
+ {
+ gqe = tb_surface_list.get()->get_geometry_query_engine();
+
+ gqe->fire_ray( origin, direction, tb_surface_list, ray_params, max_hits,
+ ray_radius, hit_entity_list_ptr );
+
+ // If surface_ptr is a PartitionSurface, it could be smaller than the underlying surface.
+ // This means we have to check to make sure any hit points lie inside the surface. Remove if they don't.
+ if (CAST_TO(surface_ptr, PartitionSurface))
+ {
+ // start iterating at the first new ray_param
+ ray_params.reset();
+ ray_params.step(prev_num_hits);
+ hit_entity_list_ptr->reset();
+ hit_entity_list_ptr->step(prev_num_hits);
+
+ int j;
+ for (j=prev_num_hits; j<ray_params.size(); j++)
+ {
+ CubitVector *loc_ptr;
+ double param = ray_params.get();
+
+ loc_ptr = new CubitVector;
+ origin.next_point( direction, param, *loc_ptr );
+
+ CubitPointContainment containment = CUBIT_PNT_UNKNOWN;
+ containment = surface_ptr->point_containment(*loc_ptr);
+ if ( (containment != CUBIT_PNT_ON) && (containment != CUBIT_PNT_BOUNDARY) )
+ {
+ //remove from the hit list
+ ray_params.remove();
+ hit_entity_list_ptr->remove();
+ }
+ else
+ {
+ ray_params.step();
+ hit_entity_list_ptr->step();
+ }
+ }
+ }
+
+ }
+ }
+
+ }
+
+ if( hit_entity_list_ptr && hit_entity_list_ptr->size() != ray_params.size() )
+ PRINT_WARNING( "Hit entity list size not equal to number of hits\n" );
+
+ // Account for max hits
+ if( max_hits != 0 )
+ {
+ if( ray_params.size() <= max_hits )
+ return CUBIT_SUCCESS;
+
+ for( i=ray_params.size()-max_hits; i--; )
+ {
+ ray_params.last();
+ ray_params.remove();
+ if( hit_entity_list_ptr )
+ {
+ hit_entity_list_ptr->last();
+ hit_entity_list_ptr->remove();
+ }
+ }
+ }
+
+ return CUBIT_SUCCESS;
}
double VirtualQueryEngine::get_sme_resabs_tolerance() const
@@ -1860,6 +2138,32 @@
return CUBIT_FAILURE;
}
+//Function should only be called on volumes of multi-volume bodies
+CubitBoolean VirtualQueryEngine::volumes_overlap (Lump *lump1, Lump *lump2 ) const
+{
+ PartitionLump* partition_lump1 = dynamic_cast<PartitionLump*>(lump1);
+ PartitionLump* partition_lump2 = dynamic_cast<PartitionLump*>(lump2);
+
+ Lump *tmp_lump1 = lump1;
+ if( partition_lump1 )
+ tmp_lump1 = partition_lump1->real_lump();
+
+ Lump *tmp_lump2 = lump2;
+ if( partition_lump2 )
+ tmp_lump2 = partition_lump2->real_lump();
+
+ GeometryQueryEngine *gqe = tmp_lump1->get_geometry_query_engine();
+ if( gqe != tmp_lump2->get_geometry_query_engine() )
+ {
+ PRINT_ERROR("Volumes must be of the same type (ACIS, SolidWorks, etc) to\n"
+ "find if they overlap.\n");
+ return CUBIT_FALSE;
+ }
+
+ return gqe->volumes_overlap( tmp_lump1, tmp_lump2 );
+}
+
+
CubitBoolean VirtualQueryEngine::bodies_overlap (BodySM *body_ptr_1, BodySM *body_ptr_2 ) const
{
PartitionBody* partition_body1 = dynamic_cast<PartitionBody*>(body_ptr_1);
@@ -1885,4 +2189,255 @@
}
+TopologyBridge* VirtualQueryEngine::get_visible_entity_at_point(TopologyBridge* hidden_tb, CubitVector* point)
+{
+ // Determine entity type; should only be Curve or Point
+ int j, k;
+ bool added_entity = false;
+ TopologyBridge* bridge_ptr = hidden_tb;
+ TopologyBridge* tb_owner = NULL;
+ bool hidden = CUBIT_TRUE;
+
+ TopologyBridge* visible_tb = NULL;
+
+ while (hidden)
+ {
+ tb_owner = dynamic_cast<TopologyBridge*>(bridge_ptr->owner());
+ if( tb_owner )
+ {
+ if( tb_owner->topology_entity() )
+ {
+ visible_tb = tb_owner;
+ hidden = CUBIT_FALSE;
+ added_entity = true;
+ continue;
+ }
+ else
+ hidden = CUBIT_TRUE;
+ }
+ else
+ {
+ if( bridge_ptr->topology_entity() )
+ {
+ visible_tb = bridge_ptr;
+ hidden = CUBIT_FALSE;
+ added_entity = true;
+ continue;
+ }
+ else
+ {
+ hidden = CUBIT_TRUE;
+ }
+ }
+
+
+ TopologyBridge *tb_ptr;
+ if( tb_owner )
+ tb_ptr = tb_owner;
+ else
+ tb_ptr = bridge_ptr;
+
+ TBOwner* tb_owner = tb_ptr->owner();
+ if (CAST_TO(tb_owner, HiddenEntitySet)) // virtual geometry
+ {
+ TopologyBridge* parent = NULL;
+ while (CAST_TO(tb_owner, HiddenEntitySet)) // virtual geometry
+ {
+ HiddenEntitySet* hidden_set_ptr = CAST_TO(tb_owner, HiddenEntitySet);
+ parent = dynamic_cast<TopologyBridge*>(hidden_set_ptr->owner());
+ if (parent)
+ tb_owner = parent->owner();
+ }
+ if (parent)
+ {
+ bridge_ptr = parent;
+ added_entity = true;
+ continue;
+ }
+ }
+ else if (CAST_TO(tb_owner, SubEntitySet)) // partition geometry
+ {
+ SubEntitySet* sub_set_ptr = CAST_TO(tb_owner, SubEntitySet);
+
+ DLIList<TopologyBridge*> owner_list;
+ sub_set_ptr->get_owners(owner_list);
+ owner_list.reset();
+ // need to traverse all the entities that make up the original geometry
+ // if intersected a surface, and the surface is partitioned into mult surfaces,
+ // which surface did we hit? Did we hit the curve in between? The vertices? gahhhh...
+ for (j=0; j<owner_list.size(); j++)
+ {
+ TopologyBridge* owner_partition = owner_list.get_and_step();
+ //determine geometry type and call point_containment
+
+ CubitPointContainment containment = CUBIT_PNT_UNKNOWN;
+
+ if (CAST_TO(owner_partition, Surface))
+ {
+ containment = CAST_TO(owner_partition, Surface)->point_containment(*point);
+ switch (containment)
+ {
+ case CUBIT_PNT_OFF:
+ break;
+ case CUBIT_PNT_ON:
+ bridge_ptr = owner_partition;
+ added_entity = true;
+ break;
+ case CUBIT_PNT_UNKNOWN:
+ break;
+ case CUBIT_PNT_BOUNDARY:
+ {
+ DLIList<TopologyBridge*> children, related_loops, related_coedges;
+ DLIList<TopologyBridge*> related_curves, temp;
+
+ // Goal: get curves (incl. virtual ones)
+ // Note: can't use ->curves() func b/c it won't grab the virtual curves
+
+ // get all Loops, including virtual
+ owner_partition->get_children( related_loops, true );
+
+ related_loops.reset();
+ int ii;
+
+ // get all CoEdges
+ for (ii = related_loops.size(); ii--;)
+ {
+ temp.clean_out();
+ related_loops.get_and_step()->get_children(temp, true);
+ related_coedges.merge_unique(temp);
+ }
+ // get all Curves
+ for (ii = related_coedges.size(); ii--;)
+ {
+ temp.clean_out();
+ related_coedges.get_and_step()->get_children(temp, true);
+ related_curves.merge_unique(temp);
+ }
+
+ CAST_LIST(related_curves, children, TopologyBridge);
+ for (k=0; k<children.size(); k++)
+ {
+ // CAST and do point_containment for each curve
+ containment = CUBIT_PNT_UNKNOWN;
+ TopologyBridge* partition_curve = children.get_and_step();
+ containment = CAST_TO(partition_curve, Curve)->point_containment(*point);
+ switch (containment)
+ {
+ case CUBIT_PNT_OFF:
+ case CUBIT_PNT_UNKNOWN:
+ break;
+ case CUBIT_PNT_ON:
+ bridge_ptr = partition_curve;
+ added_entity = true;
+ break;
+ case CUBIT_PNT_BOUNDARY:
+ {
+ // CAST and do point_containment for each vertex
+ children.clean_out();
+ partition_curve->get_children(children, true);
+ int kk;
+ for (kk=0; kk<children.size(); kk++)
+ {
+ TopologyBridge* partition_vertex = children.get_and_step();
+ containment = CUBIT_PNT_UNKNOWN;
+ CubitVector coords = CAST_TO(partition_vertex, Point)->coordinates();
+ if (coords.distance_between_squared(*point) < GEOMETRY_RESABS*GEOMETRY_RESABS)
+ {
+ containment = CUBIT_PNT_ON;
+ bridge_ptr = partition_vertex;
+ added_entity = true;
+ break;
+ }
+ else
+ containment = CUBIT_PNT_OFF;
+ }
+ }
+ }
+
+ if (added_entity)
+ break;
+ }
+ break;
+ }
+ }
+ if (added_entity)
+ break;
+ }
+ else if (CAST_TO(owner_partition, Curve))
+ {
+ // CAST and do point_containment for each curve
+ containment = CUBIT_PNT_UNKNOWN;
+ containment = CAST_TO(owner_partition, Curve)->point_containment(*point);
+ switch (containment)
+ {
+ case CUBIT_PNT_OFF:
+ case CUBIT_PNT_UNKNOWN:
+ break;
+ case CUBIT_PNT_ON:
+ bridge_ptr = owner_partition;
+ added_entity = true;
+ break;
+ case CUBIT_PNT_BOUNDARY:
+ {
+ // CAST and do point_containment for each vertex
+ DLIList<TopologyBridge*> children;
+ children.clean_out();
+ owner_partition->get_children(children, true);
+ int kk;
+ for (kk=0; kk<children.size(); kk++)
+ {
+ TopologyBridge* partition_vertex = children.get_and_step();
+ containment = CUBIT_PNT_UNKNOWN;
+ CubitVector coords = CAST_TO(partition_vertex, Point)->coordinates();
+ if (coords.distance_between_squared(*point) < GEOMETRY_RESABS*GEOMETRY_RESABS)
+ {
+ containment = CUBIT_PNT_ON;
+ bridge_ptr = partition_vertex;
+ added_entity = true;
+ break;
+ }
+ else
+ containment = CUBIT_PNT_OFF;
+ }
+ break;
+ }
+ }
+
+ if (added_entity)
+ break;
+ }
+
+ else if (CAST_TO(owner_partition, Point))
+ {
+ CubitVector coords = CAST_TO(owner_partition, Point)->coordinates();
+ if (coords.distance_between_squared(*point) < GEOMETRY_RESABS*GEOMETRY_RESABS)
+ {
+ containment = CUBIT_PNT_ON;
+ bridge_ptr = owner_partition;
+ added_entity = true;
+ break;
+ }
+ else
+ containment = CUBIT_PNT_OFF;
+ }
+
+ else
+ PRINT_WARNING("Hit unknown partition entity.\n");
+
+
+ }
+ if (!added_entity)
+ {
+ visible_tb = NULL;
+ hidden = CUBIT_FALSE;
+ //break;
+ }
+
+ }
+
+
+ } //while
+
+ return visible_tb;
+}
Modified: cgm/branches/cubit/geom/virtual/VirtualQueryEngine.hpp
===================================================================
--- cgm/branches/cubit/geom/virtual/VirtualQueryEngine.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/geom/virtual/VirtualQueryEngine.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -71,6 +71,8 @@
public:
+ virtual int curve_is_on_ignored_surface(Curve *curve,
+ Surface *surf);
void remove_virtual_geometry( RefEntity* entity_ptr,
CubitBoolean all_children );
void remove_virtual_geometry( Body* body, bool all_children );
@@ -115,6 +117,8 @@
//- Access to VirtualQueryEngine must be through this function.
//- This forces single instance of the class. (constructor is protected)
+ static void delete_instance();
+
void register_attributes();
//- VGE registers attributes required for virtual geometry
// -- only call this once per session
@@ -139,9 +143,6 @@
virtual bool is_intermediate_engine() {return TRUE;}
virtual CubitStatus get_graphics( Surface* surface_ptr,
- int& number_of_triangles,
- int& number_of_points,
- int& number_of_facets,
GMem* gMem,
unsigned short normal_tolerance,
double distance_tolerance,
@@ -163,7 +164,6 @@
//- all goes well, CUBIT_Success is retuned.
virtual CubitStatus get_graphics( Curve* curve_ptr,
- int& num_points,
GMem* gMem = NULL,
double tolerance = 0.0 ) const;
//R CubitStatus
@@ -243,8 +243,11 @@
//I- Return only entities visible in the model.
//- Get any virtual geometry of the passed entity or its children.
+ virtual TopologyBridge* get_visible_entity_at_point(TopologyBridge* hidden_tb, CubitVector* point);
+ //R TopologyBridge*
+ //I hidden_tb, point
+ //I- Returns the lowest level visible entity that contains 'point.' (used for fire_ray())
-
CubitBoolean virtuals_created() const;
//- returns CUBIT_TRUE if there are virtual entities in the model
@@ -264,6 +267,11 @@
const CubitBoolean children_too = CUBIT_FALSE);
//- returns CUBIT_TRUE if the entities passed in are virtual or
//- contain any virtual entities
+
+ CubitBoolean is_partition( RefEntity *ref_entity );
+
+ CubitStatus get_sister_partitions( RefEntity *ref_entity,
+ DLIList<RefEntity*> &sisters);
CubitStatus sort_edges( DLIList<RefEdge*>& edge_list ) const;
//R CubitStatus
@@ -292,8 +300,11 @@
DLIList<TopologyBridge*>& curve_list);
virtual CubitStatus get_underlying_surfaces(Surface * surf_ptr,
DLIList<TopologyBridge*>& surf_list) ;
+ virtual CubitStatus get_underlying_bridges(TopologyBridge* bridge_ptr,
+ DLIList<TopologyBridge*>& bridge_list);
virtual CubitBoolean bodies_overlap (BodySM *body_ptr_1, BodySM *body_ptr_2 ) const;
+ virtual CubitBoolean volumes_overlap (Lump *lump1, Lump *lump2 ) const;
protected:
@@ -305,25 +316,17 @@
//**** Display related methods
CubitStatus get_composite_curve_facetting( CompositeCurve* ccurve_ptr,
- int& num_points,
GMem* gMem ) const;
CubitStatus get_partition_curve_facetting( PartitionCurve* pcurve_ptr,
- int& num_points,
GMem* gMem ) const;
CubitStatus get_composite_surface_facetting( CompositeSurface* surf_ptr,
- int& number_triangles,
- int& number_points,
- int& number_facets,
GMem* gMem,
unsigned short normal_tol,
double absolute_tol,
double longest_edge ) const;
CubitStatus get_partition_surface_facetting( PartitionSurface* surf_ptr,
- int& number_triangles,
- int& number_points,
- int& number_facets,
GMem* gMem,
unsigned short normal_tol,
double absolute_tol,
@@ -386,11 +389,22 @@
virtual CubitStatus delete_solid_model_entities( Curve* curve_ptr ) const;
virtual CubitStatus delete_solid_model_entities( Point* point_ptr ) const;
- virtual CubitStatus fire_ray(BodySM *body,
- const CubitVector &ray_point,
- const CubitVector &unit,
- DLIList<double> &ray_params,
- DLIList<GeometryEntity*> *entity_list = 0) const;
+ virtual CubitStatus 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=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. 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).
+ //- NOTE: returned entities hit might be "hidden" beneath virtual entities.
+ //- To resolve to visible entities, use "get_visible_ents_for_hits"
+ //- in GeometryQueryTool.
virtual double get_sme_resabs_tolerance() const;
virtual double set_sme_resabs_tolerance( double new_resabs );
Modified: cgm/branches/cubit/util/AppUtil.cpp
===================================================================
--- cgm/branches/cubit/util/AppUtil.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/AppUtil.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -12,8 +12,8 @@
// Owner : Darryl Melander
//-------------------------------------------------------------------------
-#include <stdio.h>
-#include <stdlib.h>
+#include <cstdio>
+#include <cstdlib>
#include <signal.h>
#ifndef NT
# include <unistd.h>
@@ -174,6 +174,15 @@
mProgressTool = NULL;
}
+void AppUtil::delete_instance()
+{
+ if( NULL != instance_ )
+ {
+ delete instance_;
+ instance_ = NULL;
+ }
+}
+
#ifdef CAT
// Returns how many days until the app expires. A negative
// number inicates it is already expired. If there is
@@ -353,7 +362,7 @@
}
// Delete the singletons
- delete CubitMessage::instance();
+ CubitMessage::delete_instance();
CubitObserver::term_static_observers();
Modified: cgm/branches/cubit/util/AppUtil.hpp
===================================================================
--- cgm/branches/cubit/util/AppUtil.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/AppUtil.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -32,7 +32,7 @@
static AppUtil* instance();
//- Access to the application object
- static void delete_instance() {if (instance_) delete instance_;};
+ static void delete_instance();
void report_resource_usage() const;
//- Prints out information about the session
Modified: cgm/branches/cubit/util/ArrayBasedContainer.cpp
===================================================================
--- cgm/branches/cubit/util/ArrayBasedContainer.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/ArrayBasedContainer.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -5,8 +5,8 @@
#include "ArrayBasedContainer.hpp"
#include "CubitDefines.h"
-#include <string.h>
-#include <assert.h>
+#include <cstring>
+#include <cassert>
unsigned int ArrayBasedContainer::currentAllocatedMemory = 0;
unsigned int ArrayBasedContainer::maxAllocatedMemory = 0;
Modified: cgm/branches/cubit/util/CMakeLists.txt
===================================================================
--- cgm/branches/cubit/util/CMakeLists.txt 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CMakeLists.txt 2010-01-06 19:22:14 UTC (rev 3423)
@@ -4,6 +4,7 @@
INCLUDE(${cubit_util_SOURCE_DIR}/UseUtil.cmake)
SET(UTIL_SRCS
+ AllocMemManagersList.cpp
AppUtil.cpp
ArrayBasedContainer.cpp
CpuTimer.cpp
@@ -27,6 +28,7 @@
CubitStack.cpp
CubitString.cpp
CubitTransformMatrix.cpp
+ CubitUndo.cpp
CubitUtil.cpp
CubitVector.cpp
DIntArray.cpp
@@ -34,6 +36,7 @@
DynamicArray.cpp
GetLongOpt.cpp
GfxDebug.cpp
+ GlobalCommandFeedback.cpp
GMem.cpp
IntersectionTool.cpp
MemoryBlock.cpp
@@ -52,12 +55,68 @@
ToolDataUser.cpp
Tree.cpp
TtyProgressTool.cpp
- CubitEventDefines.h
)
-SET(EXTRA_UTIL_SRCS
- AllocMemManagersList.cpp
- )
+SET(UTIL_HDRS
+ AppUtil.hpp
+ ArrayBasedContainer.hpp
+ CpuTimer.hpp
+ CommandFeedback.hpp
+ Cubit2DPoint.hpp
+ CubitBox.hpp
+ CubitCollection.hpp
+ CubitContainer.hpp
+ CubitCoordinateSystem.hpp
+ CubitDefines.h
+ CubitDynamicLoader.hpp
+ CubitEntity.hpp
+ CubitEquation.hpp
+ CubitFile.hpp
+ CubitFileFEModel.hpp
+ CubitFileIOWrapper.hpp
+ CubitFileMetaData.hpp
+ CubitFileUtil.hpp
+ CubitMatrix.hpp
+ CubitMessage.hpp
+ CubitObservable.hpp
+ CubitObserver.hpp
+ CubitPlane.hpp
+ CubitStack.hpp
+ CubitString.hpp
+ CubitTransformMatrix.hpp
+ CubitUndo.hpp
+ CubitUtil.hpp
+ CubitVector.hpp
+ DIntArray.hpp
+ DLIList.hpp
+ DLList.hpp
+ DynamicArray.hpp
+ GetLongOpt.hpp
+ GfxDebug.hpp
+ GlobalCommandFeedback.hpp
+ GMem.hpp
+ IntersectionTool.hpp
+ MemoryBlock.hpp
+ MemoryManager.hpp
+ OrderedSet.hpp
+ OrderedMap.hpp
+ ParamCubitPlane.hpp
+ PlanarParamTool.hpp
+ Queue.hpp
+ RandomMersenne.hpp
+ SDLList.hpp
+ SettingHandler.hpp
+ SettingHolder.hpp
+ StubProgressTool.hpp
+ TDUPtr.hpp
+ TextProgressTool.hpp
+ ToolData.hpp
+ ToolDataUser.hpp
+ Tree.hpp
+ TtyProgressTool.hpp
+ CubitEventDefines.h
+ ${cubit_util_BINARY_DIR}/CubitUtilConfigure.h
+ )
IF(TEMPLATE_DEFS_INCLUDED)
SET(TEMPLATE_SRCS
@@ -74,17 +133,8 @@
)
ENDIF(TEMPLATE_DEFS_INCLUDED)
-IF(WIN32)
- FOREACH(var ${UTIL_SRCS})
- STRING(REGEX REPLACE ".cpp" ".hpp" header ${var})
- SET(UTIL_HEADERS ${UTIL_HEADERS} ${header})
- ENDFOREACH(var ${UTIL_SRCS})
- SET(UTIL_HEADERS ${UTIL_HEADERS} CubitEquation.hpp)
-ENDIF(WIN32)
-
ADD_DEFINITIONS(${CUBIT_UTIL_DEFINES})
-
INCLUDE_DIRECTORIES(${cubit_util_BINARY_DIR})
OPTION(CUBIT_UTIL_BUILD_SHARED_LIBS "Build Cubit_Util as shared library" OFF)
@@ -92,37 +142,52 @@
SET(CUBIT_UTIL_BUILD_SHARED_LIBS ON CACHE BOOL "Build Cubit_Util as shared library" FORCE)
ENDIF(BUILD_SHARED_LIBS)
-IF(CUBIT_UTIL_BUILD_SHARED_LIBS)
- ADD_LIBRARY(cubit_util SHARED ${UTIL_SRCS} ${UTIL_HEADERS} ${TEMPLATE_SRCS} ${EXTRA_UTIL_SRCS})
-
- IF(CUBIT_COPY_DIR)
- # The cubit copy dir should only be set on windows.
- STRING(REGEX REPLACE "/" "\\\\" winbin "${CUBIT_COPY_DIR}")
- IF(${CMAKE_GENERATOR} MATCHES "Visual Studio")
- ADD_CUSTOM_COMMAND(TARGET cubit_util POST_BUILD
- COMMAND ${CMAKE_COMMAND}
- ARGS -E copy
- $\(TargetPath\) ${winbin}\\$\(TargetName\).dll)
- ELSE(${CMAKE_GENERATOR} MATCHES "Visual Studio")
- STRING(REGEX REPLACE "/" "\\\\" winsrc "${LIBRARY_OUTPUT_PATH}")
- ADD_CUSTOM_COMMAND(TARGET cubit_util POST_BUILD
- COMMAND ${CMAKE_COMMAND}
- ARGS -E copy
- ${winsrc}\\cubit_util.dll
- ${winlib}\\cubit_util.dll)
- ENDIF(${CMAKE_GENERATOR} MATCHES "Visual Studio")
- ENDIF(CUBIT_COPY_DIR)
-ELSE(CUBIT_UTIL_BUILD_SHARED_LIBS)
- ADD_LIBRARY(cubit_util ${UTIL_SRCS} ${UTIL_HEADERS} ${TEMPLATE_SRCS} ${EXTRA_UTIL_SRCS})
-ENDIF(CUBIT_UTIL_BUILD_SHARED_LIBS)
-
CONFIGURE_FILE(${cubit_util_SOURCE_DIR}/CubitUtilConfigure.h.in
${cubit_util_BINARY_DIR}/CubitUtilConfigure.h
@ONLY)
+IF(NOT CUBIT_UTIL_NAME)
+ SET(CUBIT_UTIL_NAME cubit_util)
+ENDIF(NOT CUBIT_UTIL_NAME)
-SET(CMAKE_INSTALL_BINARY_DIR "bin" CACHE PATH "Install directory for binaries")
IF(CUBIT_UTIL_BUILD_SHARED_LIBS)
- INSTALL_TARGETS(/${CMAKE_INSTALL_BINARY_DIR} cubit_util)
+ ADD_LIBRARY(${CUBIT_UTIL_NAME} SHARED ${UTIL_SRCS} ${UTIL_HDRS} ${TEMPLATE_SRCS})
+ELSE(CUBIT_UTIL_BUILD_SHARED_LIBS)
+ ADD_LIBRARY(${CUBIT_UTIL_NAME} ${UTIL_SRCS} ${UTIL_HDRS} ${TEMPLATE_SRCS})
ENDIF(CUBIT_UTIL_BUILD_SHARED_LIBS)
+TARGET_LINK_LIBRARIES(${CUBIT_UTIL_NAME} ${CMAKE_DL_LIBS})
+
+IF(CUBIT_LIBRARY_PROPERTIES)
+ SET_TARGET_PROPERTIES(${CUBIT_UTIL_NAME}
+ PROPERTIES ${CUBIT_LIBRARY_PROPERTIES})
+ENDIF(CUBIT_LIBRARY_PROPERTIES)
+
+
+IF(NOT CMAKE_INSTALL_BINARY_DIR)
+ SET(CMAKE_INSTALL_BINARY_DIR bin)
+ENDIF(NOT CMAKE_INSTALL_BINARY_DIR)
+
+IF(NOT CMAKE_INSTALL_INCLUDE_DIR)
+ SET(CMAKE_INSTALL_INCLUDE_DIR include)
+ENDIF(NOT CMAKE_INSTALL_INCLUDE_DIR)
+
+IF(CUBIT_UTIL_INSTALL_NO_DEVELOPMENT)
+ IF(CUBIT_UTIL_BUILD_SHARED_LIBS)
+ INSTALL(TARGETS ${CUBIT_UTIL_NAME} ${CUBIT_UTIL_EXPORT_GROUP}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINARY_DIR} COMPONENT Runtime
+ LIBRARY DESTINATION ${CMAKE_INSTALL_BINARY_DIR} COMPONENT Runtime)
+ ENDIF(CUBIT_UTIL_BUILD_SHARED_LIBS)
+ELSE(CUBIT_UTIL_INSTALL_NO_DEVELOPMENT)
+INSTALL(TARGETS ${CUBIT_UTIL_NAME} ${CUBIT_UTIL_EXPORT_GROUP}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINARY_DIR} COMPONENT Runtime
+ LIBRARY DESTINATION ${CMAKE_INSTALL_BINARY_DIR} COMPONENT Runtime
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_BINARY_DIR} COMPONENT Development)
+
+IF(NOT CUBIT_UTIL_INSTALL_NO_DEVELOPMENT_HEADERS)
+INSTALL(FILES ${UTIL_HDRS}
+ DESTINATION ${CMAKE_INSTALL_INCLUDE_DIR} COMPONENT Development)
+ENDIF(NOT CUBIT_UTIL_INSTALL_NO_DEVELOPMENT_HEADERS)
+
+ENDIF(CUBIT_UTIL_INSTALL_NO_DEVELOPMENT)
+
Modified: cgm/branches/cubit/util/CastTo.hpp
===================================================================
--- cgm/branches/cubit/util/CastTo.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CastTo.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -47,6 +47,7 @@
{ \
(classOneList).reset(); \
(classTwoList).clean_out(); \
+ (classTwoList).reserve((classOneList).size()); \
for (int CAST_LIST_IT = (classOneList).size(); CAST_LIST_IT > 0; CAST_LIST_IT--) \
(classTwoList).append((classOneList).get_and_step()); \
}
Added: cgm/branches/cubit/util/CommandFeedback.hpp
===================================================================
--- cgm/branches/cubit/util/CommandFeedback.hpp (rev 0)
+++ cgm/branches/cubit/util/CommandFeedback.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,62 @@
+#ifndef CUBIT_COMMANDFEEDBACK_HPP
+#define CUBIT_COMMANDFEEDBACK_HPP
+
+#include <typeinfo>
+#include <cassert>
+
+// Base class for all command feedback.
+class CommandFeedback
+{
+public:
+ typedef const std::type_info& Type;
+
+ CommandFeedback()
+ {}
+
+ virtual ~CommandFeedback()
+ {}
+
+ virtual Type this_type() const = 0;
+
+ template <typename target_type>
+ target_type& get_reference()
+ {
+ assert(this->this_type() == target_type::type());
+ return *(dynamic_cast<target_type*>(this));
+ }
+
+ template <typename target_type>
+ const target_type& get_reference() const
+ {
+ assert(this->this_type() == target_type::type());
+ return *(dynamic_cast<const target_type*>(this));
+ }
+};
+
+// The rest of this file is an example to show how to use CommandFeedback
+#include "CubitString.hpp"
+
+class DeprecatedCommandError : public CommandFeedback
+{
+public:
+ DeprecatedCommandError(const CubitString &some_string)
+ : myString(some_string), myInt(27)
+ {}
+
+ int wow_an_integer() const
+ { return myInt; }
+ CubitString wow_a_string() const
+ { return myString; }
+
+ static CommandFeedback::Type type()
+ { return typeid(DeprecatedCommandError); }
+
+ CommandFeedback::Type this_type() const
+ { return DeprecatedCommandError::type(); }
+
+private:
+ int myInt;
+ CubitString myString;
+};
+
+#endif
Modified: cgm/branches/cubit/util/CpuTimer.cpp
===================================================================
--- cgm/branches/cubit/util/CpuTimer.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CpuTimer.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -1,4 +1,4 @@
-#include <stdio.h>
+#include <cstdio>
#include "CpuTimer.hpp"
#include "CubitMessage.hpp"
@@ -9,7 +9,7 @@
#include <sys/times.h>
#endif
-#include <time.h>
+#include <time.h>
#ifdef SOLARIS
#include <unistd.h>
#endif
@@ -43,8 +43,12 @@
// Added by Cat for NT port
#ifdef NT
- nt_times(¤t);
+ nt_times(¤t);
+ wallTimeInitial = clock();
+ wallTime = wallTimeInitial;
#else
+ gettimeofday(&wallTimeInitial, NULL);
+ wallTime = wallTimeInitial;
times( ¤t );
#endif
@@ -84,24 +88,76 @@
}
double
-CpuTimer::elapsed()
+CpuTimer::clock_secs()
{
- tms current;
+ double elapsed_time;
+#ifdef NT
+ clock_t current;
+ current = clock();
+ elapsed_time = double( current - wallTime );
+ elapsed_time = elapsed_time / HZ;
+ wallTime = current;
+#else
+ timeval current;
+ gettimeofday( ¤t, NULL );
+ double prev_time = wallTime.tv_sec;
+ prev_time += double( wallTime.tv_usec ) / 1000000.0;
+
+ elapsed_time = current.tv_sec;
+ elapsed_time += double( current.tv_usec ) / 1000000.0;
+ elapsed_time = elapsed_time - prev_time;
+
+ wallTime = current;
+#endif
+
+ return elapsed_time;
+}
+
+double
+CpuTimer::elapsed(bool wall_time)
+{
+ if( wall_time )
+ {
+ double elapsed;
+#ifdef NT
+ clock_t current;
+ current = clock();
+ elapsed = double( current - wallTimeInitial);
+ elapsed = elapsed / HZ;
+#else
+ double current_time;
+ timeval current;
+ gettimeofday( ¤t, NULL );
+ double initial_time;
+ initial_time = wallTimeInitial.tv_sec;
+ initial_time += double(wallTimeInitial.tv_usec) / 1000000.0;
+ current_time = current.tv_sec;
+ current_time += double( current.tv_usec ) / 1000000.0;
+
+ elapsed = current_time - initial_time;
+#endif
+ return elapsed;
+ }
+ else
+ {
+ tms current;
+
// Added by Cat for NT port
#ifdef NT
- nt_times(¤t);
+ nt_times(¤t);
#else
- times( ¤t );
+ times( ¤t );
#endif
// Store totals
- time_t cpu_now = current.tms_utime +
- current.tms_stime +
- current.tms_cutime +
- current.tms_cstime;
- time_t elapsed = cpu_now - cpuInitial;
- return (double) elapsed / HZ;
+ time_t cpu_now = current.tms_utime +
+ current.tms_stime +
+ current.tms_cutime +
+ current.tms_cstime;
+ time_t elapsed = cpu_now - cpuInitial;
+ return (double) elapsed / HZ;
+ }
}
Modified: cgm/branches/cubit/util/CpuTimer.hpp
===================================================================
--- cgm/branches/cubit/util/CpuTimer.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CpuTimer.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -3,27 +3,39 @@
#if !defined(CPU_TIMER)
#define CPU_TIMER
#include <sys/types.h>
+#ifndef NT
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
#include "CubitUtilConfigure.h"
class CUBIT_UTIL_EXPORT CpuTimer {
public:
CpuTimer(); //- initialise to current system time
- double cpu_secs(); //- return CPU time in seconds since last
- //- to cpu_secs();
- double elapsed(); //- return CPU time in seconds since 'birth'
+ double cpu_secs(); //- return CPU time in seconds since last
+ //- call to cpu_secs();
+ double clock_secs(); //- return wall clock time in seconds since last
+ //- call to clock_secs();
+ double elapsed(bool wall_time = false); //- return CPU time in seconds since 'birth' if
+ //- wall_time is false, else returns the wall clock time.
private:
time_t cpu; //- cpu time in 1/HZ units since last call
//- to cpu_secs()
time_t cpuInitial; //- cpu time in 1/HZ units since construction.
- // Added by Cat for NT port
+
+ // Added by Cat for NT port
#ifdef NT
void nt_times(struct tms *);
+ clock_t wallTimeInitial;
+ clock_t wallTime;
+ #else
+ timeval wallTimeInitial; //- Time at construction.
+ timeval wallTime; //- Time since last call.
#endif
-
-
};
#endif
Modified: cgm/branches/cubit/util/CubitBox.cpp
===================================================================
--- cgm/branches/cubit/util/CubitBox.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitBox.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -3,9 +3,9 @@
//- Owner: Greg Sjaardema
//- Checked by:
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cassert>
#include "CubitBox.hpp"
#include "CubitVector.hpp"
@@ -433,3 +433,85 @@
vect.z() <= minimum_.z() ||
vect.z() >= maximum_.z() );
}
+
+/*
+Fast Ray-Box Intersection
+by Andrew Woo
+from "Graphics Gems", Academic Press, 1990
+*/
+
+#define NUMDIM 3
+#define RIGHT 0
+#define LEFT 1
+#define MIDDLE 2
+
+//char HitBoundingBox(minB,maxB, origin, dir,coord)
+//double minB[NUMDIM], maxB[NUMDIM]; /*box */
+//double origin[NUMDIM], dir[NUMDIM]; /*ray */
+//double coord[NUMDIM]; /* hit point */
+bool CubitBox::intersect(const CubitVector* ray_origin, const CubitVector* ray_direction,
+ CubitVector* intersection_pt)
+{
+ bool inside = true;
+ int quadrant[NUMDIM];
+ register int i;
+ int whichPlane;
+ double maxT[NUMDIM];
+ double candidatePlane[NUMDIM];
+
+ /* Find candidate planes; this loop can be avoided if
+ rays cast all from the eye(assume perpsective view) */
+ for (i=0; i<NUMDIM; i++)
+ if((*ray_origin)[i] < (this->minimum())[i]) {
+ quadrant[i] = LEFT;
+ candidatePlane[i] = (this->minimum())[i];
+ inside = false;
+ }else if ( (*ray_origin)[i] > (this->maximum())[i]) {
+ quadrant[i] = RIGHT;
+ candidatePlane[i] = (this->maximum())[i];
+ inside = false;
+ }else {
+ quadrant[i] = MIDDLE;
+ }
+
+ /* Ray origin inside bounding box */
+ if(inside)
+ {
+ intersection_pt = new CubitVector(*ray_origin);
+ return true;
+ }
+
+
+ /* Calculate T distances to candidate planes */
+ for (i = 0; i < NUMDIM; i++)
+ if (quadrant[i] != MIDDLE && (*ray_direction)[i] !=0.)
+ maxT[i] = ( candidatePlane[i]-(*ray_origin)[i]) / ((*ray_direction)[i]);
+ else
+ maxT[i] = -1.;
+
+ /* Get largest of the maxT's for final choice of intersection */
+ whichPlane = 0;
+ for (i = 1; i < NUMDIM; i++)
+ if (maxT[whichPlane] < maxT[i])
+ whichPlane = i;
+
+ /* Check final candidate actually inside box */
+ double intersection_coords[3];
+
+ if (maxT[whichPlane] < 0.)
+ return false;
+
+ for (i = 0; i < NUMDIM; i++)
+ {
+ if (whichPlane != i)
+ {
+ intersection_coords[i] = (*ray_origin)[i] + maxT[whichPlane] * (*ray_direction)[i];
+ if (intersection_coords[i] < (this->minimum())[i] || intersection_coords[i] > (this->maximum())[i])
+ return false;
+ }
+ else
+ intersection_coords[i] = candidatePlane[i];
+ }
+
+ return true; /* ray hits box */
+}
Modified: cgm/branches/cubit/util/CubitBox.hpp
===================================================================
--- cgm/branches/cubit/util/CubitBox.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitBox.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -80,6 +80,10 @@
//- Check if boxes are within passed tolerance of each other.
//- If tolerance is 0, use && or || operator.
+ bool intersect(const CubitVector* ray_origin, const CubitVector* ray_direction,
+ CubitVector* intersection_pt = NULL);
+ //- Check if ray intersects box
+
//- Heading: Operators
// Operators that modify {this}
@@ -133,14 +137,14 @@
// Operators that return a modification of {this}.
// {this} itself is not modified.
- friend CubitBox operator|(const CubitBox& lhs, const CubitBox& rhs);
- friend CubitBox operator|(const CubitBox& lhs, const CubitVector& rhs);
- friend CubitBox operator&(const CubitBox& lhs, const CubitBox& rhs);
- friend CubitBox operator*(const CubitBox& lhs, double rhs);
- friend CubitBox operator*(double rhs, const CubitBox& lhs);
- friend CubitBox operator/(const CubitBox& lhs, double rhs);
- friend CubitBox operator+(const CubitBox& lhs, const CubitVector& rhs);
- friend CubitBox operator-(const CubitBox& lhs, const CubitVector& rhs);
+ friend CUBIT_UTIL_EXPORT CubitBox operator|(const CubitBox& lhs, const CubitBox& rhs);
+ friend CUBIT_UTIL_EXPORT CubitBox operator|(const CubitBox& lhs, const CubitVector& rhs);
+ friend CUBIT_UTIL_EXPORT CubitBox operator&(const CubitBox& lhs, const CubitBox& rhs);
+ friend CUBIT_UTIL_EXPORT CubitBox operator*(const CubitBox& lhs, double rhs);
+ friend CUBIT_UTIL_EXPORT CubitBox operator*(double rhs, const CubitBox& lhs);
+ friend CUBIT_UTIL_EXPORT CubitBox operator/(const CubitBox& lhs, double rhs);
+ friend CUBIT_UTIL_EXPORT CubitBox operator+(const CubitBox& lhs, const CubitVector& rhs);
+ friend CUBIT_UTIL_EXPORT CubitBox operator-(const CubitBox& lhs, const CubitVector& rhs);
#ifdef BOYD15
double distance( const CubitVector& position ) const;
Modified: cgm/branches/cubit/util/CubitColorConstants.hpp
===================================================================
--- cgm/branches/cubit/util/CubitColorConstants.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitColorConstants.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -4,14 +4,14 @@
const int CUBIT_DEFAULT_COLOR = -1;
const int CUBIT_BLACK = 0;
const int CUBIT_GREY = 1;
-const int CUBIT_GREEN = 2;
-const int CUBIT_YELLOW = 3;
-const int CUBIT_RED = 4;
-const int CUBIT_MAGENTA = 5;
-const int CUBIT_CYAN = 6;
-const int CUBIT_BLUE = 7;
-const int CUBIT_WHITE = 8;
-const int CUBIT_ORANGE = 9;
+const int CUBIT_ORANGE = 2;
+const int CUBIT_RED = 3;
+const int CUBIT_GREEN = 4;
+const int CUBIT_YELLOW = 5;
+const int CUBIT_MAGENTA = 6;
+const int CUBIT_CYAN = 7;
+const int CUBIT_BLUE = 8;
+const int CUBIT_WHITE = 9;
const int CUBIT_BROWN = 10;
const int CUBIT_GOLD = 11;
const int CUBIT_LIGHTBLUE = 12;
Modified: cgm/branches/cubit/util/CubitCoordinateSystem.cpp
===================================================================
--- cgm/branches/cubit/util/CubitCoordinateSystem.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitCoordinateSystem.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -1,7 +1,7 @@
#include "CubitCoordinateSystem.hpp"
-#include <assert.h>
+#include <cassert>
#include "CubitMessage.hpp"
Modified: cgm/branches/cubit/util/CubitDefines.h
===================================================================
--- cgm/branches/cubit/util/CubitDefines.h 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitDefines.h 2010-01-06 19:22:14 UTC (rev 3423)
@@ -18,6 +18,7 @@
#ifdef NT
#pragma warning ( 4 : 4291 4244 4305 4018 4786)
+#pragma warning(error : 4239)
#endif
/* Adds DBL_MIN, DBL_MAX definitions on some platforms*/
#include <float.h>
@@ -75,8 +76,10 @@
enum FirmnessType {LIMP, SOFT, FIRM, HARD};
/* Firmness continuum - how bad does the user want something?
- LIMP means "don't care" or "unset", SOFT means "about right" or
- "automatically set", HARD means "user set" or "must be this way".
+ LIMP - default setting--i.e. "don't care" or "unset"
+ SOFT - determined by basic geometric criteria--"about right" or "automatically set"
+ FIRM - determined by advanced heuristic data, including adjacent environmental data
+ HARD - user set--"must be this way"
*/
/* Relationships between types of objects in the Entity Relationship
Modified: cgm/branches/cubit/util/CubitDynamicLoader.cpp
===================================================================
--- cgm/branches/cubit/util/CubitDynamicLoader.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitDynamicLoader.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -1,6 +1,6 @@
// We have 4 different implementations here
-// Windows, Unix, MacOSX, HP-UX
+// Windows, Unix, , HP-UX
#include "CubitDynamicLoader.hpp"
@@ -48,6 +48,10 @@
}
}
+ // one more final attempt
+ if (stat(library, &buf) == 0)
+ return CUBIT_TRUE;
+
return CUBIT_FALSE;
}
@@ -188,83 +192,6 @@
return ".sl";
}
-#elif defined(__APPLE__)
-
-#include <mach-o/dyld.h>
-
-CubitDynamicLoader::LibraryHandle CubitDynamicLoader::InvalidLibraryHandle = NULL;
-
-CubitDynamicLoader::LibraryHandle CubitDynamicLoader::load_library(const char* lib)
-{
- NSObjectFileImageReturnCode rc;
- NSObjectFileImage image;
-
- LibraryHandle handle = InvalidLibraryHandle;
-
- // if absolute path, test it directly
- if(absolute_path(lib))
- {
- rc = NSCreateObjectFileImageFromFile(lib, &image);
- handle = NSLinkModule(image, lib, TRUE);
- }
- else
- {
- // try finding with our search paths
- for(int i=0; i<gSearchPaths.size(); i++)
- {
- CubitString path = gSearchPaths[i]+CubitString("/")+lib;
- rc = NSCreateObjectFileImageFromFile(path.c_str(), &image);
- handle = NSLinkModule(image, lib, TRUE);
- if(handle != InvalidLibraryHandle)
- return handle;
- }
- }
-
- // one more final attempt
- rc = NSCreateObjectFileImageFromFile(lib, &image);
- handle = NSLinkModule(image, lib, TRUE);
- return handle;
-}
-
-CubitString CubitDynamicLoader::get_error()
-{
- return CubitString();
-}
-
-CubitStatus CubitDynamicLoader::unload_library(CubitDynamicLoader::LibraryHandle lib)
-{
- return NSUnLinkModule(static_cast<NSModule>(lib), FALSE) == 0 ? CUBIT_SUCCESS : CUBIT_FAILURE;
-}
-
-void* CubitDynamicLoader::get_symbol_address(CubitDynamicLoader::LibraryHandle, const char* sym)
-{
- void *result = 0;
- // global 'C' symbols names are preceded with an underscore '_'
- char *_sym = new char[ strlen(sym) + 2 ];
- strcpy( _sym + 1, sym );
- _sym[0] = '_';
- if( NSIsSymbolNameDefined(_sym) )
- {
- NSSymbol symbol = NSLookupAndBindSymbol(_sym);
- if(symbol)
- {
- result = NSAddressOfSymbol(symbol);
- }
- }
- delete[] _sym;
- return result;
-}
-
-const char* CubitDynamicLoader::library_prefix()
-{
- return "lib";
-}
-
-const char* CubitDynamicLoader::library_extension()
-{
- return ".so";
-}
-
#else
#include <dlfcn.h>
Modified: cgm/branches/cubit/util/CubitEntity.cpp
===================================================================
--- cgm/branches/cubit/util/CubitEntity.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitEntity.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -11,8 +11,8 @@
#endif
-#include <assert.h>
-#include <string.h>
+#include <cassert>
+#include <cstring>
#include "CubitDefines.h"
#include "CubitVector.hpp"
@@ -65,7 +65,7 @@
int CubitEntity::id() const { return entityId; }
-void CubitEntity::set_id(int i) {entityId = i;}
+void CubitEntity::set_id(int i) { entityId = i; }
//- set the id of this entity to i
int CubitEntity::validate()
Modified: cgm/branches/cubit/util/CubitEventDefines.h
===================================================================
--- cgm/branches/cubit/util/CubitEventDefines.h 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitEventDefines.h 2010-01-06 19:22:14 UTC (rev 3423)
@@ -13,6 +13,8 @@
/* A ModelEntity was deleted */
COMPARISON_FOUND,
/* A partner entity was found (they compare successfully) */
+ DEVELOPER_COMMAND_FLAG_MODIFIED,
+ /* The 'set developer command on/off' was issued */
ENTITY_SURVIVED_MERGE,
/* An entity was involved in a merge and survived */
MERGE_COMPLETED,
@@ -34,6 +36,22 @@
* was changed. Used for virtual topology. */
GEOMETRY_MODIFIED,
/* The geometry of a RefEntity was altered. */
+ HEALER_COMPLETED,
+ /* Notifies that the healer completed */
+ COMPOSITE_CREATION_COMPLETED,
+ /* Notifies that a composite was created */
+ SPLIT_SURFACE_COMPLETED,
+ /* Notifies that a split face operation is done */
+ COLLAPSE_CURVE_COMPLETED,
+ /* Notifies that a collapse curve operation is done */
+ AUTO_CLEAN_COMPLETED,
+ /* Notifies that an auto_clean operation is done */
+ REMOVE_SURFACE_COMPLETED,
+ /* Notifies that a remove surface operation is done */
+ REMOVE_TOPOLOGY_COMPLETED,
+ /* Notifies that a remove_topology operation is done */
+ REGULARIZE_ENTITY_COMPLETED,
+ /* Notifies that a regularize entity operation is done */
NEW_ENTITY_UNMERGED,
/*A surface, curve, or vertex was unmerged. */
DAG_NODE_DESTRUCTED,
@@ -94,19 +112,30 @@
// Block, nodeset or sideset was deleted.
GENESIS_ENTITY_MODIFIED,
// Block, nodeset or sideset was modified.
+ MATERIAL_CREATED,
+ // Material created
+ MATERIAL_MODIFIED,
+ // Material modified
+ MATERIAL_DELETED,
+ // Material deleted
SUSPEND_GENESIS_PROCESSING,
// Suspend processing (in CubitInterface) for Genesis events
RESUME_GENESIS_PROCESSING,
// Resume processing (in CubitInterface) for Genesis events
UPDATE_GENESIS_DISPLAY,
// Force an update of all genesis entity display
+ UNDO_STATE_CHANGED,
+ // Undo has been changed in some way
+ UNDO_COMPLETE,
+ // Undo has completed its processing
-
// ******** Assembly Events *********
// All assembly events pass an AssemblyEvent
// object. The functions used to get valid
// data for a particular event type is listed
// right after the event type name.
+ WEBCUT_COMPLETED,
+ // Inform regarding the completion of a webcut operation
ASSEMBLY_ADD_CHILD,
// (get_assembly(), get_node())
@@ -147,7 +176,7 @@
// Sent just after a property of the tree changes.
// These are properties that apply to the tree as a whole,
// not to any individual AssemblyNode.
-
+
//
// ********* End of Assembly Events **********
};
Modified: cgm/branches/cubit/util/CubitFile.cpp
===================================================================
--- cgm/branches/cubit/util/CubitFile.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitFile.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -30,7 +30,7 @@
#include "CubitFileIOWrapper.hpp"
#include "CubitFileMetaData.hpp"
#include "CubitFileFEModel.hpp"
-#include <string.h>
+#include <cstring>
using namespace NCubitFile;
@@ -40,7 +40,7 @@
/* Note: some platforms define both BIG_ENDIAN and LITTLE_ENDIAN
so don't do if defined(LITTLE_ENDIAN) here. Compare to BYTE_ORDER instead. */
-#if defined(NT) || defined(DA) || defined(CUBIT_LINUX) || (defined(LITTLE_ENDIAN) && (BYTE_ORDER==LITTLE_ENDIAN)) /* should be little endian platforms */
+#if defined(NT) || defined(__LITTLE_ENDIAN__) || defined(CUBIT_LINUX) || (defined(LITTLE_ENDIAN) && (BYTE_ORDER==LITTLE_ENDIAN)) /* should be little endian platforms */
const UnsignedInt32 CCubitFile::mintNativeEndian = 0;
#else // big endian platforms
const UnsignedInt32 CCubitFile::mintNativeEndian = 0xFFFFFFFF;
@@ -451,7 +451,7 @@
// Initialize the new model's table entry.
mpaWriteModels[mWriteContents.mintNumModels].mintModelHandle =
- xintModel = mintNextModelID++;
+ xintModel;// = mintNextModelID++;
mpaWriteModels[mWriteContents.mintNumModels].mintModelOffset = 0;
mpaWriteModels[mWriteContents.mintNumModels].mintModelLength = 0;
mpaWriteModels[mWriteContents.mintNumModels].mintModelType = xeModelType;
@@ -975,6 +975,7 @@
UnsignedInt32 CCubitFile::WriteBlock(UnsignedInt32 xintIndex,
UnsignedInt32 xintBlockID,
+ int unique_id,
UnsignedInt32 xintBlockType,
UnsignedInt32 xintBlockColor,
UnsignedInt32 xintMixedElemType,
@@ -991,7 +992,7 @@
try {
if(!mpWriteFEModel)
throw eOrderError;
- mpWriteFEModel->WriteBlock(xintIndex, xintBlockID, xintBlockType,
+ mpWriteFEModel->WriteBlock(xintIndex, xintBlockID, unique_id, xintBlockType,
xintBlockColor, xintMixedElemType, xintDefPyramidType,
xintMaterialID, xintBlockDimension, xintNumTypes, xpaBlockData,
xintAttributeOrder, xpadblAttributes);
@@ -1003,18 +1004,20 @@
UnsignedInt32 CCubitFile::WriteNodeSet(UnsignedInt32 xintIndex,
UnsignedInt32 xintNodeSetID,
+ int unique_id,
UnsignedInt32 xintColor,
UnsignedInt32 xintPointSymbol,
UnsignedInt32 xintNumTypes,
- SNodeSetData* xpaNodeSetData)
+ SNodeSetData* xpaNodeSetData,
+ const std::vector<char>& bcdata)
// Try to write the membership of the passed group index to the writable file.
// RETURNS: 0 on success, other values indicate error code.
{
try {
if(!mpWriteFEModel)
throw eOrderError;
- mpWriteFEModel->WriteNodeSet(xintIndex, xintNodeSetID, xintColor,
- xintPointSymbol, xintNumTypes, xpaNodeSetData);
+ mpWriteFEModel->WriteNodeSet(xintIndex, xintNodeSetID, unique_id, xintColor,
+ xintPointSymbol, xintNumTypes, xpaNodeSetData, bcdata);
return eSuccess;
}
catch(EErrorCode xeErrorCode) { return xeErrorCode; }
@@ -1023,21 +1026,23 @@
UnsignedInt32 CCubitFile::WriteSideSet_11(UnsignedInt32 xintIndex,
UnsignedInt32 xintSideSetID,
+ int unique_id,
UnsignedInt32 xintColor,
UnsignedInt32 xintUseShells,
UnsignedInt32 xintNumTypes,
SSideSetData_11* xpaSideSetData,
UnsignedInt32 xintNumDistFact,
- double* xpadblDistribution)
+ double* xpadblDistribution,
+ const std::vector<char>& bcdata)
// Try to write the membership of the passed group index to the writable file.
// RETURNS: 0 on success, other values indicate error code.
{
try {
if(!mpWriteFEModel)
throw eOrderError;
- mpWriteFEModel->WriteSideSet_11(xintIndex, xintSideSetID, xintColor,
+ mpWriteFEModel->WriteSideSet_11(xintIndex, xintSideSetID, unique_id, xintColor,
xintUseShells, xintNumTypes, xpaSideSetData, xintNumDistFact,
- xpadblDistribution);
+ xpadblDistribution, bcdata);
return eSuccess;
}
catch(EErrorCode xeErrorCode) { return xeErrorCode; }
@@ -1216,6 +1221,7 @@
UnsignedInt32 CCubitFile::ReadBlock(UnsignedInt32 xintIndex,
UnsignedInt32& xintBlockID,
+ int& unique_id,
UnsignedInt32& xintBlockType,
UnsignedInt32& xintBlockColor,
UnsignedInt32& xintMixedElemType,
@@ -1234,7 +1240,7 @@
try {
if(!mpReadFEModel)
throw eOrderError;
- mpReadFEModel->ReadBlock(xintIndex, xintBlockID,
+ mpReadFEModel->ReadBlock(xintIndex, xintBlockID, unique_id,
xintBlockType, xintBlockColor, xintMixedElemType,
xintDefPyramidType, xintMaterialID, xintBlockDimension,
xintNumTypes, xpaBlockData, xintAttributeOrder, xpadblAttributes);
@@ -1256,10 +1262,12 @@
UnsignedInt32 CCubitFile::ReadNodeSet(UnsignedInt32 xintIndex,
UnsignedInt32& xintNodeSetID,
+ int& unique_id,
UnsignedInt32& xintColor,
UnsignedInt32& xintPointSymbol,
UnsignedInt32& xintNumTypes,
- SNodeSetData*& xpaNodeSetData)
+ SNodeSetData*& xpaNodeSetData,
+ std::vector<char>& bcdata)
// Try to read the membership of the passed node set index from the read-only file.
// Note: The
// RETURNS: 0 on success, other values indicate error code.
@@ -1268,8 +1276,8 @@
try {
if(!mpReadFEModel)
throw eOrderError;
- mpReadFEModel->ReadNodeSet(xintIndex, xintNodeSetID,
- xintColor, xintPointSymbol, xintNumTypes, xpaNodeSetData);
+ mpReadFEModel->ReadNodeSet(xintIndex, xintNodeSetID, unique_id,
+ xintColor, xintPointSymbol, xintNumTypes, xpaNodeSetData, bcdata);
return eSuccess;
}
catch(EErrorCode xeErrorCode) {
@@ -1318,12 +1326,14 @@
UnsignedInt32 CCubitFile::ReadSideSet_11(UnsignedInt32 xintIndex,
UnsignedInt32& xintSideSetID,
+ int& unique_id,
UnsignedInt32& xintColor,
UnsignedInt32& xintUseShells,
UnsignedInt32& xintNumTypes,
SSideSetData_11*& xpaSideSetData,
UnsignedInt32& xintNumDistFact,
- double*& xpadblDistribution)
+ double*& xpadblDistribution,
+ std::vector<char>& bcdata)
// Try to read the membership of the passed side set index from the read-only file.
// Note: The
// RETURNS: 0 on success, other values indicate error code.
@@ -1332,9 +1342,9 @@
try {
if(!mpReadFEModel)
throw eOrderError;
- mpReadFEModel->ReadSideSet_11(xintIndex, xintSideSetID,
+ mpReadFEModel->ReadSideSet_11(xintIndex, xintSideSetID, unique_id,
xintColor, xintUseShells, xintNumTypes, xpaSideSetData,
- xintNumDistFact, xpadblDistribution);
+ xintNumDistFact, xpadblDistribution, bcdata);
return eSuccess;
}
catch(EErrorCode xeErrorCode) {
Modified: cgm/branches/cubit/util/CubitFile.hpp
===================================================================
--- cgm/branches/cubit/util/CubitFile.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitFile.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -30,9 +30,10 @@
#ifndef CubitFile_HPP
#define CubitFile_HPP
-#include <stdio.h>
+#include <cstdio>
#include <memory.h>
#include "CubitUtilConfigure.h"
+#include <vector>
namespace NCubitFile {
@@ -159,21 +160,30 @@
ConstCharPtr xpachrGroupName,
UnsignedInt32 xintNumTypes, SGroupData* xpaGroupData);
UnsignedInt32 WriteBlock(UnsignedInt32 xintIndex,
- UnsignedInt32 xintBlockID, UnsignedInt32 xintBlockType,
+ UnsignedInt32 xintBlockID,
+ int block_unique_id,
+ UnsignedInt32 xintBlockType,
UnsignedInt32 xintBlockColor, UnsignedInt32 xintMixedElemType,
UnsignedInt32 xintDefPyramidType, UnsignedInt32 xintMaterialID,
UnsignedInt32 xintBlockDimension,
UnsignedInt32 xintNumTypes, SBlockData* xpaBlockData,
UnsignedInt32 xintAttributeOrder, double* xpadblAttributes);
UnsignedInt32 WriteNodeSet(UnsignedInt32 xintIndex,
- UnsignedInt32 xintNodeSetID, UnsignedInt32 xintColor,
+ UnsignedInt32 xintNodeSetID,
+ int nodeset_unique_id,
+ UnsignedInt32 xintColor,
UnsignedInt32 xintPointSymbol,
- UnsignedInt32 xintNumTypes, SNodeSetData* xpaNodeSetData);
+ UnsignedInt32 xintNumTypes, SNodeSetData* xpaNodeSetData,
+ const std::vector<char>& bcdata
+ );
UnsignedInt32 WriteSideSet_11(UnsignedInt32 xintIndex,
- UnsignedInt32 xintSideSetID, UnsignedInt32 xintColor,
+ UnsignedInt32 xintSideSetID,
+ int sideset_unique_id,
+ UnsignedInt32 xintColor,
UnsignedInt32 xintUseShells,
UnsignedInt32 xintNumTypes, SSideSetData_11* xpaSideSetData,
- UnsignedInt32 xintNumDistFact, double* xpadblDistribution);
+ UnsignedInt32 xintNumDistFact, double* xpadblDistribution,
+ const std::vector<char>& bcdata);
UnsignedInt32 EndWriteFEModel();
UnsignedInt32 BeginReadFEModel(HModel xintFEModel,
@@ -194,16 +204,17 @@
UnsignedInt32 ReadGroupMembers(UnsignedInt32 xintIndex,
UnsignedInt32& xintNumTypes, SGroupData*& xpaGroupData);
UnsignedInt32 ReadBlock(UnsignedInt32 xintIndex,
- UnsignedInt32& xintBlockID, UnsignedInt32& xintBlockType,
+ UnsignedInt32& xintBlockID, int& unique_id, UnsignedInt32& xintBlockType,
UnsignedInt32& xintBlockColor, UnsignedInt32& xintMixedElemType,
UnsignedInt32& xintDefPyramidType, UnsignedInt32& xintMaterialID,
UnsignedInt32& xintBlockDimension,
UnsignedInt32& xintNumTypes, SBlockData*& xpaBlockData,
UnsignedInt32& xintAttributeOrder, double*& xpadblAttributes);
UnsignedInt32 ReadNodeSet(UnsignedInt32 xintIndex,
- UnsignedInt32& xintNodeSetID, UnsignedInt32& xintColor,
+ UnsignedInt32& xintNodeSetID, int& unique_id, UnsignedInt32& xintColor,
UnsignedInt32& xintPointSymbol,
- UnsignedInt32& xintNumTypes, SNodeSetData*& xpaNodeSetData);
+ UnsignedInt32& xintNumTypes, SNodeSetData*& xpaNodeSetData,
+ std::vector<char>& bcdata);
// read old sideset format
UnsignedInt32 ReadSideSet_10(UnsignedInt32 xintIndex,
@@ -214,10 +225,11 @@
// read new sideset format
UnsignedInt32 ReadSideSet_11(UnsignedInt32 xintIndex,
- UnsignedInt32& xintSideSetID, UnsignedInt32& xintColor,
+ UnsignedInt32& xintSideSetID, int& unique_id, UnsignedInt32& xintColor,
UnsignedInt32& xintUseShells,
UnsignedInt32& xintNumTypes, SSideSetData_11*& xpaSideSetData,
- UnsignedInt32& xintNumDistFact, double*& xpadblDistribution);
+ UnsignedInt32& xintNumDistFact, double*& xpadblDistribution,
+ std::vector<char>& bcdata);
UnsignedInt32 EndReadFEModel();
Modified: cgm/branches/cubit/util/CubitFileFEModel.cpp
===================================================================
--- cgm/branches/cubit/util/CubitFileFEModel.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitFileFEModel.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -396,6 +396,7 @@
void CFEModel::WriteBlock(UnsignedInt32 xintIndex,
UnsignedInt32 xintBlockID,
+ int unique_id,
UnsignedInt32 xintBlockType,
UnsignedInt32 xintBlockColor,
UnsignedInt32 xintMixedElemType,
@@ -464,6 +465,9 @@
}
if(xintAttributeOrder)
lpIO->Write(xpadblAttributes, xintAttributeOrder);
+
+ lpIO->Write("id", 2);
+ lpIO->Write(reinterpret_cast<UnsignedInt32*>(&unique_id), 1);
mpaBlocks[xintIndex].mintBlockLength = lpIO->EndWriteBlock();
mFEModel.mintFEModelLength += mpaBlocks[xintIndex].mintBlockLength;
@@ -478,10 +482,12 @@
void CFEModel::WriteNodeSet(UnsignedInt32 xintIndex,
UnsignedInt32 xintNodeSetID,
+ int unique_id,
UnsignedInt32 xintColor,
UnsignedInt32 xintPointSymbol,
UnsignedInt32 xintNumTypes,
- SNodeSetData* xpaNodeSetData)
+ SNodeSetData* xpaNodeSetData,
+ const std::vector<char>& bcdata)
{
if(!mpWriteFile)
throw CCubitFile::eFileWriteError;
@@ -528,6 +534,17 @@
xpaNodeSetData[lintNodeSet].mintMemberCount);
}
+ UnsignedInt32 size = bcdata.size();
+ if(size)
+ {
+ lpIO->Write("bc", 2);
+ lpIO->Write(&size, 1);
+ lpIO->Write(&bcdata[0], size);
+ }
+
+ lpIO->Write("id", 2);
+ lpIO->Write(reinterpret_cast<UnsignedInt32*>(&unique_id), 1);
+
mpaNodeSets[xintIndex].mintNodeSetLength = lpIO->EndWriteBlock();
mFEModel.mintFEModelLength += mpaNodeSets[xintIndex].mintNodeSetLength;
delete lpIO;
@@ -541,12 +558,14 @@
void CFEModel::WriteSideSet_11(UnsignedInt32 xintIndex,
UnsignedInt32 xintSideSetID,
+ int unique_id,
UnsignedInt32 xintColor,
UnsignedInt32 xintUseShells,
UnsignedInt32 xintNumTypes,
SSideSetData_11* xpaSideSetData,
UnsignedInt32 xintNumDistFact,
- double* xpadblDistribution)
+ double* xpadblDistribution,
+ const std::vector<char>& bcdata)
{
if(!mpWriteFile)
throw CCubitFile::eFileWriteError;
@@ -621,7 +640,18 @@
}
if(xintNumDistFact)
lpIO->Write(xpadblDistribution, xintNumDistFact);
+
+ UnsignedInt32 size = bcdata.size();
+ if(size)
+ {
+ lpIO->Write("bc", 2);
+ lpIO->Write(&size, 1);
+ lpIO->Write(&bcdata[0], size);
+ }
+ lpIO->Write("id", 2);
+ lpIO->Write(reinterpret_cast<UnsignedInt32*>(&unique_id), 1);
+
mpaSideSets[xintIndex].mintSideSetLength = lpIO->EndWriteBlock();
mFEModel.mintFEModelLength += mpaSideSets[xintIndex].mintSideSetLength;
delete lpIO;
@@ -991,6 +1021,7 @@
void CFEModel::ReadBlock(UnsignedInt32 xintIndex,
UnsignedInt32& xintBlockID,
+ int& unique_id,
UnsignedInt32& xintBlockType,
UnsignedInt32& xintBlockColor,
UnsignedInt32& xintMixedElemType,
@@ -1002,6 +1033,7 @@
UnsignedInt32& xintAttributeOrder,
double*& xpadblAttributes)
{
+ unique_id = 0;
if(!mpReadFile)
throw CCubitFile::eFileReadError;
if(xintIndex >= mFEModel.mintBlockCount)
@@ -1035,6 +1067,7 @@
CIOWrapper* lpIO = new CIOWrapper(mpReadFile, mFEModel.mintFEModelEndian);
lpIO->BeginReadBlock(mintFEModelOffset,
mpaBlocks[xintIndex].mintMemberOffset);
+ long start_location = lpIO->GetLocation();
for(UnsignedInt32 lintType = 0; lintType < xintNumTypes; lintType++) {
lpIO->Read(&xpaBlockData[lintType].mintMemberType, 1);
lpIO->Read(&xpaBlockData[lintType].mintMemberCount, 1);
@@ -1053,6 +1086,23 @@
}
if(xintAttributeOrder)
lpIO->Read(xpadblAttributes, xintAttributeOrder);
+
+ // see if there is more data
+ int diff = lpIO->GetLocation() - start_location;
+ int remaining = diff - mpaBlocks[xintIndex].mintBlockLength;
+ while(remaining)
+ {
+ // remaining data could be bc data
+ char type[2];
+ lpIO->Read(type, 2);
+ if(type[0] == 'i' && type[1] == 'd')
+ {
+ lpIO->Read(reinterpret_cast<UnsignedInt32*>(&unique_id), 1);
+ }
+ remaining = (lpIO->GetLocation() - start_location) -
+ mpaBlocks[xintIndex].mintBlockLength;
+ }
+
lpIO->EndReadBlock();
delete lpIO;
}
@@ -1064,11 +1114,14 @@
void CFEModel::ReadNodeSet(UnsignedInt32 xintIndex,
UnsignedInt32& xintNodeSetID,
+ int& unique_id,
UnsignedInt32& xintColor,
UnsignedInt32& xintPointSymbol,
UnsignedInt32& xintNumTypes,
- SNodeSetData*& xpaNodeSetData)
+ SNodeSetData*& xpaNodeSetData,
+ std::vector<char>& bcdata)
{
+ unique_id = 0;
if(!mpReadFile)
throw CCubitFile::eFileReadError;
if(xintIndex >= mFEModel.mintNodeSetCount)
@@ -1081,7 +1134,8 @@
xintPointSymbol = mpaNodeSets[xintIndex].mintNodeSetPointSym;
xintColor = mpaNodeSets[xintIndex].mintNodeSetColor;
- if(xintNumTypes) {
+ if(xintNumTypes)
+ {
// Resize the node set return buffer if necessary and then set the return
// pointers to the buffer.
xpaNodeSetData = AdjustBuffer(xintNumTypes,
@@ -1095,6 +1149,7 @@
CIOWrapper* lpIO = new CIOWrapper(mpReadFile, mFEModel.mintFEModelEndian);
lpIO->BeginReadBlock(mintFEModelOffset,
mpaNodeSets[xintIndex].mintMemberOffset);
+ long start_location = lpIO->GetLocation();
for(UnsignedInt32 lintType = 0; lintType < xintNumTypes; lintType++) {
lpIO->Read(&xpaNodeSetData[lintType].mintMemberType, 1);
lpIO->Read(&xpaNodeSetData[lintType].mintMemberCount, 1);
@@ -1111,6 +1166,31 @@
lpIDs = &lpIDs[lintNumMembers];
}
+
+ // see if there is more data
+ int diff = lpIO->GetLocation() - start_location;
+ int remaining = diff - mpaNodeSets[xintIndex].mintNodeSetLength;
+ while(remaining)
+ {
+ // remaining data could be bc data
+ char type[2];
+ lpIO->Read(type, 2);
+ if(type[0] == 'b' && type[1] == 'c')
+ {
+ // get serialize data size
+ UnsignedInt32 size;
+ lpIO->Read(&size, 1);
+ bcdata.resize(size);
+ lpIO->Read(&bcdata[0], size);
+ }
+ else if(type[0] == 'i' && type[1] == 'd')
+ {
+ lpIO->Read(reinterpret_cast<UnsignedInt32*>(&unique_id), 1);
+ }
+ remaining = (lpIO->GetLocation() - start_location) -
+ mpaNodeSets[xintIndex].mintNodeSetLength;
+ }
+
lpIO->EndReadBlock();
delete lpIO;
}
@@ -1220,13 +1300,16 @@
void CFEModel::ReadSideSet_11(UnsignedInt32 xintIndex,
UnsignedInt32& xintSideSetID,
+ int& unique_id,
UnsignedInt32& xintColor,
UnsignedInt32& xintUseShells,
UnsignedInt32& xintNumTypes,
SSideSetData_11*& xpaSideSetData,
UnsignedInt32& xintNumDistFact,
- double*& xpadblDistribution)
+ double*& xpadblDistribution,
+ std::vector<char>& bcdata)
{
+ unique_id = 0;
if(!mpReadFile)
throw CCubitFile::eFileReadError;
if(xintIndex >= mFEModel.mintSideSetCount)
@@ -1263,6 +1346,7 @@
CIOWrapper* lpIO = new CIOWrapper(mpReadFile, mFEModel.mintFEModelEndian);
lpIO->BeginReadBlock(mintFEModelOffset,
mpaSideSets[xintIndex].mintMemberOffset);
+ long start_location = lpIO->GetLocation();
for(UnsignedInt32 lintType = 0; lintType < xintNumTypes; lintType++) {
lpIO->Read(&xpaSideSetData[lintType].mintMemberCount, 1);
@@ -1300,6 +1384,32 @@
}
if(xintNumDistFact)
lpIO->Read(xpadblDistribution, xintNumDistFact);
+
+ // see if there is more data
+ int diff = lpIO->GetLocation() - start_location;
+ int remaining = diff - mpaSideSets[xintIndex].mintSideSetLength;
+ while(remaining)
+ {
+ // remaining data could be bc data
+ char type[2];
+ lpIO->Read(type, 2);
+ if(type[0] == 'b' && type[1] == 'c')
+ {
+ // get serialize data size
+ UnsignedInt32 size;
+ lpIO->Read(&size, 1);
+ bcdata.resize(size);
+ lpIO->Read(&bcdata[0], size);
+ }
+ // or unique id
+ else if(type[0] == 'i' && type[1] == 'd')
+ {
+ lpIO->Read(reinterpret_cast<UnsignedInt32*>(&unique_id), 1);
+ }
+ remaining = (lpIO->GetLocation() - start_location) -
+ mpaSideSets[xintIndex].mintSideSetLength;
+ }
+
lpIO->EndReadBlock();
delete lpIO;
}
Modified: cgm/branches/cubit/util/CubitFileFEModel.hpp
===================================================================
--- cgm/branches/cubit/util/CubitFileFEModel.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitFileFEModel.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -27,12 +27,13 @@
*******************************************************************************/
+#ifndef CubitFileFEModel_HPP
+#define CubitFileFEModel_HPP
+
#include "CubitFileMetaData.hpp"
#include "CubitUtilConfigure.h"
+#include <vector>
-#ifndef CubitFileFEModel_HPP
-#define CubitFileFEModel_HPP
-
namespace NCubitFile {
class CUBIT_UTIL_EXPORT CFEModel {
@@ -53,21 +54,23 @@
UnsignedInt32 xintGroupType, const char* xpachrGroupName,
UnsignedInt32 xintNumTypes, SGroupData* xpaGroupData);
void WriteBlock(UnsignedInt32 xintIndex,
- UnsignedInt32 xintBlockID, UnsignedInt32 xintBlockType,
+ UnsignedInt32 xintBlockID, int unique_id, UnsignedInt32 xintBlockType,
UnsignedInt32 xintBlockColor, UnsignedInt32 xintMixedElemType,
UnsignedInt32 xintDefPyramidType, UnsignedInt32 xintMaterialID,
UnsignedInt32 xintBlockDimension,
UnsignedInt32 xintNumTypes, SBlockData* xpaBlockData,
UnsignedInt32 xintAttributeOrder, double* xpadblAttributes);
void WriteNodeSet(UnsignedInt32 xintIndex,
- UnsignedInt32 xintNodeSetID, UnsignedInt32 xintColor,
+ UnsignedInt32 xintNodeSetID, int unique_id, UnsignedInt32 xintColor,
UnsignedInt32 xintPointSymbol,
- UnsignedInt32 xintNumTypes, SNodeSetData* xpaNodeSetData);
+ UnsignedInt32 xintNumTypes, SNodeSetData* xpaNodeSetData,
+ const std::vector<char>& bcdata);
void WriteSideSet_11(UnsignedInt32 xintIndex,
- UnsignedInt32 xintSideSetID, UnsignedInt32 xintColor,
+ UnsignedInt32 xintSideSetID, int unique_id, UnsignedInt32 xintColor,
UnsignedInt32 xintUseShells,
UnsignedInt32 xintNumTypes, SSideSetData_11* xpaSideSetData,
- UnsignedInt32 xintNumDistFact, double* xpadblDistribution);
+ UnsignedInt32 xintNumDistFact, double* xpadblDistribution,
+ const std::vector<char>& bcdata);
UnsignedInt32 EndWrite();
void InitRead(FILE* xpFile, UnsignedInt32 xintAbsoluteOffset,
@@ -84,26 +87,28 @@
void ReadGroupMembers(UnsignedInt32 xintIndex,
UnsignedInt32& xintNumTypes, SGroupData*& xpaGroupData);
void ReadBlock(UnsignedInt32 xintIndex,
- UnsignedInt32& xintBlockID, UnsignedInt32& xintBlockType,
+ UnsignedInt32& xintBlockID, int& unique_id, UnsignedInt32& xintBlockType,
UnsignedInt32& xintBlockColor, UnsignedInt32& xintMixedElemType,
UnsignedInt32& xintDefPyramidType, UnsignedInt32& xintMaterialID,
UnsignedInt32& xintBlockDimension,
UnsignedInt32& xintNumTypes, SBlockData*& xpaBlockData,
UnsignedInt32& xintAttributeOrder, double*& xpadblAttributes);
void ReadNodeSet(UnsignedInt32 xintIndex,
- UnsignedInt32& xintNodeSetID, UnsignedInt32& xintColor,
+ UnsignedInt32& xintNodeSetID, int& unique_id, UnsignedInt32& xintColor,
UnsignedInt32& xintPointSymbol,
- UnsignedInt32& xintNumTypes, SNodeSetData*& xpaNodeSetData);
+ UnsignedInt32& xintNumTypes, SNodeSetData*& xpaNodeSetData,
+ std::vector<char>& bcdata);
void ReadSideSet_10(UnsignedInt32 xintIndex,
UnsignedInt32& xintSideSetID, UnsignedInt32& xintColor,
UnsignedInt32& xintUseShells,
UnsignedInt32& xintNumTypes, SSideSetData_10*& xpaSideSetData,
UnsignedInt32& xintNumDistFact, double*& xpadblDistribution);
void ReadSideSet_11(UnsignedInt32 xintIndex,
- UnsignedInt32& xintSideSetID, UnsignedInt32& xintColor,
+ UnsignedInt32& xintSideSetID, int& unique_id, UnsignedInt32& xintColor,
UnsignedInt32& xintUseShells,
UnsignedInt32& xintNumTypes, SSideSetData_11*& xpaSideSetData,
- UnsignedInt32& xintNumDistFact, double*& xpadblDistribution);
+ UnsignedInt32& xintNumDistFact, double*& xpadblDistribution,
+ std::vector<char>& bcdata);
void EndRead();
CMetaData& GetGeomMetaData();
Modified: cgm/branches/cubit/util/CubitFileIOWrapper.cpp
===================================================================
--- cgm/branches/cubit/util/CubitFileIOWrapper.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitFileIOWrapper.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -27,7 +27,7 @@
*******************************************************************************/
#include "CubitFileIOWrapper.hpp"
-#include <string.h>
+#include <cstring>
using namespace NCubitFile;
@@ -240,4 +240,9 @@
{
mintBlockStart = mintBlockEnd = 0;
}
+
+long CIOWrapper::GetLocation()
+{
+ return ftell(mpFile);
+}
Modified: cgm/branches/cubit/util/CubitFileIOWrapper.hpp
===================================================================
--- cgm/branches/cubit/util/CubitFileIOWrapper.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitFileIOWrapper.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -63,6 +63,8 @@
virtual char* Read();
virtual void EndReadBlock();
virtual UnsignedInt32 get_endian() { return mintSwapEndian; }
+
+ virtual long GetLocation();
private:
FILE* mpFile;
Modified: cgm/branches/cubit/util/CubitFileMetaData.cpp
===================================================================
--- cgm/branches/cubit/util/CubitFileMetaData.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitFileMetaData.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -28,7 +28,7 @@
#include "CubitFileMetaData.hpp"
#include "CubitFileIOWrapper.hpp"
-#include <string.h>
+#include <cstring>
using namespace NCubitFile;
Modified: cgm/branches/cubit/util/CubitFileUtil.cpp
===================================================================
--- cgm/branches/cubit/util/CubitFileUtil.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitFileUtil.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -17,7 +17,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
- #include <stdlib.h>
+ #include <cstdlib>
#include <sys/param.h>
#include <unistd.h>
#include <pwd.h>
Modified: cgm/branches/cubit/util/CubitInputFile.hpp
===================================================================
--- cgm/branches/cubit/util/CubitInputFile.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitInputFile.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -2,7 +2,7 @@
#define CUBITINPUTFILE_HPP
#include "CubitString.hpp"
-#include <stdio.h>
+#include <cstdio>
#include "CubitMessage.hpp"
struct CubitInputFile
Modified: cgm/branches/cubit/util/CubitMatrix.cpp
===================================================================
--- cgm/branches/cubit/util/CubitMatrix.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitMatrix.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -3,7 +3,7 @@
//- Owner: Dan Goodrich
//- Checked by:
-#include <assert.h>
+#include <cassert>
#include "CubitMatrix.hpp"
#include "CubitMessage.hpp"
@@ -394,7 +394,6 @@
assert( fabs(det) > CUBIT_DBL_MIN );
matrix_inverse.set(0,0, matrixPtr[0][0]);
- matrix_inverse *= det_inv;
}
if ( numRows == 2 ) {
@@ -402,7 +401,6 @@
matrix_inverse.set(1,0,-matrixPtr[1][0]);
matrix_inverse.set(0,1,-matrixPtr[0][1]);
matrix_inverse.set(1,1, matrixPtr[0][0]);
- matrix_inverse *= det_inv;
}
if ( numRows == 3 ) {
Modified: cgm/branches/cubit/util/CubitMessage.cpp
===================================================================
--- cgm/branches/cubit/util/CubitMessage.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitMessage.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -6,8 +6,8 @@
#include "CubitDefines.h"
#include "CubitString.hpp"
#include "CubitUtil.hpp"
-#include <assert.h>
-#include <string.h>
+#include <cassert>
+#include <cstring>
#include <vector>
#include "SettingHandler.hpp"
@@ -33,6 +33,7 @@
int CubitMessage::infoFlag = CUBIT_TRUE;
int CubitMessage::diagnosticFlag = CUBIT_FALSE;
int CubitMessage::warningFlag = CUBIT_TRUE;
+int CubitMessage::errorFlag = CUBIT_TRUE;
std::ofstream* CubitMessage::loggingStream = NULL;
CubitString* CubitMessage::loggingFile = NULL;
std::ofstream* CubitMessage::loggingErrorStream = NULL;
@@ -56,6 +57,7 @@
{
infoFlag = CUBIT_TRUE;
warningFlag = CUBIT_TRUE;
+ errorFlag = CUBIT_TRUE;
diagnosticFlag= CUBIT_FALSE;
loggingStream = NULL;
loggingFile = NULL;
@@ -66,108 +68,108 @@
// Initialize the debugFlag array
static MessageFlag staticDebugFlag[] =
{
- MessageFlag( 0, "UNUSED"),
- MessageFlag( 1, "Debug Graphics toggle for some debug options."),
- MessageFlag( 2, "Whisker weaving information"),
- MessageFlag( 3, "Timing information for 3D Meshing routines."),
- MessageFlag( 4, "Graphics Debugging (DrawingTool)"),
- MessageFlag( 5, "FastQ debugging"),
- MessageFlag( 6, "Submapping graphics debugging"),
- MessageFlag( 7, "Knife progress whisker weaving information"),
- MessageFlag( 8, "Mapping Face debug / Linear Programing debug "),
- MessageFlag( 9, "Paver Debugging"),
- MessageFlag(10, "WW: removed hex seam flag"),
- MessageFlag(11, "Nodeset Associativity debugging"),
- MessageFlag(12, "Fastq activity"),
- MessageFlag(13, "Mesh entities"),
- MessageFlag(14, "Model activity"),
- MessageFlag(15, "2.5D Debugging (Project, Translate, Rotate)"),
- MessageFlag(16, "RefFace activity"),
- MessageFlag(17, "Use Count debugging"),
- MessageFlag(18, "Webcut debugging"),
- MessageFlag(19, "Feature Merge / Unmerge debugging"),
- MessageFlag(20, "Parallel meshing activity"),
- MessageFlag(21, "Boundary Layer Tool Debugging"),
- MessageFlag(22, "ExodusMesh sizing function debugging"),
- MessageFlag(23, "Draw after joining chords in WW"),
- MessageFlag(24, "SelfCrossingLoop (and derivatives) debug info"),
- MessageFlag(25, "Extra invalidity checking in WW"),
- MessageFlag(26, "Surface Smoothing"),
- MessageFlag(27, "Primal Construction debugging, see also flag 70"),
- MessageFlag(28, "Plastering debugging"),
- MessageFlag(29, "Volume SubMapping"),
- MessageFlag(30, "Volume Mapping"),
- MessageFlag(31, "CleanUp debugging"),
- MessageFlag(32, "Pyramid debugging"),
- MessageFlag(33, "Whisker Weaving inside chord list face drawing"),
- MessageFlag(34, "If on Whisker Weaving doesn't merge sheets"),
- MessageFlag(35, "If on WW query displays sheets before joining chords"),
- MessageFlag(36, "Enable/Disable idr_keyword_debugger function"),
- MessageFlag(37, "Superdrive debugging"),
- MessageFlag(38, "WW hex formation messages"),
- MessageFlag(39, "Doublet Pillower graphics output"),
- MessageFlag(40, "Element Quality debugging output"),
- MessageFlag(41, "Check_join adjacency check"),
- MessageFlag(42, "Auto vertex type and sweep verification"),
- MessageFlag(43, "Programmer Errors for SubMapping"),
- MessageFlag(44, "Submapping Graphics Debugging"),
- MessageFlag(45, "Pillow Sheet debugging"),
- MessageFlag(46, "Paver breakout detection (expensive)"),
- MessageFlag(47, "Extra LP debugging (see flag 8 also)"),
- MessageFlag(48, "Geometry sizing function."),
- MessageFlag(49, "Draws Face by Face Creation in Paving"),
- MessageFlag(50, "Debugging for AutoSchemeSelect"),
- MessageFlag(51, "Modified Paver (row by row, more intersection checking)"),
- MessageFlag(52, "User Interface: If flag is enabled, filenames being\n"
- "\t\t\tused for input will be echoed and each input line\n"
- "\t\t\twill be echoed prior to being parsed."),
- MessageFlag(53, "Surface Morpher debugging"),
- MessageFlag(54, "Parser debugging"),
- MessageFlag(55, "Stairtool general debugging"),
- MessageFlag(56, "Stairtool face intersection debugging"),
- MessageFlag(57, "Relative Interval/Length setting"),
- MessageFlag(58, "StcVertex debugging of Whisker Weaving" ),
- MessageFlag(59, "VGI developer error"),
- MessageFlag(60, "StcVertex debugging of Looping" ),
- MessageFlag(61, "List number of points used in curve faceting" ),
- MessageFlag(62, "Print verbose information on group operations"),
- MessageFlag(63, "Label Whisker Weaving diagrams tersely"),
- MessageFlag(64, "No label on Whisker Weaving diagrams"),
- MessageFlag(65, "Volume Morpher debugging"),
- MessageFlag(66, "Print debug information on importing Pro/E geometry"),
- MessageFlag(67, "List number of triangles used in surface faceting" ),
- MessageFlag(68, "Debug information on tetrizing volumes" ),
- MessageFlag(69, "Debug information on tet mesher geometry access" ),
- MessageFlag(70, "STC Pillowing, see also flag 27" ),
- MessageFlag(71, "Hex-Tet Debug Flag"),
- MessageFlag(72, "DoubletPillower text messages"),
- MessageFlag(73, "Auto Surface debugging (use new auto surf select)"),
- MessageFlag(74, "Feature-based decomposition info"),
- MessageFlag(75, "Many-to-many sweep imprint debugging"),
- MessageFlag(76, "Virtual point and partition curve"),
- MessageFlag(77, "Volume interval matching"),
- MessageFlag(78, "Tipton Smoother jacobian modification enabler"),
- MessageFlag(79, "VoidCleanupTool debugging"),
- MessageFlag(80, "Hex-Tet informational messages"),
- MessageFlag(81, "Curve Morpher Debugging"),
- MessageFlag(82, "Diamond debugging"),
- MessageFlag(83, "AutoSizer debugging"),
- MessageFlag(84, "Surface auto decomposition"),
- MessageFlag(85, "U-SubMapping debugging"),
- MessageFlag(86, "Virtual curve and partition surface"),
- MessageFlag(87, "Composite curve and composite surface"),
- MessageFlag(88, "Volume partitioning"),
- MessageFlag(89, "Tet meshing warning and debug messages"),
- MessageFlag(90, "Geometry attributes"),
- MessageFlag(91, "Smoothing Debug Output"),
- MessageFlag(92, "Print name changed warnings"),
- MessageFlag(93, "Hex Fix Up"),
- MessageFlag(94, "Entity name attribute"),
- MessageFlag(95, "Group imprint errors"),
- MessageFlag(96, "GraftTool debugging"),
- MessageFlag(97, "Quality details"),
- MessageFlag(98, "Color code imported THEX meshes"),
- MessageFlag(99, "Geometry creation"),
+ MessageFlag( 0, "UNUSED"),
+ MessageFlag( 1, "Debug Graphics toggle for some debug options."),
+ MessageFlag( 2, "Whisker weaving information"),
+ MessageFlag( 3, "Timing information for 3D Meshing routines."),
+ MessageFlag( 4, "Graphics Debugging (DrawingTool)"),
+ MessageFlag( 5, "FastQ debugging"),
+ MessageFlag( 6, "Submapping graphics debugging"),
+ MessageFlag( 7, "Knife progress whisker weaving information"),
+ MessageFlag( 8, "Mapping Face debug / Linear Programing debug "),
+ MessageFlag( 9, "Paver Debugging"),
+ MessageFlag( 10, "WW: removed hex seam flag"),
+ MessageFlag( 11, "Nodeset Associativity debugging"),
+ MessageFlag( 12, "Fastq activity"),
+ MessageFlag( 13, "Mesh entities"),
+ MessageFlag( 14, "Model activity"),
+ MessageFlag( 15, "2.5D Debugging (Project, Translate, Rotate)"),
+ MessageFlag( 16, "RefFace activity"),
+ MessageFlag( 17, "Use Count debugging"),
+ MessageFlag( 18, "Webcut debugging"),
+ MessageFlag( 19, "Feature Merge / Unmerge debugging"),
+ MessageFlag( 20, "Parallel meshing activity"),
+ MessageFlag( 21, "Boundary Layer Tool Debugging"),
+ MessageFlag( 22, "ExodusMesh sizing function debugging"),
+ MessageFlag( 23, "Draw after joining chords in WW"),
+ MessageFlag( 24, "SelfCrossingLoop (and derivatives) debug info"),
+ MessageFlag( 25, "Extra invalidity checking in WW"),
+ MessageFlag( 26, "Surface Smoothing"),
+ MessageFlag( 27, "Primal Construction debugging, see also flag 70"),
+ MessageFlag( 28, "Plastering debugging"),
+ MessageFlag( 29, "Volume SubMapping"),
+ MessageFlag( 30, "Volume Mapping"),
+ MessageFlag( 31, "CleanUp debugging"),
+ MessageFlag( 32, "Pyramid debugging"),
+ MessageFlag( 33, "Whisker Weaving inside chord list face drawing"),
+ MessageFlag( 34, "If on Whisker Weaving doesn't merge sheets"),
+ MessageFlag( 35, "If on WW query displays sheets before joining chords"),
+ MessageFlag( 36, "Enable/Disable idr_keyword_debugger function"),
+ MessageFlag( 37, "Superdrive debugging"),
+ MessageFlag( 38, "WW hex formation messages"),
+ MessageFlag( 39, "Doublet Pillower graphics output"),
+ MessageFlag( 40, "Element Quality debugging output"),
+ MessageFlag( 41, "Check_join adjacency check"),
+ MessageFlag( 42, "Auto vertex type and sweep verification"),
+ MessageFlag( 43, "Programmer Errors for SubMapping"),
+ MessageFlag( 44, "Submapping Graphics Debugging"),
+ MessageFlag( 45, "Pillow Sheet debugging"),
+ MessageFlag( 46, "Paver breakout detection (expensive)"),
+ MessageFlag( 47, "Extra LP debugging (see flag 8 also)"),
+ MessageFlag( 48, "Geometry sizing function."),
+ MessageFlag( 49, "Draws Face by Face Creation in Paving"),
+ MessageFlag( 50, "Debugging for AutoSchemeSelect"),
+ MessageFlag( 51, "Modified Paver: row by row, more intersection checks"),
+ MessageFlag( 52, "User Interface: If flag is enabled, filenames being\n"
+ "\t\t\t\tused for input will be echoed and each input\n"
+ "\t\t\t\tline will be echoed prior to being parsed."),
+ MessageFlag( 53, "Surface Morpher debugging"),
+ MessageFlag( 54, "Parser debugging"),
+ MessageFlag( 55, "Stairtool general debugging"),
+ MessageFlag( 56, "Stairtool face intersection debugging"),
+ MessageFlag( 57, "Relative Interval/Length setting"),
+ MessageFlag( 58, "StcVertex debugging of Whisker Weaving" ),
+ MessageFlag( 59, "VGI developer error"),
+ MessageFlag( 60, "StcVertex debugging of Looping" ),
+ MessageFlag( 61, "List number of points used in curve faceting" ),
+ MessageFlag( 62, "Print verbose information on group operations"),
+ MessageFlag( 63, "Label Whisker Weaving diagrams tersely"),
+ MessageFlag( 64, "No label on Whisker Weaving diagrams"),
+ MessageFlag( 65, "Volume Morpher debugging"),
+ MessageFlag( 66, "Print debug information on importing Pro/E geometry"),
+ MessageFlag( 67, "List number of triangles used in surface faceting" ),
+ MessageFlag( 68, "Debug information on tetrizing volumes" ),
+ MessageFlag( 69, "Debug information on tet mesher geometry access" ),
+ MessageFlag( 70, "STC Pillowing, see also flag 27" ),
+ MessageFlag( 71, "Hex-Tet Debug Flag"),
+ MessageFlag( 72, "DoubletPillower text messages"),
+ MessageFlag( 73, "Auto Surface debugging (use new auto surf select)"),
+ MessageFlag( 74, "Feature-based decomposition info"),
+ MessageFlag( 75, "Many-to-many sweep imprint debugging"),
+ MessageFlag( 76, "Virtual point and partition curve"),
+ MessageFlag( 77, "Volume interval matching"),
+ MessageFlag( 78, "Tipton Smoother jacobian modification enabler"),
+ MessageFlag( 79, "VoidCleanupTool debugging"),
+ MessageFlag( 80, "Hex-Tet informational messages"),
+ MessageFlag( 81, "Curve Morpher Debugging"),
+ MessageFlag( 82, "Diamond debugging"),
+ MessageFlag( 83, "AutoSizer debugging"),
+ MessageFlag( 84, "Surface auto decomposition"),
+ MessageFlag( 85, "U-SubMapping debugging"),
+ MessageFlag( 86, "Virtual curve and partition surface"),
+ MessageFlag( 87, "Composite curve and composite surface"),
+ MessageFlag( 88, "Volume partitioning"),
+ MessageFlag( 89, "Tet meshing warning and debug messages"),
+ MessageFlag( 90, "Geometry attributes"),
+ MessageFlag( 91, "Smoothing Debug Output"),
+ MessageFlag( 92, "Print name changed warnings"),
+ MessageFlag( 93, "Hex Fix Up"),
+ MessageFlag( 94, "Entity name attribute"),
+ MessageFlag( 95, "Group imprint errors"),
+ MessageFlag( 96, "GraftTool debugging"),
+ MessageFlag( 97, "Quality details"),
+ MessageFlag( 98, "Color code imported THEX meshes"),
+ MessageFlag( 99, "Geometry creation"),
MessageFlag(100, "Skew Control debugging"),
MessageFlag(101, "Parsing debugging"),
MessageFlag(102, "CAEntityId debugging"),
@@ -179,7 +181,7 @@
MessageFlag(108, "Simulog tetmesher debugging"),
MessageFlag(109, "Transition schemes debugging"),
MessageFlag(110, "Mesh Defined Geometry"),
- MessageFlag(111, "Tri mesher debugging"),
+ MessageFlag(111, "TriAdvance mesher debugging"),
MessageFlag(112, "Auto Detail Suppression"),
MessageFlag(113, "Extra Multi-sweep/sweep debugging"),
MessageFlag(114, "Blend Finder Debugging"),
@@ -191,8 +193,8 @@
MessageFlag(120, "Print unassociated node locations on import mesh"),
MessageFlag(121, "Print verbose infeasible match interval messages"),
MessageFlag(122, "Mesh-Based Geometry Debug Information"),
- MessageFlag(123, "Collect memory statistics from Tetmesh-GHS3D"),
- MessageFlag(124, "Print verbose debugging information from Tetmesh-GHS3D"),
+ MessageFlag(123, "Collect memory statistics from Tetmesher"),
+ MessageFlag(124, "Print verbose Tetmesher debugging information"),
MessageFlag(125, "Mesh refinement debugging"),
MessageFlag(126, "Surface Splicer debugging"),
MessageFlag(127, "SculptingTool debug flag"),
@@ -225,7 +227,7 @@
MessageFlag(154, "Split Surface Debugging"),
MessageFlag(155, "Meshing Benchmarks Summary"),
MessageFlag(156, "CAMAL Paver CleanUp debuging"),
- MessageFlag(157, "Skeleton Sizing Function Debugging (timing & counts)"),
+ MessageFlag(157, "Skeleton Sizing Function timing and counts"),
MessageFlag(158, "Write a CAMAL debug file"),
MessageFlag(159, "Read a CAMAL debug file"),
MessageFlag(160, "CAMAL debug file format is binary"),
@@ -244,9 +246,44 @@
MessageFlag(173, "Enable Quad-Coarsening Pinch inside corners"),
MessageFlag(174, "Enable Quad-Coarsening Pinch outside corners"),
MessageFlag(175, "Disable creation of crashbackup.cub during crash"),
- MessageFlag(176, "Disable UCP Curve Smoothing"),
- MessageFlag(177, "Enable Unconstrained Plastering Debug Drawing")
-
+ MessageFlag(176, "Enable UCP database checking"),
+ MessageFlag(177, "Enable Unconstrained Plastering Debug Drawing"),
+ MessageFlag(178, "Enable Harris instead of Parrish hex refinement"),
+ MessageFlag(179, "Enable Camal Sweeper for UCP Front Advancements.\n"
+ "\t\t\t\tIgnored if debug 189 is on"),
+ MessageFlag(180, "DecompAide (decomposition helper) debugging"),
+ MessageFlag(181, "MBG. Draw curve paths."),
+ MessageFlag(182, "UCP Detailed Debug Printing." ),
+ MessageFlag(183, "Use legacy tools for multisweep meshing." ),
+ MessageFlag(184, "Enable old sheet refinement command." ),
+ MessageFlag(185, "Enable straddle elements on hardlines." ),
+ MessageFlag(186, "Disable parametric coordinates in TriAdvMesher" ),
+ MessageFlag(187, "Custom Autoscheme" ),
+ MessageFlag(188, "Tolerant Triangle Meshing" ),
+ MessageFlag(189, "Enable Tri-Based Surface offset in UCP.\n"
+ "\t\t\t\tTakes precedence over debug flag 179." ),
+ MessageFlag(190, "Count CAMAL calls to move_to and normal_at" ),
+ MessageFlag(191, "Auto clean messages" ),
+ MessageFlag(192, "MBG - nonmanifold edge check" ),
+ MessageFlag(193, "Tetmesh with stand-alone INRIA execuable thru files" ),
+ MessageFlag(194, "Hex Mesh Matching Debug drawing" ),
+ MessageFlag(195, "CaptureMeshTool print debug information" ),
+ MessageFlag(196, "TriAdvance mesher debug timings" ),
+ MessageFlag(197, "CAMAL Paver debugging (no Cubit smoothing, etc.)" ),
+ MessageFlag(198, "Auto Midsurface debugging" ),
+ MessageFlag(199, "Angle smoothing debugging" ),
+ MessageFlag(200, "Paver quality data output" ),
+ MessageFlag(201, "Paver cleanup edge metrics" ),
+ MessageFlag(202, "Disable Paver cleanup 3-3 replace"),
+ MessageFlag(203, "Disable Paver cleanup 3-offset-3/5 replace"),
+ MessageFlag(204, "Enable Paver cleanup 3-valent quad cluster" ),
+ MessageFlag(205, "Enable Paver cleanup partial chord collapse"),
+ MessageFlag(206, "Hex Mesh Matching, match chords one at a time." ),
+ MessageFlag(207, "Defeature and Geometry tolerant meshing" ),
+ MessageFlag(208, "unassigned" ),
+ MessageFlag(209, "unassigned" ),
+ MessageFlag(210, "unassigned" )
+
// IMPORTANT!!!
// If you add a new debug flag, make sure that you change
// the result of CubitMessage::number_of_debug_flags().
@@ -290,6 +327,15 @@
instance_ = 0;
}
+void CubitMessage::delete_instance()
+{
+ if( NULL != instance )
+ {
+ delete instance_;
+ instance_ = NULL;
+ }
+}
+
int CubitMessage::number_of_debug_flags()
{
return NUM_DEBUG_FLAGS;
@@ -307,10 +353,12 @@
switch (message_type)
{
case CUBIT_ERROR:
-
- print_it = CUBIT_TRUE;
- prefix = "ERROR: ";
- break;
+ if (errorFlag)
+ {
+ print_it = CUBIT_TRUE;
+ prefix = "ERROR: ";
+ }
+ break;
case CUBIT_WARNING:
if (warningFlag)
{
@@ -718,6 +766,11 @@
return cubit_intr;
}
+void CubitMessage::clear_Interrupt()
+{
+ cubit_intr = CUBIT_FALSE;
+}
+
void CubitMessage::set_message_handler(CubitMessageHandler *handler)
{
CubitMessage::mHandler = handler;
@@ -744,7 +797,7 @@
}
-void CubitMessage::set_logging_file_setting(char* filename)
+void CubitMessage::set_logging_file_setting(const char* filename)
{
if (loggingFile && *loggingFile == filename)
return;
@@ -765,11 +818,17 @@
}
}
-void CubitMessage::set_error_logging_file_setting(char* filename)
+void CubitMessage::set_error_logging_file_setting(const char* filename, CubitBoolean resume_flag)
{
if (loggingErrorFile && *loggingErrorFile == filename)
return;
+ if(loggingFile && *loggingFile == filename)
+ {
+ PRINT_ERROR("Can't explicitly set the Error logging file to be the same as the logging file.\n");
+ return;
+ }
+
if (CubitUtil::compare(filename,"terminal")) { // Filename is 'terminal'
if (loggingErrorStream != NULL) {
loggingErrorStream->close();
@@ -782,7 +841,10 @@
}
else {
loggingErrorFile = new CubitString(filename);
- loggingErrorStream = new std::ofstream(filename, std::ios::out | std::ios::app );
+ if(resume_flag)
+ loggingErrorStream = new std::ofstream(filename, std::ios::out | std::ios::app );
+ else
+ loggingErrorStream = new std::ofstream(filename );
}
}
Modified: cgm/branches/cubit/util/CubitMessage.hpp
===================================================================
--- cgm/branches/cubit/util/CubitMessage.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitMessage.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -14,7 +14,7 @@
#include <fstream>
-#include <stdarg.h>
+#include <cstdarg>
#include "CubitDefines.h"
#include "CubitUtilConfigure.h"
@@ -214,7 +214,40 @@
#define PRINT_DEBUG_175 PRINT_DEBUG(175)
#define PRINT_DEBUG_176 PRINT_DEBUG(176)
#define PRINT_DEBUG_177 PRINT_DEBUG(177)
-#define NUM_DEBUG_FLAGS 177
+#define PRINT_DEBUG_178 PRINT_DEBUG(178)
+#define PRINT_DEBUG_179 PRINT_DEBUG(179)
+#define PRINT_DEBUG_180 PRINT_DEBUG(180)
+#define PRINT_DEBUG_181 PRINT_DEBUG(181)
+#define PRINT_DEBUG_182 PRINT_DEBUG(182)
+#define PRINT_DEBUG_183 PRINT_DEBUG(183)
+#define PRINT_DEBUG_184 PRINT_DEBUG(184)
+#define PRINT_DEBUG_185 PRINT_DEBUG(185)
+#define PRINT_DEBUG_186 PRINT_DEBUG(186)
+#define PRINT_DEBUG_187 PRINT_DEBUG(187)
+#define PRINT_DEBUG_188 PRINT_DEBUG(188)
+#define PRINT_DEBUG_189 PRINT_DEBUG(189)
+#define PRINT_DEBUG_190 PRINT_DEBUG(190)
+#define PRINT_DEBUG_191 PRINT_DEBUG(191)
+#define PRINT_DEBUG_192 PRINT_DEBUG(192)
+#define PRINT_DEBUG_193 PRINT_DEBUG(193)
+#define PRINT_DEBUG_194 PRINT_DEBUG(194)
+#define PRINT_DEBUG_195 PRINT_DEBUG(195)
+#define PRINT_DEBUG_196 PRINT_DEBUG(196)
+#define PRINT_DEBUG_197 PRINT_DEBUG(197)
+#define PRINT_DEBUG_198 PRINT_DEBUG(198)
+#define PRINT_DEBUG_199 PRINT_DEBUG(199)
+#define PRINT_DEBUG_200 PRINT_DEBUG(200)
+#define PRINT_DEBUG_201 PRINT_DEBUG(201)
+#define PRINT_DEBUG_202 PRINT_DEBUG(202)
+#define PRINT_DEBUG_203 PRINT_DEBUG(203)
+#define PRINT_DEBUG_204 PRINT_DEBUG(204)
+#define PRINT_DEBUG_205 PRINT_DEBUG(205)
+#define PRINT_DEBUG_206 PRINT_DEBUG(206)
+#define PRINT_DEBUG_207 PRINT_DEBUG(207)
+#define PRINT_DEBUG_208 PRINT_DEBUG(208)
+#define PRINT_DEBUG_209 PRINT_DEBUG(209)
+#define PRINT_DEBUG_210 PRINT_DEBUG(210)
+#define NUM_DEBUG_FLAGS 210
#define PRINT_ERROR CubitMessage::instance()->print_error
#define PRINT_WARNING CubitMessage::instance()->print_warning
@@ -226,6 +259,8 @@
#define SET_INFO_FLAG CubitMessage::instance()->set_info_flag
#define SET_WARNING_FLAG CubitMessage::instance()->set_warning_flag
#define GET_WARNING_FLAG CubitMessage::instance()->get_warning_flag
+#define SET_ERROR_FLAG CubitMessage::instance()->set_error_flag
+#define GET_ERROR_FLAG CubitMessage::instance()->get_error_flag
#define DEBUG_FLAG_SET CubitMessage::instance()->is_debug_flag_set
#define PRINT_DEBUG(x) if(!DEBUG_FLAG_SET(x));else CubitMessage::instance()->print_debug
@@ -284,6 +319,9 @@
static int warningFlag;
//- warning flag, used with internal_error
+ static int errorFlag;
+ //- error flag, used with internal_error
+
static int diagnosticFlag;
//- diagnostic flag, used with internal_error
@@ -335,6 +373,7 @@
virtual ~CubitMessage();
//- Class Destructor.
+ static void delete_instance();
void set_logging_file_setting(const CubitString &filename, CubitBoolean resume_flag = CUBIT_FALSE);
void set_debug_file_setting(const int index, const CubitString &filename);
@@ -356,6 +395,12 @@
int number_of_debug_flags();
//- debug flag, used with internal_error
+ virtual void set_debug_flag_gui(bool flag){};
+ virtual int is_debug_flag_gui_set(){return 0;};
+ virtual int print_debug_gui( const char *format, ... ){return 0;};
+ //- write out a debug message (from GUI only)
+ //- used for GUI Debugging (CAT-only)
+
static bool get_info_flag();
static void set_info_flag(bool flag);
//- info flag, used with internal_error
@@ -364,6 +409,10 @@
static void set_warning_flag(bool flag);
//- warning flag, used with internal_error
+ static bool get_error_flag();
+ static void set_error_flag(bool flag);
+ //- error flag, used with internal_error
+
static bool get_diagnostic_flag();
static void set_diagnostic_flag(bool flag);
//- diagnostic flag, used with internal_error
@@ -416,8 +465,8 @@
void output_logging_information();
static char* get_logging_file_setting();
- static void set_logging_file_setting(char* file);
- static void set_error_logging_file_setting(char* file);
+ static void set_logging_file_setting(const char* file);
+ static void set_error_logging_file_setting(const char* file, CubitBoolean resume_flag = CUBIT_FALSE);
static void initialize_settings();
@@ -425,6 +474,10 @@
//- passes back value of interrupt flag (see CubitDefines.h for how
//- this flag is stored)
+ virtual void clear_Interrupt();
+ //- clears the value of interrupt flag (see CubitDefines.h for how
+ //- this flag is stored)
+
static void set_message_handler(CubitMessageHandler *handler);
static CubitMessageHandler* get_message_handler();
@@ -455,6 +508,14 @@
{warningFlag = flag;}
inline bool
+CubitMessage::get_error_flag()
+{return !!errorFlag;}
+
+inline void
+CubitMessage::set_error_flag(bool flag)
+{errorFlag = flag;}
+
+inline bool
CubitMessage::get_diagnostic_flag()
{return !!diagnosticFlag;}
Modified: cgm/branches/cubit/util/CubitPlane.cpp
===================================================================
--- cgm/branches/cubit/util/CubitPlane.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitPlane.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -4,8 +4,8 @@
//- Checked by:
-#include <stdio.h>
-#include <stdlib.h>
+#include <cstdio>
+#include <cstdlib>
#include <math.h>
#include "CubitPlane.hpp"
#include "CubitVector.hpp"
@@ -128,11 +128,11 @@
CubitVector CubitPlane::point_on_plane() const
{
- if (normal_.x() != 0)
+ if ( fabs( normal_.x() ) > CUBIT_RESABS )
return CubitVector(-d_ / normal_.x(), 0, 0);
- else if (normal_.y() != 0)
+ else if ( fabs( normal_.y() ) > CUBIT_RESABS )
return CubitVector(0, -d_ / normal_.y(), 0);
- else if (normal_.z() != 0)
+ else if ( fabs( normal_.z() ) > CUBIT_RESABS )
return CubitVector(0, 0, -d_ / normal_.z());
// If A B and C are all zero, the plane is invalid,
// Just return <0,0,0>
@@ -200,7 +200,7 @@
else if (dir2.y() > dir2.x() && dir2.y() > CUBIT_RESABS)
{
// then get a point on the XZ plane
- invdet = 1.0 / vector.y();
+ invdet = -1.0 / vector.y();
// solve < pl1.x * origin.x + pl1.z * origin.z = -pl1.w >
// < plane2n.x * origin.x + plane2n.z * origin.z = -plane2n.w >
Modified: cgm/branches/cubit/util/CubitPlane.hpp
===================================================================
--- cgm/branches/cubit/util/CubitPlane.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitPlane.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -99,6 +99,10 @@
CubitVector project( const CubitVector& point ) const;
//- Project a point onto plane
+ void reverse()
+ { normal_ = -normal_; d_ = -d_; }
+ //- flip the normal of the plane
+
CubitPlane& operator=(const CubitPlane &plane);
//- assignment
Modified: cgm/branches/cubit/util/CubitStack.cpp
===================================================================
--- cgm/branches/cubit/util/CubitStack.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitStack.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -5,7 +5,7 @@
//- Checked by:
//- Version: $Id:
-#include <string.h>
+#include <cstring>
#include "CubitStack.hpp"
Modified: cgm/branches/cubit/util/CubitString.cpp
===================================================================
--- cgm/branches/cubit/util/CubitString.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitString.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -9,10 +9,10 @@
#include <iomanip>
-#include <stddef.h>
-#include <stdio.h>
-#include <assert.h>
-#include <string.h>
+#include <cstddef>
+#include <cstdio>
+#include <cassert>
+#include <cstring>
class CubitStringRep
{
@@ -114,7 +114,7 @@
// Create the empty string rep
if (!sEmptyStringRep)
{
- static char dummy = CubitStringRep::initialize_empty_string_rep();
+ CubitStringRep::initialize_empty_string_rep();
}
rep = sEmptyStringRep;
rep->increment();
@@ -136,7 +136,7 @@
{
// Use a static variable in order to call a function
// once and only once.
- static char dummy = CubitStringRep::initialize_empty_string_rep();
+ CubitStringRep::initialize_empty_string_rep();
// If it's an empty string...
if (!s || s[0] == '\0')
@@ -387,10 +387,14 @@
else
{
// Append character the lazy way
- char buf[2];
- buf[0] = c;
- buf[1] = '\0';
- operator+=(buf);
+ size_t new_count = length() + 1;
+ char *buf = new char[new_count + 1];
+ memcpy(buf, rep->chars, length());
+ buf[new_count -1] = c;
+ buf[new_count] = '\0';
+ rep->decrement();
+ rep = new CubitStringRep(buf, 1);
+ rep->increment();
}
}
}
@@ -441,6 +445,17 @@
to_upper(p);
}
+void CubitString::tokenize( char *delimiter, std::vector<CubitString> &strings )
+{
+ char* tmp_word;
+ tmp_word = strtok( rep->chars, delimiter );
+ if( tmp_word != NULL )
+ strings.push_back( CubitString( tmp_word ) );
+
+ while( tmp_word=strtok( NULL, delimiter ) )
+ strings.push_back( CubitString( tmp_word ) );
+}
+
bool CubitString::operator==(const CubitString& s2) const
{
return (rep == s2.rep) || (strcmp(rep->chars, s2.rep->chars) == 0);
Modified: cgm/branches/cubit/util/CubitString.hpp
===================================================================
--- cgm/branches/cubit/util/CubitString.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitString.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -15,12 +15,13 @@
#if !defined(STRING_HPP)
#define STRING_HPP
-#include <assert.h>
-#include <stdlib.h>
+#include <cassert>
+#include <cstdlib>
#include <ctype.h>
#include "CubitDefines.h"
#include <iostream>
+#include <vector>
#include "CubitUtilConfigure.h"
@@ -91,8 +92,10 @@
static void to_lower(char *string);
void to_upper();
static void to_upper(char *string);
- static void trim(char* &string);
//- Subscripting
+
+ void tokenize( char *delimiter, std::vector<CubitString> &strings );
+
size_t find(const CubitString& s, size_t pos = 0) const;
size_t find_first_of(const CubitString& s, size_t pos = 0) const;
@@ -136,16 +139,6 @@
}
}
-inline void CubitString::trim(char* &string)
-{
- while(isspace(*string))
- string++;
- char *p = (string + strlen(string)) - 1;
- while(isspace(*p))
- p--;
- p++;
- *p = '\0';
-}
#endif
Modified: cgm/branches/cubit/util/CubitTransformMatrix.cpp
===================================================================
--- cgm/branches/cubit/util/CubitTransformMatrix.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitTransformMatrix.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -396,3 +396,78 @@
return mat;
}
+void CubitTransformMatrix::get_rotation_axis_and_angle(CubitVector &rotation_axis, double &angle)
+{
+ double cos_theta = (this->get(0,0) + this->get(1,1) + this->get(2,2) - 1) / 2;
+
+ double x = 0;
+ double y = 0;
+ double z = 0;
+
+ if (fabs(cos_theta - 1) < .0001)
+ {
+ // theta is 1 or almost 1
+ angle = 0;
+ x = 0;
+ y = 0;
+ z = 1;
+ }
+ else if (fabs(cos_theta + 1) > .0001)
+ {
+ // theta is NOT -1 or almost -1
+ angle = acos(cos_theta);
+ angle = (angle * 180.0) / CUBIT_PI; // convert to degrees
+ double sin_theta = sqrt(1 - cos_theta * cos_theta);
+ x = ( (this->get(2,1) - this->get(1,2)) / 2 ) / sin_theta;
+ y = ( (this->get(0,2) - this->get(2,0)) / 2 ) / sin_theta;
+ z = ( (this->get(1,0) - this->get(0,1)) / 2 ) / sin_theta;
+ }
+ else
+ {
+ angle = 180;
+ if (this->get(0,0) >= this->get(1,1))
+ {
+
+ if (this->get(0,0) >= this->get(2,2))
+ {
+ // 0,0 is maximal diagonal term
+ x = sqrt(this->get(0,0) - this->get(1,1) - this->get(2,2) + 1) / 2;
+ double half_inverse = 1 / (2 * x);
+ y = half_inverse * this->get(0,1);
+ z = half_inverse * this->get(0,2);
+ }
+ else
+ {
+ // 2,2 is maximal diagonal term
+ z = sqrt(this->get(2,2) - this->get(0,0) - this->get(1,1) + 1) / 2;
+ double half_inverse = 1 / (2 * z);
+ x = half_inverse * this->get(0,2);
+ y = half_inverse * this->get(1,2);
+ }
+ }
+ else
+ {
+ if (this->get(1,1) >= this->get(2,2))
+ {
+ // 1,1 is maximal diagonal term
+ y = sqrt(this->get(1,1) - this->get(0,0) - this->get(2,2) + 1) / 2;
+ double half_inverse = 1 / (2 * y);
+ x = half_inverse * this->get(0,1);
+ z = half_inverse * this->get(1,2);
+ }
+ else
+ {
+ // 2,2 is maximal diagonal term
+ z = sqrt(this->get(2,2) - this->get(0,0) - this->get(1,1) + 1) / 2;
+ double half_inverse = 1 / (2 * z);
+ x = half_inverse * this->get(0,2);
+ y = half_inverse * this->get(1,2);
+ }
+ }
+
+ }
+
+ rotation_axis.x(x);
+ rotation_axis.y(y);
+ rotation_axis.z(z);
+}
Modified: cgm/branches/cubit/util/CubitTransformMatrix.hpp
===================================================================
--- cgm/branches/cubit/util/CubitTransformMatrix.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitTransformMatrix.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -31,6 +31,8 @@
CubitTransformMatrix& rotate(double degrees, char axis);
CubitTransformMatrix& rotate(double degrees, const CubitVector& axis_from,
const CubitVector& axis_to);
+
+ void get_rotation_axis_and_angle(CubitVector &rotation_axis, double &angle);
CubitTransformMatrix& reflect(const CubitVector& vector);
Added: cgm/branches/cubit/util/CubitUndo.cpp
===================================================================
--- cgm/branches/cubit/util/CubitUndo.cpp (rev 0)
+++ cgm/branches/cubit/util/CubitUndo.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,243 @@
+//- Class: UndoCommands
+//- Description: Provides main undo capability for Cubit system
+//- Owner: Ray J. Meyers
+//- Checked by:
+//- Version: $Id:
+
+#include "CubitUndo.hpp"
+#include "CubitString.hpp"
+
+CubitUndo* CubitUndo::mInstance = 0;
+
+CubitUndo::CubitUndo()
+{
+ if(mInstance)
+ {
+ assert(0);
+ // if you want a new instance in place of a previous one,
+ // delete the previous one first
+ }
+ mInstance = this;
+}
+
+CubitUndo::~CubitUndo()
+{
+ mInstance = 0;
+}
+
+void CubitUndo::start_undo_group()
+{
+ if(!mInstance ) return;
+ mInstance->p_start_undo_group();
+}
+
+void CubitUndo::end_undo_group()
+{
+ if(!mInstance ) return;
+ mInstance->p_end_undo_group();
+}
+
+void CubitUndo::set_undo_enabled(bool value)
+{
+ if(!mInstance ) return;
+ mInstance->p_set_undo_enabled( value );
+}
+
+bool CubitUndo::get_undo_enabled()
+{
+ if(!mInstance ) return false;
+ return mInstance->p_get_undo_enabled();
+}
+
+void CubitUndo::clear_undo_groups()
+{
+ if(!mInstance ) return;
+ mInstance->p_clear_undo_groups();
+}
+
+int CubitUndo::execute_undo()
+{
+ if(!mInstance )
+ return 0;
+
+ return mInstance->p_execute_undo();
+}
+
+void CubitUndo::remove_last_undo()
+{
+ if(!mInstance ) return;
+ mInstance->p_remove_last_undo();
+}
+
+
+void CubitUndo::remove_last_undo_group()
+{
+ if(!mInstance ) return;
+ mInstance->p_remove_last_undo_group();
+}
+
+void CubitUndo::save_state()
+{
+ if(!mInstance ) return;
+ mInstance->p_save_state();
+}
+
+void CubitUndo::save_state_with_cubit_file(DLIList<RefVolume*> &volumes_to_save )
+{
+ if(!mInstance ) return;
+ mInstance->p_save_state_with_cubit_file( volumes_to_save );
+}
+
+void CubitUndo::save_state_with_cubit_file(RefFace *face_to_save )
+{
+ if(!mInstance ) return;
+ mInstance->p_save_state_with_cubit_file( face_to_save );
+}
+
+void CubitUndo::save_state_with_cubit_file(RefVolume *volume_to_save )
+{
+ if(!mInstance ) return;
+ mInstance->p_save_state_with_cubit_file( volume_to_save );
+}
+
+void CubitUndo::save_state_with_cubit_file( DLIList<MRefVolume*> &volumes_to_save )
+{
+ if(!mInstance ) return;
+ mInstance->p_save_state_with_cubit_file( volumes_to_save );
+}
+void CubitUndo::save_state_with_cubit_file(DLIList<RefFace*> &faces_to_save )
+{
+ if(!mInstance ) return;
+ mInstance->p_save_state_with_cubit_file( faces_to_save );
+}
+
+void CubitUndo::save_state_with_cubit_file(DLIList<RefEdge*> &edges_to_save )
+{
+ if(!mInstance ) return;
+ mInstance->p_save_state_with_cubit_file( edges_to_save );
+}
+
+void CubitUndo::save_state_with_cubit_file(DLIList<RefVertex*> &verts_to_save,
+ bool save_only_if_free )
+{
+ if(!mInstance ) return;
+ mInstance->p_save_state_with_cubit_file( verts_to_save, save_only_if_free );
+}
+
+void CubitUndo::save_state_with_cubit_file( DLIList<Body*> &bodies_to_save,
+ DLIList<RefEntity*> *free_ents_to_save )
+{
+ if(!mInstance ) return;
+ mInstance->p_save_state_with_cubit_file( bodies_to_save, free_ents_to_save );
+}
+
+void CubitUndo::note_result_body( Body *body_to_delete )
+{
+ if(!mInstance ) return;
+ mInstance->p_note_result_body( body_to_delete );
+}
+
+void CubitUndo::note_result_bodies( DLIList<Body*> &bodies_to_delete )
+{
+ if(!mInstance ) return;
+ mInstance->p_note_result_bodies( bodies_to_delete );
+}
+
+void CubitUndo::note_result_entity( RefEntity *entity_to_delete )
+{
+ if(!mInstance ) return;
+ mInstance->p_note_result_entity( entity_to_delete );
+}
+
+void CubitUndo::note_result_entities( DLIList<MRefVolume*> &vols_to_delete )
+{
+ if(!mInstance ) return;
+ mInstance->p_note_result_entities( vols_to_delete );
+}
+
+void CubitUndo::note_result_entities( DLIList<RefEntity*> &entities_to_delete )
+{
+ if(!mInstance ) return;
+ mInstance->p_note_result_entities( entities_to_delete );
+}
+
+void CubitUndo::set_undo_by_restoring_state()
+{
+ if(!mInstance ) return;
+ mInstance->p_set_undo_by_restoring_state();
+}
+
+void CubitUndo::set_undo_by_command(CubitString undo_command_string)
+{
+ if(!mInstance ) return;
+ mInstance->p_set_undo_by_command( undo_command_string );
+}
+
+int CubitUndo::number_undo_groups()
+{
+ if(!mInstance ) return 0;
+ return mInstance->p_number_undo_groups();
+}
+
+void CubitUndo::create_dummy_undo_object()
+{
+ if(!mInstance ) return;
+ mInstance->p_create_dummy_undo_object();
+}
+
+bool CubitUndo::inside_undo_group()
+{
+ if(!mInstance ) return false;
+ return mInstance->p_inside_undo_group();
+}
+
+void CubitUndo::save_mesh_size_data( MRefEntity *entity )
+{
+ if(!mInstance ) return;
+ mInstance->p_save_mesh_size_data( entity );
+}
+
+void CubitUndo::save_mesh_scheme_data( MRefEntity *entity )
+{
+ if(!mInstance ) return;
+ mInstance->p_save_mesh_scheme_data( entity );
+}
+
+void CubitUndo::save_smooth_scheme_data( MRefEntity *entity )
+{
+ if(!mInstance ) return;
+ mInstance->p_save_smooth_scheme_data( entity );
+}
+
+void CubitUndo::save_all_mesh_data( MRefEntity *entity )
+{
+ if(!mInstance ) return;
+ mInstance->p_save_all_mesh_data( entity );
+}
+
+void CubitUndo::save_merge_data( DLIList<RefEntity*> &ents, bool merging )
+{
+ if(!mInstance ) return;
+ mInstance->p_save_merge_data( ents, merging );
+}
+
+void CubitUndo::save_mesh_state_before_smoothing( MRefEntity *entity )
+{
+ if(!mInstance ) return;
+ DLIList<MRefEntity*> ents_to_smooth(1);
+ ents_to_smooth.append( entity );
+ mInstance->p_save_mesh_state_before_smoothing( ents_to_smooth );
+}
+
+void CubitUndo::save_mesh_state_before_smoothing( DLIList<MRefEntity*> &ents_to_smooth )
+{
+ if(!mInstance ) return;
+ mInstance->p_save_mesh_state_before_smoothing( ents_to_smooth );
+}
+
+void CubitUndo::save_mesh_state_before_smoothing( DLIList<MeshEntity*> &ents_to_smooth )
+{
+ if(!mInstance ) return;
+ mInstance->p_save_mesh_state_before_smoothing( ents_to_smooth );
+}
+
Added: cgm/branches/cubit/util/CubitUndo.hpp
===================================================================
--- cgm/branches/cubit/util/CubitUndo.hpp (rev 0)
+++ cgm/branches/cubit/util/CubitUndo.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,137 @@
+//- Class: UndoCommands
+//- Description: Provides undo capability for Cubit system
+//- Owner: Ray J. Meyers
+//- Checked by:
+//- Version: $Id:
+
+
+#ifndef CUBITUNDO_HPP
+#define CUBITUNDO_HPP
+
+#include <stack>
+#include "DLIList.hpp"
+
+class UndoCommand;
+class CubitString;
+class RefEntity;
+class Body;
+class RefVolume;
+class RefFace;
+class RefEdge;
+class RefVertex;
+class MRefEntity;
+class MRefVolume;
+class MeshEntity;
+
+class CUBIT_UTIL_EXPORT CubitUndo
+{
+ // the one instance of the Cubit Undo object
+ // creating a second instance will delete and replace the first instance.
+ static CubitUndo* mInstance;
+
+public:
+
+ CubitUndo();
+ virtual ~CubitUndo();
+
+ static void start_undo_group();
+ static void end_undo_group();
+ static void set_undo_enabled(bool value);
+ static bool get_undo_enabled();
+ static void clear_undo_groups();
+ static int execute_undo();
+ static void set_undo_by_restoring_state();
+ static void set_undo_by_command(CubitString command);
+
+ static void save_state_with_cubit_file( DLIList<Body*> &bodies_to_save,
+ DLIList<RefEntity*> *free_ents_to_save = NULL );
+ static void save_state_with_cubit_file( DLIList<RefVolume*> &volumes_to_save );
+ static void save_state_with_cubit_file( DLIList<RefFace*> &faces_to_save );
+ static void save_state_with_cubit_file( RefFace* face_to_save );
+ static void save_state_with_cubit_file( RefVolume* volume_to_save );
+ static void save_state_with_cubit_file( DLIList<MRefVolume*> &volumes_to_save );
+ static void save_state_with_cubit_file( DLIList<RefEdge*> &edges_to_save );
+ static void save_state_with_cubit_file( DLIList<RefVertex*> &vertices_to_save,
+ bool save_if_free = false );
+
+ static void save_state();
+ static int number_undo_groups();
+ static void note_result_bodies( DLIList<Body*> &bodies_to_delete );
+ static void note_result_body( Body* body_to_delete );
+ static void note_result_entities( DLIList<RefEntity*> &entities_to_delete );
+ static void note_result_entities( DLIList<MRefVolume*> &vols_to_delete );
+ static void note_result_entity( RefEntity *entity_to_delete );
+ static void remove_last_undo();
+ static void remove_last_undo_group();
+ static void create_dummy_undo_object();
+ static bool inside_undo_group();
+
+ //meshing data
+ static void save_mesh_size_data( MRefEntity *entity );
+ static void save_mesh_scheme_data( MRefEntity *entity );
+ static void save_smooth_scheme_data( MRefEntity *entity );
+ static void save_all_mesh_data( MRefEntity *entity );
+
+ //merging
+ static void save_merge_data( DLIList<RefEntity*> &ents, bool merging = true );
+
+ //smoothing
+ static void save_mesh_state_before_smoothing( MRefEntity *entity );
+ static void save_mesh_state_before_smoothing( DLIList<MRefEntity*> &ents );
+ static void save_mesh_state_before_smoothing( DLIList<MeshEntity*> &ents );
+
+protected:
+
+ virtual void p_start_undo_group() = 0;
+ virtual void p_end_undo_group() = 0;
+
+ virtual void p_set_undo_enabled(bool value)=0;
+ virtual bool p_get_undo_enabled()=0;
+ virtual void p_clear_undo_groups()=0;
+ virtual int p_execute_undo()=0;
+ virtual void p_set_undo_by_restoring_state()=0;
+ virtual void p_set_undo_by_command(CubitString command)=0;
+
+ virtual void p_save_state_with_cubit_file( DLIList<Body*> &bodies_to_save,
+ DLIList<RefEntity*> *free_ref_ents = NULL )=0;
+ virtual void p_save_state_with_cubit_file( DLIList<RefVolume*> &volumes_to_save )=0;
+ virtual void p_save_state_with_cubit_file( DLIList<RefFace*> &faces_to_save )=0;
+ virtual void p_save_state_with_cubit_file( RefFace *face_to_save )=0;
+ virtual void p_save_state_with_cubit_file( RefVolume* volume_to_save )=0;
+ virtual void p_save_state_with_cubit_file( DLIList<MRefVolume*> &volumes_to_save )=0;
+ virtual void p_save_state_with_cubit_file( DLIList<RefEdge*> &edges_to_save )=0;
+ virtual void p_save_state_with_cubit_file( DLIList<RefVertex*> &vertices_to_save,
+ bool save_only_if_free = false )=0;
+
+ virtual void p_save_state()=0;
+ virtual int p_number_undo_groups()=0;
+ virtual void p_note_result_bodies( DLIList<Body*> &bodies_to_delete )=0;
+ virtual void p_note_result_body( Body* body_to_delete )=0;
+ virtual void p_note_result_entities( DLIList<RefEntity*> &entities_to_delete )=0;
+ virtual void p_note_result_entities( DLIList<MRefVolume*> &vols_to_delete )=0;
+ virtual void p_note_result_entity( RefEntity *entity_to_delete )=0;
+ virtual void p_remove_last_undo_group()=0;
+ virtual void p_remove_last_undo()=0;
+ virtual void p_create_dummy_undo_object()=0;
+ virtual bool p_inside_undo_group()=0;
+
+ //meshing data
+ virtual void p_save_mesh_size_data( MRefEntity *entity )=0;
+ virtual void p_save_mesh_scheme_data( MRefEntity *entity )=0;
+ virtual void p_save_smooth_scheme_data( MRefEntity *entity )=0;
+ virtual void p_save_all_mesh_data( MRefEntity *entity )=0;
+
+ //merging
+ virtual void p_save_merge_data( DLIList<RefEntity*> &ents, bool merging = true)=0;
+
+ //smoothing
+ virtual void p_save_mesh_state_before_smoothing( DLIList<MRefEntity*> &ents_to_smooth )=0;
+ virtual void p_save_mesh_state_before_smoothing( DLIList<MeshEntity*> &ents_to_smooth )=0;
+
+};
+
+#endif
+
+
+
+
Modified: cgm/branches/cubit/util/CubitUtil.cpp
===================================================================
--- cgm/branches/cubit/util/CubitUtil.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitUtil.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -21,7 +21,10 @@
#include "AppUtil.hpp"
#include <ctype.h>
#include <time.h>
+#include <fstream>
+using std::ifstream;
+
#ifdef NT
#include "Windows.h"
#else
@@ -468,19 +471,31 @@
// If the path is not writeable, use the current directory instead
DWORD atts = GetFileAttributes(temp_path);
+#if _MSC_VER > 1200 // after VC6.0
if (atts == INVALID_FILE_ATTRIBUTES || // File doesn't exist
(atts & FILE_ATTRIBUTE_DIRECTORY) == 0 || // File isn't a directory
atts & FILE_ATTRIBUTE_READONLY) // File is read only
+#else
+ if ((atts & FILE_ATTRIBUTE_DIRECTORY) == 0 || // File isn't a directory
+ atts & FILE_ATTRIBUTE_READONLY) // File is read only
+#endif
{
if (DEBUG_FLAG(141))
{
PRINT_DEBUG_141("\nUsing cwd because ");
+#if _MSC_VER > 1200
if (atts == INVALID_FILE_ATTRIBUTES)
PRINT_DEBUG_141("directory doesn't exist: %s\n", temp_path);
else if ((atts & FILE_ATTRIBUTE_DIRECTORY) == 0)
PRINT_DEBUG_141("file isn't a directory: %s\n", temp_path);
else if (atts & FILE_ATTRIBUTE_READONLY)
PRINT_DEBUG_141("directory is read only: %s\n", temp_path);
+#else
+ if ((atts & FILE_ATTRIBUTE_DIRECTORY) == 0)
+ PRINT_DEBUG_141("file isn't a directory: %s\n", temp_path);
+ else if (atts & FILE_ATTRIBUTE_READONLY)
+ PRINT_DEBUG_141("directory is read only: %s\n", temp_path);
+#endif
}
temp_path[0] = '.';
temp_path[1] = '\0';
@@ -525,7 +540,8 @@
CubitString tmpdir = get_temp_directory();
const char* filepattern = "CBT.XXXXXX";
- char *temp_file_name = new char[tmpdir.length() + strlen(filepattern) + 1];
+ //needs to be two longer because of the "/"?
+ char *temp_file_name = new char[tmpdir.length() + strlen(filepattern) + 2];
sprintf(temp_file_name, "%s/%s", tmpdir.c_str(), filepattern);
// make an empty file and return the name for it
@@ -659,3 +675,139 @@
sleep(duration_in_seconds);
#endif
}
+
+int CubitUtil::find_available_file_name(char* buffer)
+{
+ int num_files;
+
+ // If a bell character was encountered in the string, we need to
+ // expand it to the next available number.
+
+ char* ten_ptr = 0; //Pointer to the tens-digit in the string
+ char* one_ptr = 0; //Pointer to the ones-digit in the string
+ CubitBoolean file_already_exists = CUBIT_FALSE;
+
+ char* ptr;
+
+ // Find the tens- and ones-digit in the string.
+ // We marked them with bell characters before, so
+ // that strftime() would ignore them.
+ for( ptr = buffer; *ptr; ptr++ )
+ {
+ if( (*ptr == '\007') && (*(ptr+1) == '\007') )
+ {
+ ten_ptr = ptr;
+ one_ptr = ptr + 1;
+ *ten_ptr = '0';
+ *one_ptr = '0';
+ break;
+ }
+ }
+ assert(ten_ptr != 0);
+
+ //Search for next available number with two digits.
+
+ for(int i=0; i<10; ++i)
+ {
+ *ten_ptr = (char)(i + '0');
+ for(int j=0; j<10; ++j)
+ {
+ file_already_exists = CUBIT_FALSE;
+
+ if (i==0 && j==0)
+ continue; // Don't want cubit00.jou
+
+ *one_ptr = (char)(j + '0');
+ ifstream test_stream(buffer);
+
+ if(!test_stream)
+ {
+ // File does not exist, use it
+ num_files = i*10 + j;
+ // Break out of both loops.
+ i = 10;
+ j = 10;
+
+ file_already_exists = CUBIT_FALSE;
+ }
+ else
+ file_already_exists = CUBIT_TRUE;
+
+ test_stream.close(); // File exists, close it and try next.
+ }
+ }
+
+ //Search for next available file with three digits
+ if(file_already_exists)
+ {
+
+ // Find the tens- and ones-digit in the string.
+ //We should only be in here if they are both 9
+ char* ptr;
+ char* hun_ptr = 0; //Pointer to the hundreds-digit in the string
+ char* temp_ptr = 0;
+
+ for( ptr = buffer; *ptr; ptr++ )
+ {
+ if( (*ptr == '9') && (*(ptr+1) == '9') )
+ {
+ hun_ptr = ptr;
+ ten_ptr = ptr + 1;
+ one_ptr = ptr + 2;
+ temp_ptr = one_ptr;
+
+ do
+ {
+ temp_ptr++;
+ }
+ while(*temp_ptr !='\0');
+
+ one_ptr = temp_ptr;
+ temp_ptr ++;
+
+ do{
+ *temp_ptr = *one_ptr;
+ one_ptr--;
+ temp_ptr--;
+ }
+ while(one_ptr != ten_ptr);
+ one_ptr++;
+
+ *hun_ptr = '1';
+ *ten_ptr = '0';
+ *one_ptr = '0';
+ break;
+ }
+ }
+ assert(ten_ptr != 0);
+
+ //Search for next available number.
+
+ for(int k = 1; k<10 ; ++k)
+ {
+ *hun_ptr = (char)(k+'0');
+
+ for(int i=0; i<10 ; ++i)
+ {
+ *ten_ptr = (char)(i + '0');
+ for(int j=0; j<10 ; ++j)
+ {
+ *one_ptr = (char)(j + '0');
+ ifstream test_stream(buffer);
+ num_files = k*100 + i * 10 + j;
+ if(!test_stream)
+ {
+ // File does not exist, use it
+ //Break out of loop
+ k = 10;
+ i = 10;
+ j = 10;
+
+ }
+ test_stream.close(); // File exists, close it and try next.
+ }
+ }
+ }
+ }
+ return num_files;
+}
Modified: cgm/branches/cubit/util/CubitUtil.hpp
===================================================================
--- cgm/branches/cubit/util/CubitUtil.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitUtil.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -19,7 +19,7 @@
#ifndef CUBIT_UTIL_HPP
#define CUBIT_UTIL_HPP
-#include <string.h>
+#include <cstring>
#include "DLIList.hpp"
#include "CubitDefines.h"
#include "CubitUtilConfigure.h"
@@ -107,7 +107,11 @@
static void util_strdup_free(char* s1){free(s1);}
static void cubit_sleep(int duration_in_seconds);
-
+ //Send in a string (in buffer) with two \007 characters next to each other
+ //This function will search from 00 up to 999 to find the next available
+ //filename
+ static int find_available_file_name(char* buffer);
+
private:
CubitUtil(){}
Modified: cgm/branches/cubit/util/CubitUtilConfigure.h.in
===================================================================
--- cgm/branches/cubit/util/CubitUtilConfigure.h.in 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitUtilConfigure.h.in 2010-01-06 19:22:14 UTC (rev 3423)
@@ -4,15 +4,23 @@
#cmakedefine CUBIT_UTIL_BUILD_SHARED_LIBS
-#if defined(WIN32) && defined(CUBIT_UTIL_BUILD_SHARED_LIBS)
+#if defined(CUBIT_UTIL_BUILD_SHARED_LIBS)
#if defined(cubit_util_EXPORTS)
-#define CUBIT_UTIL_EXPORT __declspec(dllexport)
+# if defined(WIN32)
+# define CUBIT_UTIL_EXPORT __declspec(dllexport)
+# elif defined(__GNUC__) && __GNUC__ >= 4
+# define CUBIT_UTIL_EXPORT __attribute__ ((visibility("default")))
+# endif
#else
-#define CUBIT_UTIL_EXPORT __declspec(dllimport)
+# if defined(WIN32)
+# define CUBIT_UTIL_EXPORT __declspec(dllimport)
+# endif
#endif
-#else
-#define CUBIT_UTIL_EXPORT
#endif
+#ifndef CUBIT_UTIL_EXPORT
+#define CUBIT_UTIL_EXPORT
#endif
+#endif // CUBIT_UTIL_EXPORTS_H
+
Modified: cgm/branches/cubit/util/CubitVector.cpp
===================================================================
--- cgm/branches/cubit/util/CubitVector.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitVector.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -44,6 +44,24 @@
return(sqrt(x*x + y*y + z*z));
}
+double CubitVector::distance_from_infinite_line(const CubitVector& point_on_line,
+ const CubitVector& line_direction) const
+{
+ return sqrt(distance_from_infinite_line_squared(point_on_line, line_direction));
+}
+
+double CubitVector::distance_from_infinite_line_squared(
+ const CubitVector& point_on_line,
+ const CubitVector& line_direction) const
+{
+ if (line_direction == CubitVector(0, 0, 0))
+ return distance_between_squared(point_on_line);
+
+ CubitVector v = *this - point_on_line;
+ double v_dot_d = v % line_direction;
+ return fabs(v.length_squared() - v_dot_d * v_dot_d / line_direction.length_squared());
+}
+
// double CubitVector::distance_between(const CubitVector& test_vector, RefEdge* test_edge)
// {
// return( test_edge->get_arc_length(*this, test_vector) );
@@ -204,7 +222,10 @@
double y = vec2 % ry;
double angle;
- assert(x != 0.0 || y != 0.0);
+ if( x == 0.0 && y == 0.0 )
+ {
+ return 0.0;
+ }
angle = atan2(y, x);
@@ -244,6 +265,11 @@
return CubitVector(xAxis + yAxis);
}
+#ifdef __APPLE__
+// optimization issues on mac osx.
+#pragma optimization_level 0
+#endif
+
double CubitVector::vector_angle(const CubitVector &vector1,
const CubitVector &vector2) const
{
@@ -333,6 +359,10 @@
return angle;
}
+#ifdef __APPLE__
+#pragma optimization_level reset
+#endif
+
CubitBoolean CubitVector::within_tolerance( const CubitVector &vectorPtr2,
double tolerance) const
{
@@ -475,3 +505,14 @@
return;
}
+//- Project this vector onto the plane specified by the input plane normal
+void CubitVector::project_to_plane( const CubitVector &planenormal )
+{
+ // Cross the vector with the normal to get a vector on the plane
+ CubitVector planevec = planenormal * (*this);
+
+ // Cross the vector on the plane with the normal to get the
+ // projection of the vector on the plane
+ *this = planevec * planenormal;
+}
+
Modified: cgm/branches/cubit/util/CubitVector.hpp
===================================================================
--- cgm/branches/cubit/util/CubitVector.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/CubitVector.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -102,6 +102,9 @@
void rotate(double angle, double );
//- transform function.
//- transform (x,y) to (r,theta) to (r,theta+angle) to (x',y')
+
+ void project_to_plane( const CubitVector &planenormal );
+ //- project this vector onto a plane.
void reflect_about_xaxis(double dummy, double );
//- dummy argument to make it a transform function
@@ -125,7 +128,17 @@
double distance_between_squared(const CubitVector& test_vector) const;
//- Calculate the distance squared from the head of one vector
// to the head of the test_vector.
+
+ double distance_from_infinite_line(const CubitVector& point_on_line,
+ const CubitVector& line_direction) const;
+ //- Calculate the minimum distance between the head of this vector and a
+ // line of infinite length.
+ double distance_from_infinite_line_squared(const CubitVector& point_on_line,
+ const CubitVector& line_direction) const;
+ //- Calculate the square of the minimum distance between the head of this
+ // vector and a line of infinite length.
+
double length_squared() const;
//- Calculate the squared length of the vector.
//- Faster than {length()} since it eliminates the square root if
@@ -211,6 +224,9 @@
CubitVector operator-() const;
//- unary negation.
+
+ double operator[](int i) const;
+ //- return the ith value of the vector (x, y, z)
friend CubitVector operator~(const CubitVector &vec);
//- normalize. Returns a new vector which is a copy of {vec},
@@ -472,6 +488,14 @@
return CubitVector(-xVal, -yVal, -zVal);
}
+inline double CubitVector::operator[](int i) const
+{
+ assert(i > -1 && i < 3);
+ if (i == 0) return xVal;
+ else if (i == 1) return yVal;
+ else return zVal;
+}
+
inline CubitVector operator+(const CubitVector &vector1,
const CubitVector &vector2)
{
Modified: cgm/branches/cubit/util/DIntArray.cpp
===================================================================
--- cgm/branches/cubit/util/DIntArray.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/DIntArray.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -4,7 +4,7 @@
//- Checked by:
#include "DIntArray.hpp"
-#include <assert.h>
+#include <cassert>
void DIntArray::append(int item)
{
Modified: cgm/branches/cubit/util/DLIList.cpp
===================================================================
--- cgm/branches/cubit/util/DLIList.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/DLIList.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -71,6 +71,23 @@
delete [] listArray;
}
+template <class X> MY_INLINE void DLIList<X>::reserve(int min_size)
+{
+ if (min_size > listLength)
+ {
+ X* temp_list = new X [min_size];
+
+ // If the list wasn't empty, copy over the old stuff
+ if (listLength)
+ {
+ memcpy (temp_list, listArray, listLength*sizeof(X));
+ delete [] listArray;
+ }
+ listLength = min_size;
+ listArray = temp_list;
+ }
+}
+
template <class X> MY_INLINE void DLIList<X>::lengthen_list(int by_how_much,
double by_what_factor)
{
@@ -78,16 +95,7 @@
int new_size =
(int) ((double)listLength * by_what_factor)
+ by_how_much;
- X* temp_list = new X [new_size];
-
- // If the list wasn't empty, copy over the old stuff
- if (listLength)
- {
- memcpy (temp_list, listArray, listLength*sizeof(X));
- delete [] listArray;
- }
- listLength = new_size;
- listArray = temp_list;
+ reserve(new_size);
}
//- put new item in list after current item and make it current
@@ -124,39 +132,7 @@
void DLIList<X>::merge_unique ( const DLIList<X>& merge_list,
bool merge_list_unique )
{
- // MJP Note:
- // This procedure could be much more efficient if sorted lists
- // are used. However, I need this procedure at this time to merge
- // DLILists that already exist. These were not created as sorted
- // lists (SDLILists) and it would be painful to convert them to
- // SDLILists. It would be a lot easier if one could simply sort
- // a DLIList based on the numeric values of its items.
-
- // Save the current index of the merge_list
- int old_size = size();
- int i, j, check_index;
-
- X new_item;
-
- for ( i = 0; i < merge_list.size(); i++)
- {
- // Get the item from the merge_list and insert it into "this"
- // list if it doesn't already exist there.
- new_item = merge_list.next(i);
- check_index = merge_list_unique ? old_size : size();
-
- for ( j = 0; j < check_index; j++ )
- {
- if ( listArray[j] == new_item )
- {
- check_index = -1;
- break;
- }
- }
- if ( check_index != -1 )
- append(new_item);
-// append_unique(new_item);
- }
+ this->casting_merge_unique(merge_list, merge_list_unique);
}
template <class X> MY_INLINE void DLIList<X>::intersect_unordered(
@@ -216,10 +192,10 @@
remove_all_with_value(NULL);
}
-template <class X> MY_INLINE void DLIList<X>::intersect ( void* merge_list )
-{
- intersect( *(DLIList<X>*)merge_list );
-}
+//template <class X> MY_INLINE void DLIList<X>::intersect ( void* merge_list )
+//{
+// intersect( *(DLIList<X>*)merge_list );
+//}
//- remove the item at the current location and return a pointer to it.
@@ -397,36 +373,7 @@
itemCount += from.itemCount;
return *this;
}
-template <class X> MY_INLINE DLIList<X>& DLIList<X>::
- operator+=(void* from)
-{
- DLIList<X>* cast_from = (DLIList<X>*)from;
-
- // Don't do anything if the list being appended is empty.
- if (cast_from->itemCount == 0)
- return *this;
- // Make sure the array is big enough
- int tmp_itemCount = itemCount + cast_from->itemCount;
- if (tmp_itemCount >= listLength)
- lengthen_list(tmp_itemCount - listLength, 2.0 );
- // factor of 1.0 can cause huge inefficiencies
-
- // Now add the 'from' items to the list
- if (cast_from->itemCount == 1)
- {
- listArray[itemCount] = cast_from->listArray[0];
- }
- else
- {
- memcpy (&listArray[itemCount], cast_from->listArray,
- cast_from->itemCount*sizeof(X));
- }
-
- // Increase the itemCount
- itemCount += cast_from->itemCount;
- return *this;
-}
template <class X> MY_INLINE DLIList<X>& DLIList<X>::
operator-=(const DLIList<X>& from)
{
@@ -705,10 +652,6 @@
template <class X> MY_INLINE CubitBoolean DLIList<X>::move_between(X item1, X item2)
{
-// if (nullItem && (((X)nullItem == item1 ||
-// ((X)nullItem == item2))))
-// return CUBIT_FALSE;
-// else
{
assert(item1 != NULL && item2 != NULL);
if ( !itemCount )
Modified: cgm/branches/cubit/util/DLIList.hpp
===================================================================
--- cgm/branches/cubit/util/DLIList.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/DLIList.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -1,19 +1,4 @@
//- Class: DLIList
-//- Description: DLIList is a doubly linked intrinsic list class that accepts
-//- any type of object. It uses a template to allow the same
-//- list class definition for any data type. Because the list
-//- makes a copy of each item added to the list, this type of
-//- list should only be used for simple data types such as
-//- integers, doubles, and enumerated types. Other data types
-//- should use the DLList, which keeps list of pointers.
-//- The list is implemented as an array that is grown by a
-//- specified amount when the list becomes full.
-//- Insertions and deletions at any point other than the end
-//- of the list are handled inefficiently at the current time
-//- since all data from that point to the end is bubbled
-//- down/up to fill/create the void. Operators {+} and {+=}
-//- are provided as an efficient means of assigning one list
-//- to another or appending one list onto another.
//-
//- Assumptions: All data are stored contiguously in the array with
//- empty slots at the end of the array.
@@ -25,219 +10,529 @@
#include "CubitDefines.h"
#include "CubitMessage.hpp"
-#include <string.h>
-#include <assert.h>
+#include <cstring>
+#include <cassert>
#define DLI_COUNT_INCREMENT 8
#define DLI_COUNT_FACTOR 1.5
template<class X> class DLIListIterator;
+//! A list class, similar to a std::vector<>.
+/*! DLIList is implemented as an array that is grown by a
+specified amount when the list becomes full.
+Most insertions and deletions at any point other than the end
+of the list are handled inefficiently
+since all data from that point to the end is bubbled
+down/up to fill/create the void. Operators {+} and {+=}
+are provided as an efficient means of assigning one list
+to another or appending one list onto another. The list has
+a current position, which is a zero-based index into the
+list. Many of the member functions operate on the current
+item (the item at the current position) or move the current
+position.
+*/
template<class X> class DLIList
{
public:
friend class DLIListIterator<X>;
+ //! Constructor: Create a list, allocating enough storage for \a size elements.
+ /*! Although enough space is allocated for \a size elements, the list starts
+ out empty (the size() function will return 0). If the requested memory size
+ is 0, then storage is not allocated until the first element is added to the list.
+ Additional storage space will be allocated if the list grows beyond its
+ original size.
+ \param size The amount of storage to pre-allocate for this list.
+ */
explicit DLIList (int size = 0);
- //- Constructor: Create a list with initial size 'size'. Memory for the
- //- list is not allocated until the first element is added to the list.
- DLIList(const DLIList<X>& from); //- Copy Constructor
+ //! Copy constructor.
+ /*! \param from The list to be copied. */
+ DLIList(const DLIList<X>& from);
+ //! Destructor: Free all resources used by this list.
+ /*! The list and its storage space are freed. Note that if this is a list
+ of pointers, this destructor will \a NOT delete the objects whose pointers
+ are stored in the list.
+ */
~DLIList();
- //- Destructor: Free all resources used by this list.
+ //! Move the pointer to the next element in the list.
+ /*! If pointer reaches the end of the list, wrap around to the beginning */
void step();
- //- Move the pointer to the next element in the list. If pointer reaches
- //- the end of the list, wrap around to the beginning
+ //! Move the pointer \a n positions forward in the list.
+ /*! The pointer will wrap around to the beginning of the list if the end
+ is reached. If \a n is less than zero, move backward.
+ \param n The number of positions to move forward or backward.
+ */
void step(int n);
- //- Move the pointer {n} positions forward in the list wrapping
- //- around to the beginning of the list if the end is reached
- //- If {n} is less than zero, move backward.
+ //! Move the pointer to the previous element in the list.
+ /*! If it reaches the beginning of the list, wrap around to the end. */
void back();
- //- Move the pointer to the previous element in the list. If reaches
- //- the beginning of the list, wrap around to the end
+ //! Move the pointer \a n positions backward in the list.
+ /*! The pointer will wrap around to the end of the list if the beginning
+ is reached. If \a n is less than zero, move forward.
+ */
void back(int n);
- //- Move the pointer {n} positions backward in the list wrapping
- //- around to the end of the list if the beginning is reached.
- //- If {n} is less than zero, move forward.
- void reset(); //- Set the pointer to the beginning of the list.
- void last(); //- Set the pointer to the end of the list.
+ //! Set the pointer to the beginning of the list.
+ void reset();
+ //! Set the pointer to the end of the list.
+ void last();
+ //! Delete all elements in the list.
+ /*! This function does not release memory already allocated for the list. This
+ call is more efficient than creating a new list repeatedly within a loop.
+ */
void clean_out();
- //- Delete all elements in the list, reset the pointer to zero.
- //- Does not release memory already allocated for the list. This
- //- call is more efficient than creating a new list repeatedly
- //- within a loop.
+ //! Reduces the size of the list by \a k.
+ /*! No list storage is freed. Items in the array are not changed.
+ If the current position is beyond the new end of the list, then the
+ current position is moved to the new end of the list.
+ */
void shrink(int k);
- //- itemCount -= k; Doesn't change array elements.
- //- Sets the index to the new end of the list if the old_index >=
- //- new_itemCount
+ //! Returns CUBIT_TRUE if the current position is at the beginning of the list.
CubitBoolean is_at_beginning() const;
- //- returns CUBIT_TRUE if list is at beginning
+ //! Returns CUBIT_TRUE if the current position is at the end of the list.
CubitBoolean is_at_end() const;
- //- returns CUBIT_TRUE if list is at end
- void remove_all_with_value(X val);
- //- Remove all items with value 'val'. This is similar to the DLList
- //- function pair nullify() and compress(). First, change the value
- //- of any elements you want to remove to 'val'. Then, call this
- //- function to compress the list.
-
+ //! Reverse the items in the list.
void reverse();
- //- Reverse the items in the list.
+ //! Create a copy of a list.
+ /*! This is the most efficient way to do this.
+ \return A reference to this list.*/
DLIList<X>& operator=(const DLIList<X>& from);
- DLIList<X>& operator=(const DLIListIterator<X>&);
- //- Create a copy of a list. Most efficient way to do this.
+
+ //! Create a copy of the list an iterator was obtained from.
+ /*! If \a from_iterator is not associated with a list,
+ then this list becomes empty.
+ \param from_iterator An iterator to another list.
+ \return A reference to this list.
+ */
+ DLIList<X>& operator=(const DLIListIterator<X>& from_iterator);
+ //! Append one list to another list.
+ /*! This is the most efficient way to append two lists together.
+ \param from The list to be appended to this list.
+ \return A reference to this list.
+ */
DLIList<X>& operator+=(const DLIList<X>& from);
- DLIList<X>& operator+=(void* from);
- //- Append one list to another list. Most efficient way to do this.
+ //! Subtract one list from another list.
+ /*! Any element in \from which is also found in this list
+ will be removed from this list. Element ordered is retained.
+ The \a from list is not modified.
+ \param from The list to be subtracted from this list.
+ \return A reference to this list.*/
DLIList<X>& operator-=(const DLIList<X>& from);
- //- Subtract one list from another list. Retains order.
- //Added by K. Walton 3/1/01
- //Needed to make changes from DLList
+ //! Compare two lists for equality.
+ /*! Two lists are considered equal if they have the same contents.
+ The elements do not need to be in the same order. If values are
+ repeated, they do have to appear an equal number of times in each list.
+ \param from The list to compare with this list.
+ \return True if the lists are equal, false otherwise.
+ */
int operator==(const DLIList<X>& from);
+
+ //! Compare two lists for inequality.
+ /*! Two lists are considered equal if they have the same contents.
+ The elements do not need to be in the same order. If values are
+ repeated, they do have to appear an equal number of times in each list.
+ \param from The list to compare with this list.
+ \return False if the lists are equal, true otherwise.
+ */
int operator!=(const DLIList<X>& from);
+ //! Gets a reference to the element with the given index.
+ /*! The index is zero-based.
+ \param index The index to the desired element.
+ \return A reference to the indicated element.
+ */
X & operator[](int index) const;
+
+ //! Gets a reference to the last element in the list.
+ X& last_item( void ) const;
+
+ //! Merges the contents of another list into this list.
+ /*! Each element in \a merge_list is added to this list, but only if
+ it does not already appear in this list. The result is a list where
+ no value appears twice.
+
+ This function runs faster if you know that no value is repeated in the
+ \a merge_list. This is indicated with the \a merge_list_unique parameter.
+ If \a merge_list_unique is
+ \a true, then elements of \merge_list will be checked against the original
+ contents of this list, but not against the other elements of \a merge_list.
+ If \a merge_list_unique is \a false, then each element will also be checked
+ against the other elements of \merge_list.
+
+ \param merge_list The list whose elements will be incorporated into this list.
+ \param merge_list_unique A flag indicating whether to skip a check for
+ uniqueness between elements of \a merge_list.
+ */
void merge_unique(const DLIList<X>& merge_list,
bool merge_list_unique = false);
- //- Merges the contents of the list, merge_list, with those of "this"
- //- list, ensuring that items that are being added do not already
- //- exist in "this" list. If the items are known to appear in the
- //- merge_list only once, then it can be done faster.
+ //! Merges the contents of a list of a different type into this list.
+ /*! This function is like merge_unique(), except that the type of object
+ stored by \a merge_list is not the same as this list's type. The type of
+ object stored in the other list must be able to be static_cast<> to this
+ list's type.
+ \param merge_list The list whose elements will be incorporated into this list.
+ \param merge_list_unique A flag indicating whether to skip a check for
+ uniqueness between elements of \a merge_list.
+ \sa merge_unique()
+ */
+ template<typename Y> inline void casting_merge_unique(const DLIList<Y>& merge_list,
+ bool merge_list_unique = false)
+ {
+ // Save the current index of the merge_list
+ int old_size = size();
+ int i, j, check_index;
+
+ X new_item;
+
+ // The resulting list will be at least as large as the larger of the two lists.
+ // Reserve space so we don't have to reallocate so often. Note that if
+ // this list is already bigger than merge_list, the reserve won't
+ // make the list shorter.
+ reserve(merge_list.size());
+
+ for ( i = 0; i < merge_list.size(); i++)
+ {
+ // Get the item from the merge_list and insert it into "this"
+ // list if it doesn't already exist there.
+ new_item = static_cast<X>(merge_list[i]);
+ check_index = merge_list_unique ? old_size : size();
+
+ // Append the new item and then remove it if necessary.
+ append(new_item);
+ for ( j = 0; j < check_index; j++ )
+ {
+ if ( listArray[j] == new_item )
+ {
+ itemCount--;
+ break;
+ }
+ }
+ }
+ }
+
+ //! Remove all elements that are not also in \a merge_list, preserving order.
+ /*! This version is O(n^2). If the order of elements in the list does
+ not matter, then consider using intersect_undordered(), which is O(n + sort_time).
+ \param merge_list The list containing values to keep.
+ \sa intersect_unordered(const DLIList<X>& merge_list)
+ */
void intersect(const DLIList<X>& merge_list);
- void intersect(void* merge_list);
+ //! Remove all elements that are not also in \a merge_list, not preserving order.
+ /*! This version is O(n + sort_time). If the order of elements in the list
+ is significant, then use intersect(), which is O(n^2) but preserves list order.
+ \param merge_list The list containing values to keep.
+ \sa intersect(const DLIList<X>& merge_list)
+ */
void intersect_unordered(const DLIList<X>& merge_list);
- //- The regular version is O(n^2)
- //- The unordered version is O(n + sort_time).
+ //! Appends the new item to the list, but only if it isn't already in the list.
+ /*! In either case, the current position is not changed.
+ \return CUBIT_TRUE if the item was added, otherwise CUBIT_FALSE.
+ */
CubitBoolean append_unique(X new_item);
- //- Appends the new item to the list, if it doesn't already exist
- //- in the list. In either case, index is not changed.
- //- Return CUBIT_TRUE if the item was added, else CUBIT_FALSE.
+ //! Ensure each element of the list only appears once, not preserving order.
+ /*! The list is first sorted for speed, so the order of elements may change.
+ The current position is set to 0.
+ \sa uniquify_ordered()
+ */
void uniquify_unordered();
- //- Ensure each element only appears once.
- //- Sorts first for speed, resets index to 0.
+ //! Ensure each element of the list only appears once, preserving order.
+ /*! The order of elements is preserved, but at a speed cost compared to
+ uniquify_unordered(). The current position is set to 0.
+ \sa uniquify_unordered()
+ */
void uniquify_ordered();
- //- Ensures each element appears only once.
- //- Preserves order. Resets index to 0.
+ //! Removes the current item from the list.
+ /*! Remaining items with an index higher than the current item
+ are moved up in the list. The current position is set to the next item
+ in the list (i.e., the index does not change) unless the removed item was
+ the last item in the list, in which case the current position is set to
+ the beginning of the list.
+ \return The removed item.
+ \sa remove(X val)
+ \sa remove_all_with_value(X val)
+ \sa omit(X val)
+ */
X remove ();
- //- Removes the current item from the list.
- X remove (X item);
- //- Removes item with value 'item' from the list.
+ //! Removes the next item with value \a val from the list.
+ /*! Only one element is removed from the list, even if the specified
+ value occurs multiple times in the list. The list is searched from
+ the current position to the end of the list, then from the beginning of
+ the list to the current position. The current position continues to
+ point at the same element, unless it is the element which was removed,
+ in which case the behavior is identical to remove().
+ \param val The value of the item to remove.
+ \return The removed item, or X(0) if the item was not found.
+ \sa remove()
+ \sa remove_all_with_value(X val)
+ \sa omit(X val)
+ */
+ X remove (X val);
+
+ //! Remove all instances of a given value from the list.
+ /*! This function can be used to remove multiple items efficiently.
+ First, change the value of any elements you want to remove to \a val.
+ Next, call this function with that same value. This is more efficient
+ than removing each element one at a time. After this function call,
+ the current position is set to the start of the list.
+ \sa remove()
+ \sa remove(X val)
+ \sa omit(X val)
+ */
+ void remove_all_with_value(X val);
+
+ //! Removes all instances of a value from the list.
+ /*! The current position of the list is not changed, unless the
+ current item is removed from the list. If the current item is
+ removed, then the current position is moved back one item, looping
+ to the back of the list if necessary.
+ \param val The value to remove from the list.
+ \return CUBIT_TRUE if at least one instance the item was removed, CUBIT_FALSE if not.
+ \sa remove()
+ \sa remove(X val)
+ \sa remove_all_with_value(X val)
+ */
+ CubitBoolean omit (X val);
- CubitBoolean omit (X old_val);
- //- Finds instance of item by matching value and deleting next instance
- //- of it from the list, wrapping if necessary. The current position of
- //- the list is not changed.
- //- Returns CUBIT_TRUE if the item was found, CUBIT_FALSE if not.
-
+ //! Returns the value of the current item.
+ /*! \return The value of the current item. If the list is empty, X(0) is returned.
+ */
X get () const;
- //- Returns value of current item
+ //! Returns the value at next position in the list.
+ /*! The current position is not changed. If the current position is at the
+ end of the list, the function wraps to the front of the list and returns the
+ value of the first item.
+ \return The value of the next item. If the list is empty, X(0) is returned.
+ */
X next () const;
- //- Returns value at next position in the list
+ //! Returns the value at \a n positions forward in list.
+ /*! The current position is not changed. If \a n positions beyond the
+ current position would move past the end of the list, the function wraps
+ around to the start of the list.
+ \param n The number of positions beyond the current position to return.
+ \return The value of the item \a n positions beyond the current position.
+ If the list is empty, X(0) is returned.
+ */
X next (int n) const;
- //- Returns value at 'n' positions forward in list
+ //! Returns the value at the previous position in list.
+ /*! The current position is not changed. If the current position is at the
+ beginning of the list, the function wraps to the end of the list and returns the
+ value of the last item.
+ \return The value of the previous item. If the list is empty, X(0) is returned.
+ */
X prev () const;
- //- Returns value at previous position in list
+ //! Returns the value at \a n positions back in list.
+ /*! The current position is not changed. If \a n positions before the
+ current position would move before the beginning of the list, the function wraps
+ around to the end of the list.
+ \param n The number of positions behind the current position to return.
+ \return The value of the item \a n positions before the current position.
+ If the list is empty, X(0) is returned.
+ */
X prev (int n) const;
- //- Returns value 'n' positions back in list
+ //! Returns the current value, then advances the current position by one.
+ /*! If the current position is at the end of the list, the function will
+ wrap to the beginning of the list.
+ \return The value at the current position, before stepping.
+ */
X get_and_step ();
- //- Returns value, then steps
+ //! Returns the current value, then moves the current position back one.
+ /*! If the current position is at the beginning of the list, the function will
+ wrap to the end of the list.
+ \return The value at the current position, before stepping back.
+ If the list is empty, X(0) is returned.
+ */
X get_and_back ();
- //- Returns value, then goes back
+ //! Advances the current position by one, then returns the current value.
+ /*! If the current position is at the end of the list, the function will
+ wrap to the beginning of the list.
+ \return The value at the current position, after stepping.
+ */
X step_and_get ();
- //- Steps then returns value
-// CubitBoolean move_between (X item1, X item2);
+ //! Moves to the next instance of this value, wrapping if necessary.
+ /*! \return Returns \a true if the item was found in the list, otherwise returns \a false.
+ */
CubitBoolean move_to(X item);
- //- Moves to the next instance of this value, wrapping if necessary
+
+ //! Return \a true if the item is in the list, \a false otherwise.
+ /*! \return Returns \a true if the item was found in the list, otherwise returns \a false.
+ */
CubitBoolean is_in_list(X item) const;
- //- Return True if item is in the list, false otherwise.
+ //! Returns and removes last value in list.
+ /*! \return Returns the last value in the list. If the list is empty, returns X(0).
+ */
X pop();
- //- Returns and removes last value in list
- X push(X value);
- //- Moves to end of list and appends and returns value
- void insert (X new_item);
- //- put new item in list after current item and make it current
- //- Inefficient due to bubbling.
- void insert_first(X new_item);
- //- Adds value at start of list. Inefficient due to bubbling.
+
+ //! Puts a value on the end of the list.
+ /*! The current position is then set to the end of the list.
+ \param val The value to place at the end of the list.
+ \return The value placed on the end of the list.
+ \sa push_back(X val)
+ */
+ X push(X val);
+
+ //! Insert an item into the list, after current item.
+ /*! The newly inserted item becomes the current item. This function is
+ inefficient due to bubbling.
+ \param val The item to insert.
+ */
+ void insert (X val);
+
+ //! Add a value at start of the list.
+ /*! The current position is set to the beginning of the list.
+ Inefficient due to bubbling.
+ \param val The value to place at the start of the list.
+ */
+ void insert_first(X val);
+
+ //! Place an item at the end of the list.
+ /*! This is the most efficient way to insert an item to the list.
+ The current position is unchanged.
+ \param val The value to place at the end of the list.
+ */
void append(X new_item);
- //- Adds value to end of list
+
+ //! Remove the current value and put last value in the list in its place.
+ /*! If list order isn't important, this is much more efficient than remove().
+ \return The value removed from the list, or X(0) if the list was empty.
+ */
X extract();
- //- Removes current value and puts last value
- //- in the list in its place. If list order isn't important, this is
- //- much more efficient than remove().
- X change_to(X new_value);
- //- Changes value of current Item.
+ //! Change the value of the current item.
+ /*! Because this function does not actually remove or insert an element,
+ it is quite efficient. If the list is empty, the new value will not be
+ inserted into the list.
+ \return The former value of the current item, or X(0) if the list was empty.
+ */
+ X change_to(X val);
+ //! Orders the list elements from lowest to highest.
+ /*! The sort order is determined by operator>= for the
+ stored element type.
+
+ Use reverse after this call if you want to go the
+ other direction.
+ */
void sort();
- //- Orders the list elements from lowest to highest.
- //- Use reverse after this call if you want to go the
- //- other direction.
+
+ //! A function which determines the relative order of objects.
+ /*!
+ The SortFunction should return a negative number if \a a should
+ be before \a b, a positive number if \a b comes before \a a, and
+ zero if they are equal, or relative order doesn't matter.
+ \param a The first object in the comparison
+ \param b The second object in the comparison
+ \sa sort(SortFunction f)
+ */
+ typedef int (*SortFunction)(X& a, X& b);
+
+ //! Orders the list elements from lowest to highest, as defined by a function.
+ /*! The sort order is determined by the passed in SortFunction.
- typedef int (*SortFunction)(X& a, X& b);
+ Use reverse after this call if you want to go the
+ other direction.
+ \param f The function which determines the sort order.
+ \sa SortFunction
+ */
void sort(SortFunction f);
- //- Sorts based on a function you pass in.
- //- SortFunction should return a negative number if 'a' should
- //- be before 'b', a positive number if 'b' comes before 'a', and
- //- zero if they are equal, or relative order doesn't matter.
+
+ //! Allocate enough space for at least \a min_size elements.
+ /*! If there is already enough space allocated, the function does nothing; this
+ function will never reduce the amount of memory allocated to the list.
+ \param min_size The minimum number of elements to be prepared to store.
+ */
+ void reserve(int min_size);
+ //! Returns the number of items in the list
+ /*! \return The number of items current in the list. */
int size() const
{ return itemCount; }
- //- Returns the number of items in the list
+ //! Returns current index of the current position
+ /*! \return the current position */
int get_index()
{ return index; }
- //- Returns current index value
- int where_is_item(X item) const;
- //- Return index of item in list, or -1 if item is not in the list.
+ //! Return the index of an item in list, or -1 if the item is not in the list.
+ /*! The location of the first instance of \a val is returned as a zero-based
+ index from the start of the list. The list is searched starting from the
+ current position, wrapping to the front of the list if necessary.
+ \param val The value to search for.
+ \return The index of the first instance of \a val, or -1 if the value is not found.
+ */
+ int where_is_item(X val) const;
- int memory_use(CubitBoolean verbose_boolean);
- //- return memory allocated in bytes
+ //! Returns the number of bytes allocated for this list's storage space.
+ int memory_use(CubitBoolean verbose_boolean);
+ //! Copy this list's contents into an array.
+ /*! It is assumed that \a other_array is big enough to hold all of this
+ list's elements. No check is made to verify this.
+ \param other_array The array into which this list's contents will be copied.
+ */
void copy_to(X *other_array);
- //- copy this list's listArray into other_array
+ //! Copy items from an array into this list.
+ /*! Any prior contents of this list are removed. The list allocates additional storage if necessary to hold all of
+ \a other_array's contents.
+ \param other_array The array from which items will be copied.
+ \param other_size The number of items to be copied from \a other_array.
+ */
void copy_from(X *other_array, const int other_size);
- //- copy items from other_array to this list
- CubitBoolean move_to_nearby(const X objPtr);
- //- searches from the current item both forward and backward.
+ //! Moves to the nearest instance of \a val, searching both forward and backward.
+ /*!
+ \return True if an item with the specified value was found, false otherwise.
+ */
+ CubitBoolean move_to_nearby(const X val);
- int distance_to_nearby(const X objPtr);
- //- Sets indes to the item in the list that matches {body}
+ //! Returns the distance to the nearest element with a given value.
+ /*! The returned value is always positive, regardless of whether the
+ closest element is before or after the current position.
+ \param val The value to search for.
+ \return The distance to the closest element with value \a val.
+ */
+ int distance_to_nearby(const X val);
- CubitBoolean move_between(X objPtr1, X objPtr2);
- //- Sets the index to the place matching one of the items,
- //- where the previous item is the other item
+ //! Set the current position to point at one of the two items, where the previous item is the other item.
+ /*! This function looks for a place in the list where these two items are adjacent
+ to each other, in either order. The current position is then set to the later
+ of the two items. The function acts in a wrapped manner, such that the last
+ item in the list is considered adjacent to the first item in the list.
+ \param val1 One of the values to look for.
+ \param val2 The other value to look for.
+ \return \a true if the two items are found adjacent to each other, \a false otherwise.
+ */
+ CubitBoolean move_between(X val1, X val2);
private:
void lengthen_list(int by_how_much = DLI_COUNT_INCREMENT,
@@ -270,6 +565,13 @@
return listArray[index];
}
+template <class X> inline
+X & DLIList<X>::last_item(void) const
+{
+ assert( itemCount > 0 );
+ return listArray[itemCount-1];
+}
+
template <class X> inline void DLIList<X>::step()
{
if (itemCount)
Modified: cgm/branches/cubit/util/DLList.hpp
===================================================================
--- cgm/branches/cubit/util/DLList.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/DLList.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -31,8 +31,8 @@
#include "ArrayBasedContainer.hpp"
#include "CubitDefines.h"
#include "CubitMessage.hpp"
-#include <string.h>
-#include <assert.h>
+#include <cstring>
+#include <cassert>
#include "CubitUtilConfigure.h"
class CUBIT_UTIL_EXPORT DLList : public ArrayBasedContainer
Modified: cgm/branches/cubit/util/DynamicArray.cpp
===================================================================
--- cgm/branches/cubit/util/DynamicArray.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/DynamicArray.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -4,7 +4,7 @@
//- Version: $Id:
#include "DynamicArray.hpp"
-#include <string.h>
+#include <cstring>
#if defined(NO_MEMMOVE)
extern "C" void *CUBIT_memmove(void *s1, const void *s2, size_t n);
Modified: cgm/branches/cubit/util/DynamicArray.hpp
===================================================================
--- cgm/branches/cubit/util/DynamicArray.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/DynamicArray.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -23,7 +23,7 @@
#include "MemoryManager.hpp"
#include "ArrayBasedContainer.hpp"
-#include <string.h>
+#include <cstring>
#include "CubitUtilConfigure.h"
class CUBIT_UTIL_EXPORT DynamicArray : public ArrayBasedContainer
Modified: cgm/branches/cubit/util/ElementType.h
===================================================================
--- cgm/branches/cubit/util/ElementType.h 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/ElementType.h 2010-01-06 19:22:14 UTC (rev 3423)
@@ -4,7 +4,7 @@
syncronized correctly. The invalid type MUST be 0
if we have an unknown element type in the .cc file.
DRW 10/20/97 */
-
+
enum ElementType { SPHERE_EXO=0,
BAR, BAR2, BAR3,
BEAM, BEAM2, BEAM3,
@@ -16,7 +16,10 @@
QUAD, QUAD4, QUAD5, QUAD8, QUAD9,
TETRA, TETRA4, TETRA8, TETRA10, TETRA14,
PYRAMID, PYRAMID5, PYRAMID8, PYRAMID13, PYRAMID18,
- HEX, HEX8, HEX9, HEX20, HEX27, HEXSHELL,
+ HEX, HEX8, HEX9, HEX20, HEX27, HEXSHELL,
+ FLATQUAD, FLATWEDGE, FLATHEX,
+ GAP, LUMPMASS, RIGID, CONSTRAINT,
+ WEDGE,
INVALID_ELEMENT_TYPE};
/*Invalid element type must be the last type...*/
#endif
Added: cgm/branches/cubit/util/ExternalCoordinateSystem.hpp
===================================================================
--- cgm/branches/cubit/util/ExternalCoordinateSystem.hpp (rev 0)
+++ cgm/branches/cubit/util/ExternalCoordinateSystem.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,21 @@
+
+#ifndef EXTERNAL_COORDINATE_SYSTEM_HPP
+#define EXTERNAL_COORDINATE_SYSTEM_HPP
+
+class ExternalCoordinateSystem
+{
+ public:
+
+ virtual ~ExternalCoordinateSystem() {}
+
+ //given s,n return x,y,z
+ virtual bool GetXYZ( double i, double j, double k,
+ double &x, double &y, double &z ) = 0;
+
+ //given x,y,z , return an s,n
+ virtual bool GetIJK( double x, double y, double z,
+ double &i, double &j, double &k ) = 0;
+};
+
+#endif
+
Modified: cgm/branches/cubit/util/GMem.cpp
===================================================================
--- cgm/branches/cubit/util/GMem.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/GMem.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -1,5 +1,5 @@
#include "GMem.hpp"
-#include <string.h> // To define NULL
+#include <cstring> // To define NULL
#include "CubitVector.hpp"
#include "DLIList.hpp"
#include "OctTree.hpp"
Modified: cgm/branches/cubit/util/GeometryDefines.h
===================================================================
--- cgm/branches/cubit/util/GeometryDefines.h 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/GeometryDefines.h 2010-01-06 19:22:14 UTC (rev 3423)
@@ -23,8 +23,10 @@
/* than GEOMETRY_RESABS the points are considered to be identical. */
#ifdef __cplusplus
const double GEOMETRY_RESABS = 1.0E-6;
+const double DEFAULT_GEOM_FACTOR = 500.0;
#else
#define GEOMETRY_RESABS 1.0E-6
+#define DEFAULT_GEOM_FACTOR 500.0
#endif
/* Types of solid modeler engines. */
@@ -36,6 +38,8 @@
NOT_A_SOLID_MODELER,
ACIS,
PROE_GEOM, /* Normal Pro/E model */
+ PROE_PART,
+ PROE_ASSEMBLY,
PROE_FEM_MESH_SOLID, /* Pro/Mesh models... */
PROE_FEM_MESH_SHELL,
PROE_FEM_MESH_MIXED,
@@ -77,11 +81,42 @@
TORUS_SURFACE_TYPE,
BEST_FIT_SURFACE_TYPE,
FACET_SURFACE_TYPE,
+ CYLINDER_SURFACE_TYPE, // only currently defined in ACIS Engine
UNDEFINED_SURFACE_TYPE,
/* Lump types */
UNDEFINED_LUMP_TYPE
};
+enum ImprintType
+{
+ NO_IMPRINT=0,
+ ONLY_INVOLVED_BODIES,
+ INCLUDE_NEIGHBORS,
+ TOL_IMPRINT,
+ TOL_IMPRINT_INCLUDE_NEIGHBORS
+};
+
+/* loops may be the following types */
+enum LoopType
+{
+ /* Unknown loop type */
+ LOOP_TYPE_UNKNOWN,
+
+ /* The external loop of a surface */
+ LOOP_TYPE_EXTERNAL,
+
+ /* The loop is a hole */
+ LOOP_TYPE_HOLE,
+
+ /* The loop is a u or v periodic loop (only applies to periodic surfaces)
+ * An example of this is a cylindrical surface with only 2 loops with each
+ * loop defining a cap of the cylinder.
+ * If its a u periodic loop, the face is periodic in u */
+ LOOP_TYPE_U_PERIODIC,
+ LOOP_TYPE_V_PERIODIC
+};
+
+
#endif
Modified: cgm/branches/cubit/util/GetLongOpt.hpp
===================================================================
--- cgm/branches/cubit/util/GetLongOpt.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/GetLongOpt.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -24,7 +24,7 @@
#include <iostream>
-#include <string.h>
+#include <cstring>
#include "CubitUtilConfigure.h"
class CUBIT_UTIL_EXPORT GetLongOpt {
Modified: cgm/branches/cubit/util/GfxDebug.cpp
===================================================================
--- cgm/branches/cubit/util/GfxDebug.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/GfxDebug.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -3,7 +3,8 @@
#include "GfxDebug.hpp"
#include "GMem.hpp"
#include "CubitVector.hpp"
-#include <assert.h>
+#include "DLIList.hpp"
+#include <cassert>
GfxDebug* GfxDebug::mInstance = 0;
@@ -491,6 +492,16 @@
mInstance->p_draw_point(*vector, color);
}
+void GfxDebug::draw_points( DLIList<CubitVector> &points, int color )
+{
+ if (!mInstance) return;
+ int i;
+ for ( i = 0; i < points.size(); i++ )
+ {
+ mInstance->p_draw_point( points[i], color );
+ }
+}
+
// draw line of points {x,y,z}, {x,y,z} of color
void GfxDebug::draw_line(float x1, float y1, float z1, float x2, float y2, float z2, int color)
{
Modified: cgm/branches/cubit/util/GfxDebug.hpp
===================================================================
--- cgm/branches/cubit/util/GfxDebug.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/GfxDebug.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -185,6 +185,7 @@
static void draw_point(float x, float y, float z, int color);
static void draw_point(const CubitVector& vector, int color);
static void draw_point(CubitVector* vector, int color);
+ static void draw_points( DLIList<CubitVector> &points, int color );
// draw line of points {x,y,z}, {x,y,z} of color
static void draw_line(float x1, float y1, float z1,
Added: cgm/branches/cubit/util/GlobalCommandFeedback.cpp
===================================================================
--- cgm/branches/cubit/util/GlobalCommandFeedback.cpp (rev 0)
+++ cgm/branches/cubit/util/GlobalCommandFeedback.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,18 @@
+#include "GlobalCommandFeedback.hpp"
+
+namespace GlobalCommandFeedback
+{
+ ManagedPtrVector<CommandFeedback>* instance_;
+
+ void create()
+ { instance_ = new ManagedPtrVector<CommandFeedback>; }
+
+ void destroy()
+ {
+ delete instance_;
+ instance_ = NULL;
+ }
+
+ ManagedPtrVector<CommandFeedback>& instance()
+ { return *instance_; }
+}
Added: cgm/branches/cubit/util/GlobalCommandFeedback.hpp
===================================================================
--- cgm/branches/cubit/util/GlobalCommandFeedback.hpp (rev 0)
+++ cgm/branches/cubit/util/GlobalCommandFeedback.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,15 @@
+#ifndef GLOBAL_COMMAND_FEEDBACK_HPP
+#define GLOBAL_COMMAND_FEEDBACK_HPP
+
+#include "CommandFeedback.hpp"
+#include "ManagedPtrVector.hpp"
+#include "CubitUtilConfigure.h"
+
+namespace GlobalCommandFeedback
+{
+ CUBIT_UTIL_EXPORT void create();
+ CUBIT_UTIL_EXPORT void destroy();
+ CUBIT_UTIL_EXPORT ManagedPtrVector<CommandFeedback>& instance();
+};
+
+#endif
Modified: cgm/branches/cubit/util/IntersectionTool.cpp
===================================================================
--- cgm/branches/cubit/util/IntersectionTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/IntersectionTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -98,14 +98,19 @@
return t;
}
-int IntersectionTool::point_on_polyline(CubitVector& pt, DLIList<CubitVector*> &pt_list)
+int IntersectionTool::point_on_polyline(CubitVector& pt, DLIList<CubitVector*> &pt_list,
+ double *tol_in)
{
int i, ret;
double t, distance;
double pt_coords[3];
double line_coords1[3];
double line_coords2[3];
+ double tol = GEOMETRY_RESABS;
+ if(tol_in)
+ tol = *tol_in;
+
ret = 0;
pt_coords[0] = pt.x();
@@ -127,7 +132,7 @@
distance = distance_point_line(pt_coords, line_coords1, line_coords2, t);
- if(distance > -GEOMETRY_RESABS && distance < GEOMETRY_RESABS)
+ if(distance > -tol && distance < tol)
{
i = 1;
ret = 1;
@@ -397,3 +402,182 @@
point_2 = p2 + tc*v;
return CUBIT_SUCCESS;
}
+
+int IntersectionTool::intersect_triangle_with_ray( CubitVector &ray_origin, CubitVector &ray_direction,
+ const CubitVector *p0, const CubitVector *p1, const CubitVector *p2,
+ CubitVector* point, double &distance, int &edge_hit )
+{
+ // This algorithm can be found at http://geometryalgorithms.com/
+
+ CubitVector n; // triangle vectors
+ CubitVector w0, w; // ray vectors
+ double a, b; // params to calc ray-plane intersect
+
+ double tol = GEOMETRY_RESABS;
+
+ // get triangle edge vectors and plane normal
+ CubitVector u( p1->x() - p0->x(),
+ p1->y() - p0->y(),
+ p1->z() - p0->z()); //(*p1-*p0);
+ CubitVector v( p2->x() - p0->x(),
+ p2->y() - p0->y(),
+ p2->z() - p0->z()); // = (*p2-*p0);
+
+ n = u * v; // cross product to get normal
+
+ if (n.length_squared() == 0) // triangle is degenerate
+ return -1; // do not deal with this case
+
+ //dir = R.P1 - R.P0; // ray direction vector
+ //w0 = R.P0 - T.V0;
+ w0 = CubitVector(ray_origin.x() - p0->x(),
+ ray_origin.y() - p0->y(),
+ ray_origin.z() - p0->z());
+
+ a = -(n%w0);
+ b = (n%ray_direction);
+ if (fabs(b) < tol) { // ray is parallel to triangle plane
+ if (a == 0) // ray lies in triangle plane
+ return 2;
+ else return 0; // ray disjoint from plane
+ }
+
+ // get intersect point of ray with triangle plane
+ distance = a / b;
+ if (distance < 0.0) // ray goes away from triangle
+ return 0; // => no intersect
+ // for a segment, also test if (r > 1.0) => no intersect
+
+ point->set(ray_origin + distance * ray_direction); // intersect point of ray and plane
+
+ // set distance to be absolute distance (if ray_direction was a unit vector)
+ distance = distance * ray_direction.length();
+
+ // is point inside facet?
+ double uu, uv, vv, wu, wv, D;
+ uu = u%u;
+ uv = u%v;
+ vv = v%v;
+ //w = *I - T.V0;
+ w = CubitVector(point->x() - p0->x(),
+ point->y() - p0->y(),
+ point->z() - p0->z());
+ wu = w%u;
+ wv = w%v;
+ D = uv * uv - uu * vv;
+
+ // get and test parametric coords
+ double s, t;
+ s = (uv * wv - vv * wu) / D;
+ if (s < 0.0 || s > 1.0) // point is outside facet
+ return 0;
+ t = (uv * wu - uu * wv) / D;
+ if (t < 0.0 || (s + t) > 1.0) // point is outside facet
+ return 0;
+
+ if (s==0)
+ edge_hit = 2; //lies along v, edge #2
+ if (t==0)
+ edge_hit = 1; //lies along u, edge #1
+ if (s+t==1)
+ edge_hit = 3; //lies along edge #3
+
+ // note:
+ // if s and t are both 0, hit the point p0
+ // if s=1 and t=0, hit point p1
+ // if s=0 and t=1, hit point p2
+
+ return 1; // point is in facet
+
+}
+
+int IntersectionTool::intersect_segment_with_ray( CubitVector &ray_origin, CubitVector &ray_direction,
+ const CubitVector *p0, const CubitVector *p1,
+ CubitVector* point, double &hit_distance, int &point_hit, double tol )
+{
+ // This algorithm can be found at http://geometryalgorithms.com/
+
+ if (tol == 0.0)
+ tol = GEOMETRY_RESABS;
+
+ CubitVector u = CubitVector(*p0, *p1);
+ CubitVector v = ray_direction;
+ v.normalize();
+
+ CubitVector w = CubitVector(ray_origin, *p0);
+
+ double sc, tc; // sc is fraction along facet edge, tc is distance along ray
+
+ double a = u%u; // always >= 0
+ double b = u%v;
+ double c = v%v; // always >= 0
+ double d = u%w;
+ double e = v%w;
+ double D = a*c - b*b; // always >= 0
+
+ // compute the line parameters of the two closest points
+ if (D < tol)
+ {
+ // the lines are almost parallel
+ sc = 0.0;
+ tc = (b>c ? d/b : e/c); // use the largest denominator
+ }
+ else
+ {
+ sc = (b*e - c*d) / D;
+ tc = (a*e - b*d) / D;
+ }
+
+ // get the difference of the two closest points
+ CubitVector dP = CubitVector(w + (sc * u) - (tc * v)); // = <0 0 0> if intersection
+
+ double distance = sqrt(dP % dP); // return the closest distance (0 if intersection)
+
+ point->set(*p0 + (sc * u));
+ hit_distance = tc; //distance from origin to intersection point
+
+ if (distance < tol)
+ {
+ //check if parallel (infinite intersection)
+ if (D < tol)
+ return 2;
+ //check if on edge
+ if (sc <= 1.0 && sc >= 0.0)
+ {
+ if (sc==0)
+ point_hit = 1; //hit point p0
+ if (sc==1)
+ point_hit = 2; //hit point p1
+
+ return 1;
+ }
+ else
+ return 0;
+ }
+
+ return 0;
+}
+
+int IntersectionTool::intersect_point_with_ray( CubitVector &ray_origin, CubitVector &ray_direction,
+ const CubitVector* point, double &distance, double tol)
+{
+ if (tol == 0.0)
+ tol = GEOMETRY_RESABS;
+
+ //Does the ray pass through the Point?
+ // Calc distance from ray origin to Point.
+ // Then compute coord's of point along ray that distance.
+ // Calc distance between Point and this ray-point. If less than tolerance, a hit.
+
+ CubitVector pointB;
+ double dist1 = point->distance_between(ray_origin);
+ ray_origin.next_point(ray_direction, dist1, pointB);
+
+ if ( pointB.distance_between_squared(*point) <= (tol*tol) )
+ {
+ distance = dist1;
+ return 1;
+ }
+
+ return 0;
+}
Modified: cgm/branches/cubit/util/IntersectionTool.hpp
===================================================================
--- cgm/branches/cubit/util/IntersectionTool.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/IntersectionTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -30,7 +30,8 @@
double distance_point_line(const double point[3], const double start[3],
const double end[3], double &t);
- int point_on_polyline(CubitVector& pt, DLIList<CubitVector*> &pt_list);
+ int point_on_polyline(CubitVector& pt, DLIList<CubitVector*> &pt_list,
+ double *tol_in = NULL);
double parametric_position(const double node[3],
const double pt1[3],
@@ -49,6 +50,41 @@
virtual CubitStatus initialize(){return CUBIT_SUCCESS;}
+ // The following copyright applies to the following two functions...
+ //
+ // Copyright 2001, softSurfer (www.softsurfer.com)
+ //
+ // This code may be freely used and modified for any purpose
+ // providing that this copyright notice is included with it.
+ // SoftSurfer makes no warranty for this code, and cannot be held
+ // liable for any real or imagined damage resulting from its use.
+ // Users of this code must verify correctness for their application.
+
+ static int intersect_triangle_with_ray( CubitVector &ray_origin, CubitVector &ray_direction,
+ const CubitVector *p0, const CubitVector *p1, const CubitVector *p2,
+ CubitVector* point, double &distance, int &edge_hit );
+ //- Find intersection point of a ray and a triangle
+ // Return: -1 = triangle is degenerate (a segment or point)
+ // 0 = disjoint (no intersect)
+ // 1 = intersect at unique point
+ // 2 = are in the same plane
+
+ static int intersect_segment_with_ray( CubitVector &ray_origin, CubitVector &ray_direction,
+ const CubitVector *p0, const CubitVector *p1,
+ CubitVector* point, double &distance, int &point_hit, double tol=0.0 );
+ //- Find intersection point of a ray and a facet edge
+ // Return: -1 = edge is degenerate (a point)
+ // 0 = disjoint (no intersect)
+ // 1 = intersect at unique point
+ // 2 = are the same line (infinite points)
+
+ static int intersect_point_with_ray( CubitVector &ray_origin, CubitVector &ray_direction,
+ const CubitVector* point, double &distance, double tol=0.0);
+ //- Find intersection of a ray and a point
+ // Return: 0 = no intersection
+ // 1 = intersection
+
+
protected:
double mTolerance;
double mToleranceSquared;
Modified: cgm/branches/cubit/util/KDDTree.cpp
===================================================================
--- cgm/branches/cubit/util/KDDTree.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/KDDTree.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -23,8 +23,8 @@
// Include Files
//---------------------------------
-#include <stdlib.h>
-#include <stdio.h>
+#include <cstdlib>
+#include <cstdio>
#include <time.h>
#include "KDDTree.hpp"
Modified: cgm/branches/cubit/util/Makefile.am
===================================================================
--- cgm/branches/cubit/util/Makefile.am 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/Makefile.am 2010-01-06 19:22:14 UTC (rev 3423)
@@ -38,6 +38,7 @@
CubitStack.cpp \
CubitString.cpp \
CubitTransformMatrix.cpp \
+ CubitUndo.cpp \
CubitUtil.cpp \
CubitVector.cpp \
DIntArray.cpp \
@@ -46,6 +47,7 @@
GMem.cpp \
GetLongOpt.cpp \
GfxDebug.cpp \
+ GlobalCommandFeedback.cpp \
IntersectionTool.cpp \
MemoryBlock.cpp \
MemoryManager.cpp \
@@ -71,6 +73,7 @@
AppUtil.hpp \
ArrayBasedContainer.hpp \
CastTo.hpp \
+ CommandFeedback.hpp \
CpuTimer.hpp \
Cubit2DPoint.hpp \
CubitBox.hpp \
@@ -99,6 +102,7 @@
CubitStack.hpp \
CubitString.hpp \
CubitTransformMatrix.hpp \
+ CubitUndo.hpp \
CubitUtil.hpp \
CubitUtilConfigure.h \
CubitVector.hpp \
@@ -119,10 +123,12 @@
DynamicDLIIterator.hpp \
DynamicTreeIterator.hpp \
ElementType.h \
+ ExternalCoordinateSystem.hpp \
GMem.hpp \
GeometryDefines.h \
GetLongOpt.hpp \
GfxDebug.hpp \
+ GlobalCommandFeedback.hpp \
IGUIObservers.hpp \
IdSetEvent.hpp \
IndexedDouble.hpp \
@@ -131,11 +137,14 @@
KDDTree.hpp \
KDDTreeNode.hpp \
LocalStart.h \
+ ManagedPtrVector.hpp \
MemoryBlock.hpp \
MemoryManager.hpp \
MergeEvent.hpp \
OctTree.hpp \
OctTreeCell.hpp \
+ OrderedMap.hpp \
+ OrderedSet.hpp \
ParamCubitPlane.hpp \
ParamTool.hpp \
PlanarParamTool.hpp \
Added: cgm/branches/cubit/util/ManagedPtrVector.hpp
===================================================================
--- cgm/branches/cubit/util/ManagedPtrVector.hpp (rev 0)
+++ cgm/branches/cubit/util/ManagedPtrVector.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,193 @@
+#ifndef MANAGED_PTR_VECTOR
+#define MANAGED_PTR_VECTOR
+
+#include <vector>
+#include <memory>
+
+//! A vector of pointers to objects that are automatically deleted when the container itself is deleted.
+/*! Loosely
+modeled after the boost ptr containers.
+*/
+template <typename X>
+class ManagedPtrVector
+{
+public:
+ typedef X value_type;
+ typedef X& reference_type;
+ typedef size_t size_type;
+ typedef std::vector<X*> container_type;
+
+ class iterator
+ {
+ public:
+ typedef iterator this_type;
+ typedef X& reference;
+ typedef size_t size_type;
+ typedef size_t difference_type;
+
+ iterator()
+ {}
+ iterator(const this_type& rhs)
+ :mIter(rhs.mIter)
+ {}
+ iterator(const typename ManagedPtrVector<X>::container_type::iterator& rhs)
+ : mIter(rhs)
+ {}
+ ~iterator()
+ {}
+
+ X* operator->()
+ { return *mIter; }
+ reference operator*() const
+ { return **mIter; }
+
+ bool operator==(const this_type& rhs) const
+ { return this->mIter == rhs.mIter; }
+ bool operator!=(const this_type& rhs) const
+ { return this->mIter != rhs.mIter; }
+
+ this_type& operator++()
+ {
+ ++mIter;
+ return *this;
+ }
+
+ this_type operator++(int)
+ {
+ this_type rv = *this;
+ ++mIter;
+ return rv;
+ }
+
+ this_type& operator--()
+ {
+ --mIter;
+ return *this;
+ }
+
+ this_type operator--(int)
+ {
+ this_type rv = *this;
+ --mIter;
+ return rv;
+ }
+
+ this_type operator+(difference_type n)
+ {
+ this_type rv = *this;
+ rv += n;
+ return rv;
+ }
+
+ this_type& operator+=(difference_type n)
+ {
+ mIter += n;
+ return *this;
+ }
+
+ this_type& operator-=(difference_type n)
+ {
+ mIter -= n;
+ return *this;
+ }
+
+ reference operator[](difference_type i) const
+ {
+ return reference(*(mIter+i));
+ }
+
+ private:
+ typename ManagedPtrVector<X>::container_type::iterator mIter;
+ };
+
+
+ ManagedPtrVector()
+ {}
+ ~ManagedPtrVector()
+ { clear(); }
+
+ // Add an object to the container.
+ // The container becomes "owned" by the container.
+ void push_back(X* obj)
+ { mContainer.push_back(obj); }
+
+ iterator begin()
+ { return iterator(mContainer.begin()); }
+ iterator end()
+ { return iterator(mContainer.end()); }
+
+ //! Refer by index
+ reference_type operator[](size_type i)
+ { return *(mContainer[i]); }
+
+ //! Remove an item from the list without deleting it.
+ /*! The returned auto_ptr now owns the pointer.*/
+ std::auto_ptr<X> release(iterator to_release)
+ {
+ // save a raw pointer.
+ X* rv = to_release.operator->();
+ // find the iterator in the container. We don't have access
+ // to the internal iterator, so we have to loop through to find it.
+ // This could probably be optimized.
+ typename container_type::iterator i = mContainer.begin();
+ for (;
+ i != mContainer.end() && iterator(i) != to_release;
+ ++i)
+ {}
+ // we either found the iterator, or the end. erase it.
+ mContainer.erase(i);
+ return std::auto_ptr<X>(rv);
+ }
+
+ //! Replace one object with another.
+ /*! The returned auto_ptr now owns the pointer removed from
+ the container, and the container owns the object pointed to
+ by \a new_val.
+ */
+ std::auto_ptr<X> replace(iterator to_replace, std::auto_ptr<X> new_val)
+ {
+ // save a raw pointer.
+ X* rv = to_replace.operator->();
+ // find the iterator in the container. We don't have access
+ // to the internal iterator, so we have to loop through to find it.
+ // This could probably be optimized.
+ typename container_type::iterator i = mContainer.begin();
+ for (;
+ i != mContainer.end();
+ ++i)
+ {
+ if (iterator(i) == to_replace)
+ {
+ *i = new_val;
+ }
+ }
+ return std::auto_ptr<X>(NULL);
+ }
+
+ // Delete all objects contained in this container.
+ void clear()
+ {
+ // delete all the pointers
+ for (typename container_type::iterator i = mContainer.begin();
+ i != mContainer.end();
+ i++)
+ {
+ delete *i;
+ }
+ mContainer.clear();
+ }
+
+ size_type size() const
+ { return mContainer.size(); }
+
+private:
+ // Make both of these illegal
+ ManagedPtrVector(const ManagedPtrVector<X>&);
+ ManagedPtrVector& operator=(const ManagedPtrVector<X>&);
+
+ container_type mContainer;
+};
+
+
+
+#endif
Modified: cgm/branches/cubit/util/MemoryBlock.hpp
===================================================================
--- cgm/branches/cubit/util/MemoryBlock.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/MemoryBlock.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -9,7 +9,7 @@
#ifndef MEMORY_BLOCK_HPP
#define MEMORY_BLOCK_HPP
-#include <stdlib.h>
+#include <cstdlib>
#include "CubitUtilConfigure.h"
class CUBIT_UTIL_EXPORT MemoryBlock
Modified: cgm/branches/cubit/util/MemoryManager.cpp
===================================================================
--- cgm/branches/cubit/util/MemoryManager.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/MemoryManager.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -15,8 +15,8 @@
#include "CubitMessage.hpp"
#include "ArrayBasedContainer.hpp"
#include "AppUtil.hpp"
-#include <assert.h>
-#include <string.h>
+#include <cassert>
+#include <cstring>
#ifndef NT
#include <unistd.h>
#endif
@@ -447,38 +447,51 @@
#endif
// send requests of "wrong" size to ::new
-
- if (size != objectSize) return ::new char[size];
-
+
+ try
+ {
+ if (size != objectSize) return ::new char[size];
+ }
+ catch(...)
+ {
+ return (void*) NULL;
+ }
// get new element from head of free list
char* p = headOfFreeList;
- if(!p)
- {
- // allocate new block
+ try
+ {
+ if(!p)
+ {
+ // allocate new block
- int block_size = memAllocatnSize * size;
- char* new_block = ::new char[block_size];
- if (!new_block) return (void*) NULL;
+ int block_size = memAllocatnSize * size;
+ char* new_block = ::new char[block_size];
+ if (!new_block) return (void*) NULL;
- // link new elements to form the free list
+ // link new elements to form the free list
- int fill_limit = (memAllocatnSize - 1) * size;
- for (int j = 0; j < fill_limit; j += size)
- {
- *((char**) &new_block[j]) = &new_block[j + size];
- }
- *((char**) &new_block[fill_limit]) = (char*) NULL;
+ int fill_limit = (memAllocatnSize - 1) * size;
+ for (int j = 0; j < fill_limit; j += size)
+ {
+ *((char**) &new_block[j]) = &new_block[j + size];
+ }
+ *((char**) &new_block[fill_limit]) = (char*) NULL;
- // assign new element
+ // assign new element
- p = new_block;
+ p = new_block;
- // save new block to memory block stack
+ // save new block to memory block stack
- memBlockStack = new MemoryBlock(memBlockStack, new_block, block_size);
+ memBlockStack = new MemoryBlock(memBlockStack, new_block, block_size);
+ }
}
+ catch(...)
+ {
+ return (void*) NULL;
+ }
//assign head of free list and return p
headOfFreeList = *((char**) p);
Modified: cgm/branches/cubit/util/MemoryManager.hpp
===================================================================
--- cgm/branches/cubit/util/MemoryManager.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/MemoryManager.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -20,8 +20,8 @@
const int STATIC_MEMORY_MANAGER = 1;
//- Static Memory Manager definition argument
-#include <stdlib.h>
-#include <assert.h>
+#include <cstdlib>
+#include <cassert>
#include "CubitUtilConfigure.h"
class MemoryBlock;
Modified: cgm/branches/cubit/util/OctTree.cpp
===================================================================
--- cgm/branches/cubit/util/OctTree.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/OctTree.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -110,9 +110,9 @@
// other nodes were allocated from our internal memory bool by
// the allocate_8() method. We just release the whole pool.
delete root_;
- delete node_memory_;
+ delete [] node_memory_;
while( mem_pages_.size() )
- delete mem_pages_.pop();
+ delete [] mem_pages_.pop();
// Reinitialize to catch stale pointer to this object.
Added: cgm/branches/cubit/util/OrderedMap.hpp
===================================================================
--- cgm/branches/cubit/util/OrderedMap.hpp (rev 0)
+++ cgm/branches/cubit/util/OrderedMap.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,121 @@
+//-------------------------------------------------------------------------
+// Filename : OrderedMap.hpp
+//
+// Purpose : An std::map that keeps order that things were inserted
+// into it.
+//
+// Creator : Matt Staten
+//
+// Creation Date : 01/27/2006
+//
+// Owner : Matt Staten
+//-------------------------------------------------------------------------
+
+#ifndef OrderedMap_HPP
+#define OrderedMap_HPP
+
+#include <map>
+#include "DLIList.hpp"
+
+template<class X, class Y> class OrderedMap
+{
+private:
+ DLIList<X> mList1;
+ std::map<X,Y> mMap;
+
+public:
+
+ OrderedMap( void ) {};
+
+ bool find( X key, Y *data = NULL ) const
+ {
+ typename std::map<X,Y>::const_iterator iter = mMap.find( key );
+ if ( iter == mMap.end() )
+ {
+ return CUBIT_FALSE;
+ }
+ if ( data )
+ {
+ *data = iter->second;
+ }
+ return CUBIT_TRUE;
+ };
+
+ // Return true if the new pair was inserted.
+ // Return false if this key is already being used.
+ bool insert( X new_key, Y new_data )
+ {
+ if ( !find( new_key ) )
+ {
+ mList1.append( new_key );
+ mMap.insert( std::map<X,Y>::value_type( new_key, new_data ) );
+ return CUBIT_TRUE;
+ }
+ return CUBIT_FALSE;
+ };
+
+ // This can be inefficient
+ void erase( X key_to_erase )
+ {
+ typename std::map<X,Y>::iterator iter = mMap.find( key_to_erase );
+ if ( iter != mMap.end() )
+ {
+ mMap.erase( iter );
+ mList1.remove_all_with_value( key_to_erase );
+ }
+ };
+
+ void erase_iter( int iter_to_erase )
+ {
+ X key_to_erase = mList1[iter_to_erase];
+ typename std::map<X,Y>::iterator iter = mMap.find( key_to_erase );
+ if ( iter != mMap.end() )
+ {
+ mMap.erase( iter );
+ mList1.remove_all_with_value( key_to_erase );
+ }
+ };
+
+ X first( int iter ) const
+ {
+ return mList1[iter];
+ }
+ Y second( int iter ) const
+ {
+ Y data;
+ bool stat = find( mList1[iter], &data );
+ assert(stat);
+ return data;
+ }
+
+ bool empty( void ) const { return ( mList1.size() == 0 ? CUBIT_TRUE : CUBIT_FALSE ); };
+ int size( void ) const { return mList1.size(); };
+
+ void clean_out( void )
+ {
+ mList1.clean_out();
+ mMap.clear();
+ };
+
+ OrderedMap<X,Y>& operator=(const OrderedMap<X,Y>&from)
+ {
+ clean_out();
+ for ( int i = 0; i < from.size(); i++ )
+ {
+ X key = from.first( i );
+ Y data = from.second( i );
+ this->insert( key, data );
+ }
+ return *this;
+ };
+
+ Y operator[]( X key ) const
+ {
+ Y data;
+ bool stat = find( key, &data );
+ assert(stat);
+ return data;
+ };
+};
+
+#endif // OrderedMap_HPP
Added: cgm/branches/cubit/util/OrderedSet.hpp
===================================================================
--- cgm/branches/cubit/util/OrderedSet.hpp (rev 0)
+++ cgm/branches/cubit/util/OrderedSet.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -0,0 +1,330 @@
+//-------------------------------------------------------------------------
+// Filename : OrderedSet.hpp
+//
+// Purpose : A DLIList that does not allow duplicates and is faster
+// at inserting uniquely than DLIList.
+//
+// Creator : Matt Staten
+//
+// Creation Date : 09/22/2005
+//
+// Owner : Matt Staten
+//-------------------------------------------------------------------------
+
+#ifndef OrderedSet_HPP
+#define OrderedSet_HPP
+
+#include <set>
+#include "DLIList.hpp"
+
+template<class X> class OrderedSet
+{
+private:
+ DLIList<X> mList;
+ std::set<X> mSet;
+
+public:
+
+ OrderedSet( void ) {};
+ OrderedSet( const DLIList<X> list )
+ {
+ int i;
+ for ( i = 0; i < list.size(); i++ )
+ {
+ append( list[i] );
+ }
+ };
+
+ CubitBoolean is_in_list( X item ) const
+ {
+ if ( mSet.find( item ) == mSet.end() )
+ {
+ return CUBIT_FALSE;
+ }
+ return CUBIT_TRUE;
+ };
+
+ int where_is_item( X item ) const
+ {
+ CubitBoolean stat = is_in_list( item );
+ if ( stat == CUBIT_TRUE )
+ {
+ return mList.where_is_item( item );
+ }
+ return -1;
+ };
+
+ // true if it could be replaced. false if old_item is not in the list
+ bool replace_item( X old_item, X new_item )
+ {
+ if ( is_in_list( old_item ) )
+ {
+ for ( int i = 0; i < mList.size(); i++ )
+ {
+ if ( mList[i] == old_item )
+ {
+ mList[i] = new_item;
+ mSet.erase( old_item );
+ mSet.insert( new_item );
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+
+ CubitBoolean insert( X new_item )
+ {
+ if ( !is_in_list( new_item ) )
+ {
+ force_insert( new_item );
+ return CUBIT_TRUE;
+ }
+ return CUBIT_FALSE;
+ }
+
+ // Append to the end of this list.
+ CubitBoolean append( X new_item )
+ {
+ return insert( new_item );
+ }
+
+ // insert at the beginning of the list.
+ CubitBoolean prepend( X new_item )
+ {
+ if ( !is_in_list( new_item ) )
+ {
+ mList.insert_first( new_item );
+ mSet.insert( new_item );
+ return CUBIT_TRUE;
+ }
+ return CUBIT_FALSE;
+ }
+
+ void force_insert( X new_item )
+ {
+ mList.append( new_item );
+ mSet.insert( new_item );
+ };
+
+ void reverse( void )
+ {
+ mList.reverse();
+ };
+
+ void reset( void )
+ {
+ mList.reset();
+ };
+
+ void reserve( int min_size )
+ {
+ mList.reserve(min_size);
+ };
+
+ X get_and_step( int n = 1 )
+ {
+ X temp = get();
+ step( n );
+ return temp;
+ };
+
+ void step( int n = 1 )
+ {
+ mList.step( n );
+ };
+
+ X get() const
+ {
+ return mList.get();
+ };
+
+ X & operator[](int index) const;
+ OrderedSet<X>& operator=(const OrderedSet<X>& from);
+ OrderedSet<X>& operator=(const DLIList<X>& from);
+ OrderedSet<X>& operator+=(const DLIList<X>& from);
+ OrderedSet<X>& operator+=(const OrderedSet<X>& from);
+ OrderedSet<X>& operator+=( X from );
+ OrderedSet<X>& operator-=(const DLIList<X>& from);
+ OrderedSet<X>& operator-=(const OrderedSet<X> &from);
+ OrderedSet<X>& operator-=(const OrderedSet<X> *from);
+ OrderedSet<X>& operator-=( X from );
+ OrderedSet<X> operator&( const OrderedSet<X> other_set ) const;
+ OrderedSet<X> operator|( const OrderedSet<X> other_set ) const;
+
+ CubitBoolean empty( void ) const { return ( mList.size() == 0 ? CUBIT_TRUE : CUBIT_FALSE ); };
+ int size( void ) const { return mList.size(); };
+ X pop( void )
+ {
+ X item = mList.pop();
+ mSet.erase( item );
+ return item;
+ };
+ void remove( X item )
+ {
+ if ( !is_in_list( item ) )
+ return;
+ mList.remove_all_with_value( item );
+ mSet.erase( item );
+ };
+
+ void clean_out( void )
+ {
+ mList.clean_out();
+ mSet.clear();
+ };
+
+ void list( DLIList<X> &list ) const
+ {
+ list = mList;
+ }
+ const DLIList<X> * list( void ) const
+ {
+ return &mList;
+ }
+
+ X & last( void ) const;
+ X & first( void ) const;
+};
+
+template <class X> inline
+X & OrderedSet<X>::last(void) const
+{
+ assert( mList.size() > 0 );
+ int index = mList.size()-1;
+ return mList[index];
+}
+
+template <class X> inline
+X & OrderedSet<X>::first(void) const
+{
+ assert( mList.size() > 0 );
+ return mList[0];
+}
+
+template <class X> inline
+X & OrderedSet<X>::operator[](int index) const
+{
+ return mList[index];
+}
+
+template <class X> inline
+OrderedSet<X>& OrderedSet<X>::operator=(const OrderedSet<X>& from)
+{
+ mList.clean_out();
+ mSet.clear();
+ int i;
+ int from_size = from.mList.size();
+ for ( i = 0; i < from_size; i++ )
+ {
+ force_insert( from.mList[i] );
+ }
+ return *this;
+}
+
+template <class X> inline
+OrderedSet<X>& OrderedSet<X>::operator=(const DLIList<X>& list)
+{
+ mList.clean_out();
+ mSet.clear();
+ int i;
+ int list_size = list.size();
+ for ( i = 0; i < list_size; i++ )
+ {
+ this->insert( list[i] );
+ }
+ return *this;
+}
+
+template <class X> inline
+OrderedSet<X>& OrderedSet<X>::operator+=( X from )
+{
+ this->insert( from );
+ return *this;
+}
+
+template <class X> inline
+OrderedSet<X>& OrderedSet<X>::operator-=( X from )
+{
+ this->remove( from );
+ return *this;
+}
+
+template <class X> inline
+OrderedSet<X>& OrderedSet<X>::operator+=(const DLIList<X>& list)
+{
+ int i;
+ for ( i = 0; i < list.size(); i++ )
+ {
+ this->insert( list[i] );
+ }
+ return *this;
+}
+
+template <class X> inline
+OrderedSet<X>& OrderedSet<X>::operator+=(const OrderedSet<X>& list)
+{
+ int i;
+ for ( i = 0; i < list.size(); i++ )
+ {
+ this->insert( list[i] );
+ }
+ return *this;
+}
+
+template <class X> inline
+OrderedSet<X>& OrderedSet<X>::operator-=(const DLIList<X>& list)
+{
+ int i;
+ for ( i = 0; i < list.size(); i++ )
+ {
+ this->remove( list[i] );
+ }
+ return *this;
+}
+
+template <class X> inline
+OrderedSet<X>& OrderedSet<X>::operator-=(const OrderedSet<X>& list)
+{
+ int i;
+ for ( i = 0; i < list.size(); i++ )
+ {
+ this->remove( list[i] );
+ }
+ return *this;
+}
+
+template <class X> inline
+OrderedSet<X>& OrderedSet<X>::operator-=(const OrderedSet<X> *list)
+{
+ int i;
+ for ( i = 0; i < list->size(); i++ )
+ {
+ this->remove( (*list)[i] );
+ }
+ return *this;
+}
+
+template <class X> inline
+OrderedSet<X> OrderedSet<X>::operator&( const OrderedSet<X> other_set ) const
+{
+ OrderedSet<X> tmp;
+ for ( int i = 0; i < other_set.size(); i++ )
+ {
+ if ( this->is_in_list( other_set[i] ) )
+ {
+ tmp.append( other_set[i] );
+ }
+ }
+ return tmp;
+}
+
+template <class X> inline
+OrderedSet<X> OrderedSet<X>::operator|( const OrderedSet<X> other_set ) const
+{
+ OrderedSet<X> tmp = *this;
+ tmp += other_set;
+ return tmp;
+}
+
+#endif // OrderedSet_HPP
Modified: cgm/branches/cubit/util/OtherFiles/make.client
===================================================================
--- cgm/branches/cubit/util/OtherFiles/make.client 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/OtherFiles/make.client 2010-01-06 19:22:14 UTC (rev 3423)
@@ -68,7 +68,7 @@
SHELL = /bin/sh
-CUBIT_VERSION = 10.2
+CUBIT_VERSION = 12.0b
include ${CUBIT_BASE_DIR}/util/OtherFiles/cubiti.version
Modified: cgm/branches/cubit/util/ParamTool.hpp
===================================================================
--- cgm/branches/cubit/util/ParamTool.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/ParamTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -29,10 +29,13 @@
ParamTool() {}
virtual ~ParamTool() {}
- virtual CubitStatus transform_to_uv(CubitVector &xyz_location, CubitVector &uv_location) = 0;
+ virtual CubitStatus transform_to_uv(const CubitVector &xyz_location, CubitVector &uv_location) = 0;
- virtual CubitStatus transform_to_xyz(CubitVector &xyz_location, CubitVector &uv_location) = 0;
+ virtual CubitStatus transform_to_xyz(CubitVector &xyz_location, const CubitVector &uv_location) = 0;
+ virtual CubitStatus uv_derivitives( double u_param, double v_param,
+ CubitVector &du, CubitVector &dv ) {return CUBIT_FAILURE;}
+
};
#endif // PARAM_TOOL_HPP
Modified: cgm/branches/cubit/util/PlanarParamTool.cpp
===================================================================
--- cgm/branches/cubit/util/PlanarParamTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/PlanarParamTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -55,7 +55,7 @@
// Author: chynes
// Date: 7/10/02
//===================================================================================
-CubitStatus PlanarParamTool::transform_to_uv(CubitVector &xyz_location, CubitVector &uv_location)
+CubitStatus PlanarParamTool::transform_to_uv(const CubitVector &xyz_location, CubitVector &uv_location)
{
// Translate to local origin at center
@@ -65,7 +65,7 @@
uv_location.x( vect % Du );
uv_location.y( vect % Dv );
- uv_location.z( 1.0 );
+ uv_location.z( 0.0 );
return CUBIT_SUCCESS;
}
@@ -76,7 +76,7 @@
// Author: chynes
// Date: 7/10/02
//===================================================================================
-CubitStatus PlanarParamTool::transform_to_xyz(CubitVector &xyz_location, CubitVector &uv_location)
+CubitStatus PlanarParamTool::transform_to_xyz(CubitVector &xyz_location, const CubitVector &uv_location)
{
// Multiply by transformation matrix
@@ -95,6 +95,12 @@
return CUBIT_SUCCESS;
}
+CubitStatus PlanarParamTool::uv_derivitives( double u_param, double v_param,
+ CubitVector &du, CubitVector &dv )
+{
+ du = Du;
+ dv = Dv;
+ return CUBIT_SUCCESS;
+}
-
//EOF
Modified: cgm/branches/cubit/util/PlanarParamTool.hpp
===================================================================
--- cgm/branches/cubit/util/PlanarParamTool.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/PlanarParamTool.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -29,10 +29,12 @@
CubitStatus set_up_space(CubitVector& du, CubitVector& dv, CubitVector& uv_center);
- CubitStatus transform_to_uv(CubitVector &xyz_location, CubitVector &uv_location);
+ CubitStatus transform_to_uv(const CubitVector &xyz_location, CubitVector &uv_location);
- CubitStatus transform_to_xyz(CubitVector &xyz_location, CubitVector &uv_location);
+ CubitStatus transform_to_xyz(CubitVector &xyz_location, const CubitVector &uv_location);
+ virtual CubitStatus uv_derivitives( double u_param, double v_param,
+ CubitVector &du, CubitVector &dv );
private:
Modified: cgm/branches/cubit/util/PriorityQueue.cpp
===================================================================
--- cgm/branches/cubit/util/PriorityQueue.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/PriorityQueue.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -1,4 +1,4 @@
-#include "assert.h"
+#include "cassert"
#include "PriorityQueue.hpp"
#include "CubitMessage.hpp"
Modified: cgm/branches/cubit/util/RTree.cpp
===================================================================
--- cgm/branches/cubit/util/RTree.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/RTree.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -292,5 +292,63 @@
return CUBIT_FAILURE;
}
-
-
+template <class Z> MY_INLINE
+CubitStatus RTree<Z>::find( const CubitVector &ray_origin, const CubitVector &ray_direction,
+ DLIList <Z> &range_members)
+{
+ //Find all of the members of the RTree that intersect this ray.
+ if ( myRoot == NULL )
+ {
+ // Nothing has been added to this Tree yet, so we are not going to find this
+ // object in it.
+ return CUBIT_SUCCESS;
+ }
+ CubitStatus stat = recursive_find(myRoot, ray_origin, ray_direction, range_members);
+ if ( stat != CUBIT_SUCCESS )
+ return CUBIT_FAILURE;
+ else
+ return CUBIT_SUCCESS;
+}
+
+template <class Z> MY_INLINE
+CubitStatus RTree<Z>::recursive_find(RTreeNode<Z> *rect_tree,
+ const CubitVector &ray_origin,
+ const CubitVector &ray_direction,
+ DLIList <Z> &range_members)
+{
+ CubitBox rect_box = rect_tree->bounding_box();
+ //if ( !range_box.overlap(myTolerance, rect_box ) )
+ if ( !rect_box.intersect(&ray_origin, &ray_direction) )
+ return CUBIT_SUCCESS;
+
+ //Now see if this is a data member. If it is, append the data to the
+ //list.
+ if (rect_tree->is_data() )
+ {
+ range_members.append(rect_tree->get_data());
+ return CUBIT_SUCCESS;
+ }
+ //Now if this is anything else we need to keep iterating...
+ int loop_size = rect_tree->num_children();
+ //We are doing a depth-first search of the tree. Not
+ //all branches will need to be followed since they won't
+ //all overlap...
+ int ii;
+ RTreeNode<Z> *curr_node;
+ CubitStatus stat;
+ for ( ii = 0; ii < loop_size; ii++ )
+ {
+ curr_node = rect_tree->get_child(ii);
+ if ( curr_node == NULL )
+ {
+ PRINT_ERROR("Problems finding boxes in range.\n");
+ assert(curr_node != NULL);
+ return CUBIT_FAILURE;
+ }
+ stat = recursive_find(curr_node, ray_origin, ray_direction, range_members);
+ if ( stat != CUBIT_SUCCESS )
+ return stat;
+ }
+
+ return CUBIT_SUCCESS;
+}
Modified: cgm/branches/cubit/util/RTree.hpp
===================================================================
--- cgm/branches/cubit/util/RTree.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/RTree.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -34,6 +34,13 @@
//- recurses down the rtree to find all all the data members
//- that fall in the range of the range_box.
+ CubitStatus recursive_find(RTreeNode<Z> *rect_tree,
+ const CubitVector &ray_origin,
+ const CubitVector &ray_direction,
+ DLIList <Z> &range_members);
+ //- recurses down the rtree to find all all the data members
+ //- that fall in the range of the ray.
+
void to_list(DLIList <RTreeNode<Z>*> &member_list,
RTreeNode<Z> *top);
//- converts the tree under top to a list. Note, top is NOT in the list
@@ -69,6 +76,11 @@
//- searches the range tree for members that intersect this range box
//- within the tolerance.
+ CubitStatus find( const CubitVector &ray_origin, const CubitVector &ray_direction,
+ DLIList <Z> &range_members);
+ //- searches the range tree for members that intersect this ray
+ //- within the tolerance.
+
CubitBoolean remove(Z data );
//- Remove the data member's entry in the rectangle tree.
//- Returns CUBIT_TRUE if item removed. FALSE if item not
Modified: cgm/branches/cubit/util/RandomMersenne.cpp
===================================================================
--- cgm/branches/cubit/util/RandomMersenne.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/RandomMersenne.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -133,7 +133,7 @@
#ifdef TEST_RANDOM
-#include <stdio.h>
+#include <cstdio>
int main(void)
{
Modified: cgm/branches/cubit/util/SDLList.cpp
===================================================================
--- cgm/branches/cubit/util/SDLList.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/SDLList.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -180,15 +180,12 @@
// move_to_item_sorted finds the index of the given value, then sets the
// current index there
-int SDLList::move_to_item_sorted(void* value)
+CubitBoolean SDLList::move_to_item_sorted(void* value)
{
int item_index;
CubitBoolean item_exists = where_is_item_sorted( value, item_index );
index = item_index; // always
- if ( item_exists ) {
- return CUBIT_TRUE;
- }
- return CUBIT_FALSE;
+ return item_exists;
}
Modified: cgm/branches/cubit/util/SDLList.hpp
===================================================================
--- cgm/branches/cubit/util/SDLList.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/SDLList.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -31,8 +31,8 @@
#include "DLList.hpp"
#include "CubitDefines.h"
#include "CubitMessage.hpp"
-#include <string.h>
-#include <assert.h>
+#include <cstring>
+#include <cassert>
#include "CubitUtilConfigure.h"
const int ORDER_ASCENDING = 0;
@@ -119,7 +119,7 @@
//- (depending on the assignment of compare_order function pointer). The
//- list is sorted using a standard Heap Sort algorithm.
- int move_to_item_sorted(void* value);
+ CubitBoolean move_to_item_sorted(void* value);
//- move_to_item_sorted performs a binary search on the list to locate
//- the item (object) that has functionType functionName() = value
//- (see SSDLListdeclare macro for description of functionType and
@@ -318,7 +318,7 @@
{ \
return (typePtr) move_to_and_remove_item_sorted((void*) &value); \
} \
- int move_to(typePtr objPtr) \
+ CubitBoolean move_to(typePtr objPtr) \
{ \
if (nullItem && ((typePtr) nullItem == objPtr)) \
return CUBIT_FALSE; \
@@ -329,7 +329,7 @@
return move_to_item_sorted((void*) &value); \
} \
} \
- int move_to(functionType value) \
+ CubitBoolean move_to(functionType value) \
{ \
return move_to_item_sorted((void*) &value); \
} \
Modified: cgm/branches/cubit/util/SettingHandler.cpp
===================================================================
--- cgm/branches/cubit/util/SettingHandler.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/SettingHandler.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -2,9 +2,9 @@
#pragma warning(disable : 4786)
#endif
-#include <assert.h>
-#include <stdio.h>
-#include <string.h>
+#include <cassert>
+#include <cstdio>
+#include <cstring>
#include <iostream>
@@ -57,7 +57,7 @@
mSettingsList.clear();
}
-void SettingHandler::add_setting(char* name, void (*setFn) (int),
+void SettingHandler::add_setting(const char* name, void (*setFn) (int),
int (*getFn)())
{
CubitString cs = name;
@@ -72,7 +72,7 @@
}
-void SettingHandler::add_setting(char* name, void (*setFn) (double),
+void SettingHandler::add_setting(const char* name, void (*setFn) (double),
double (*getFn)())
{
CubitString cs = name;
@@ -88,7 +88,7 @@
}
-void SettingHandler::add_setting(char* name, void (*setFn) (CubitBoolean),
+void SettingHandler::add_setting(const char* name, void (*setFn) (CubitBoolean),
CubitBoolean (*getFn)())
{
CubitString cs = name;
@@ -104,7 +104,7 @@
}
-void SettingHandler::add_setting(char* name, void (*setFn) (CubitString),
+void SettingHandler::add_setting(const char* name, void (*setFn) (CubitString),
CubitString (*getFn)())
{
CubitString cs = name;
@@ -219,7 +219,7 @@
void SettingHandler::save_settings()
{
- char* default_filename = "cubit.settings";
+ const char* default_filename = "cubit.settings";
FILE* file = fopen(default_filename, "w");
@@ -374,10 +374,19 @@
return (*(mSettingsList.find(name))).second;
}
-void SettingHandler::get_settings_list(std::map<CubitString, SettingHolder*> &list)
+void SettingHandler::get_settings_list(std::vector< std::pair<CubitString, SettingHolder*> > &list)
{
- // return a copy of the settings list
- list = mSettingsList;
+ // return a list of the settings
+ std::map<CubitString, SettingHolder*>::iterator iter = mSettingsList.begin();
+ while(iter != mSettingsList.end())
+ {
+ std::pair<CubitString, SettingHolder*> tmp_pair;
+ CubitString key = (*iter).first;
+ tmp_pair.first = key;
+ tmp_pair.second = (*iter).second;
+ list.push_back( (tmp_pair) );
+ iter++;
+ }
}
Modified: cgm/branches/cubit/util/SettingHandler.hpp
===================================================================
--- cgm/branches/cubit/util/SettingHandler.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/SettingHandler.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -11,6 +11,7 @@
#include "CubitDefines.h"
#include "SettingHolder.hpp"
#include <map>
+#include <vector>
#include "CubitUtilConfigure.h"
@@ -23,15 +24,15 @@
static void delete_instance(); //deletes instance if it exists
- void add_setting(char* name, void (*setFn) (int), int (*getFn)());
- void add_setting(char* name, void (*setFn) (double), double (*getFn)());
- void add_setting(char* name, void (*setFn) (CubitBoolean), CubitBoolean (*getFn)());
- void add_setting(char* name, void (*setFn) (CubitString), CubitString (*getFn)());
+ void add_setting(const char* name, void (*setFn) (int), int (*getFn)());
+ void add_setting(const char* name, void (*setFn) (double), double (*getFn)());
+ void add_setting(const char* name, void (*setFn) (CubitBoolean), CubitBoolean (*getFn)());
+ void add_setting(const char* name, void (*setFn) (CubitString), CubitString (*getFn)());
#ifdef BOYD15
int num_settings();
#endif
- void get_settings_list(std::map<CubitString, SettingHolder*> &list);
+ void get_settings_list( std::vector< std::pair<CubitString, SettingHolder*> > &list);
void print_settings(); // Output all settings using PRINT_INFO
void save_settings(const char *filename); //Save settings into a file specified by the user
Modified: cgm/branches/cubit/util/TextProgressTool.cpp
===================================================================
--- cgm/branches/cubit/util/TextProgressTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/TextProgressTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -1,4 +1,4 @@
-//#include "string.h"
+//#include "cstring"
#include "TextProgressTool.hpp"
#include "CubitMessage.hpp"
Modified: cgm/branches/cubit/util/ToolData.cpp
===================================================================
--- cgm/branches/cubit/util/ToolData.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/ToolData.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -10,4 +10,12 @@
// functions aren't inlined in a lot of cases where their address is
// taken.
+ToolData* ToolData::propogate(ToolDataUser* new_td_user)
+{
+ return NULL;
+}
+ToolData* ToolData::merge(ToolDataUser* other_td_user)
+{
+ return NULL;
+}
Modified: cgm/branches/cubit/util/ToolData.hpp
===================================================================
--- cgm/branches/cubit/util/ToolData.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/ToolData.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -11,8 +11,10 @@
#include "CubitDefines.h"
#include "CubitUtilConfigure.h"
-#include <assert.h>
+#include <cassert>
+class ToolDataUser;
+
class CUBIT_UTIL_EXPORT ToolData
{
private:
@@ -37,6 +39,19 @@
//- access to next tooldata in chain
// handy for ToolDataUser::delete_TD, see e.g. DoubletPillower.cc
+
+
+ virtual ToolData* propogate(ToolDataUser* new_td_user);
+ //- propogate() receives the ToolData User that has been copied or split off from the
+ //- ToolDataUser this TD is on and returns the ToolData that should be put on the new
+ //- ToolDataUser. If no new TD should be created, it returns NULL.
+
+ virtual ToolData* merge(ToolDataUser* other_td_user);
+ //- merge() receives a ToolDataUser that is about to be merged with the ToolDataUser that this
+ //- TD is on. It should process what should happen to this and any similar tooldata on the
+ //- other ToolDataUser and return the TD that should be assigned to the merged entity.
+ //- Note: ToolDataUser deletes any TD that is on it when itself is deleted. The calling function
+ //- should probably remove any TD returned by this function from the entities before deleting them.
};
// ********** BEGIN INLINE FUNCTIONS **********
Modified: cgm/branches/cubit/util/ToolDataUser.cpp
===================================================================
--- cgm/branches/cubit/util/ToolDataUser.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/ToolDataUser.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -1,6 +1,6 @@
// Class: ToolDataUser
-#include <assert.h>
+#include <cassert>
#include "ToolDataUser.hpp"
#include "ToolData.hpp"
#include "DLIList.hpp"
@@ -106,6 +106,15 @@
}
}
+void ToolDataUser::get_all_TDs(DLIList <ToolData *> *all_tds) const
+{
+ ToolData *td = tool_data();
+ while (td)
+ {
+ all_tds->append(td);
+ td = td->next_tool_data();
+ }
+}
ToolDataUser::~ToolDataUser()
{
Modified: cgm/branches/cubit/util/ToolDataUser.hpp
===================================================================
--- cgm/branches/cubit/util/ToolDataUser.hpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/ToolDataUser.hpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -44,29 +44,31 @@
virtual ~ToolDataUser();
//- automatically deletes all the chained ToolDatas
- CubitBoolean delete_TD(IdentityFn specified_type);
+ virtual CubitBoolean delete_TD(IdentityFn specified_type);
//- delete the specific type of tool data from the chain.
//- return true if something was actually found and deleted.
- CubitBoolean delete_TD(ToolData *td);
+ virtual CubitBoolean delete_TD(ToolData *td);
//- delete the specific tool data from the chain.
//- return true if something was actually found and deleted.
- ToolData *remove_TD(IdentityFn specified_type);
+ virtual ToolData *remove_TD(IdentityFn specified_type);
//- remove the specific type of tool data from the chain, and
//- return it.
- ToolData *remove_TD(ToolData *td);
+ virtual ToolData *remove_TD(ToolData *td);
//- remove the specific tool data from the chain, and
//- return it.
- void add_TD(ToolData *new_td);
+ virtual void add_TD(ToolData *new_td);
//- add the new_td to the beginning of the tool_data chain
virtual ToolData *get_TD(IdentityFn specified_type);
virtual ToolData const *get_TD(IdentityFn specified_type) const;
virtual void get_all_TDs(IdentityFn specified_type,
DLIList <ToolData *> *all_tds) const;
+
+ virtual void get_all_TDs(DLIList <ToolData *> *all_tds) const;
//- get the specific type of ToolData in the chain.
//- returns null if not found.
Modified: cgm/branches/cubit/util/TtyProgressTool.cpp
===================================================================
--- cgm/branches/cubit/util/TtyProgressTool.cpp 2009-12-22 20:36:06 UTC (rev 3422)
+++ cgm/branches/cubit/util/TtyProgressTool.cpp 2010-01-06 19:22:14 UTC (rev 3423)
@@ -12,7 +12,7 @@
#ifndef NT
# include <unistd.h>
#endif
-#include <string.h>
+#include <cstring>
#include "AppUtil.hpp"
#include "TtyProgressTool.hpp"
#include "CubitUtil.hpp"
More information about the cgma-dev
mailing list