Added mesh module

parent 25f35ef4
Pipeline #6342 passed with stage
in 114 minutes and 47 seconds
......@@ -930,6 +930,9 @@ if( (NOT DEFINED WALBERLA_BUILD_WITH_OPENMESH) OR WALBERLA_BUILD_WITH_OPENMESH )
set( WALBERLA_BUILD_WITH_OPENMESH ON CACHE BOOL "Build with OpenMesh support" )
include_directories( SYSTEM ${OPENMESH_INCLUDE_DIRS} )
list( APPEND SERVICE_LIBS ${OPENMESH_LIBRARIES} )
if( WALBERLA_CXX_COMPILER_IS_MSVC )
add_definitions(-D_USE_MATH_DEFINES )
endif()
else()
set( WALBERLA_BUILD_WITH_OPENMESH OFF CACHE BOOL "Build with OpenMesh support" FORCE )
endif()
......
add_subdirectory( ComplexGeometry )
add_subdirectory( MeshDistance )
add_subdirectory( CouetteFlow )
add_subdirectory( ForcesOnSphereNearPlaneInShearFlow )
add_subdirectory( NonUniformGrid )
......
if ( WALBERLA_BUILD_WITH_OPENMESH )
waLBerla_link_files_to_builddir( "*.obj" )
waLBerla_link_files_to_builddir( "*.conf" )
waLBerla_add_executable( NAME ComplexGeometry FILES ComplexGeometry.cpp DEPENDS boundary core lbm mesh vtk )
##############
# Some tests #
##############
waLBerla_execute_test( NO_MODULE_LABEL NAME ComplexGeometry COMMAND $<TARGET_FILE:ComplexGeometry> test.conf DEPENDS_ON_TARGETS ComplexGeometry )
endif()
This diff is collapsed.
This diff is collapsed.
####
#
# OBJ File Generated by Meshlab
#
####
# Object cube.obj
#
# Vertices: 8
# Faces: 12
#
####
v 0.000000 0.000000 0.000000
v 0.000000 0.000000 1.000000
v 0.000000 1.000000 1.000000
v 0.000000 1.000000 0.000000
v 1.000000 0.000000 0.000000
v 1.000000 0.000000 1.000000
v 1.000000 1.000000 1.000000
v 1.000000 1.000000 0.000000
# 8 vertices, 0 vertices normals
f 1 2 3
f 1 3 4
f 8 7 6
f 8 6 5
f 1 5 6
f 1 6 2
f 2 6 7
f 2 7 3
f 3 7 8
f 3 8 4
f 4 8 5
f 4 5 1
# 12 faces, 0 coords texture
# End of File
\ No newline at end of file
ComplexGeometry
{
meshFile bunny.obj;
coarseDx 4;
coarseOmega 1.6;
coarseTimeSteps 1001;
numLevels 3;
bodyForce <0.0001, 0, 0>;
blockSize <16,16,16>;
domainBlowUp <5,5,5>; // simulation domain is blow up factor times mesh size per dimension
}
VTK {
fluid // identifier for this VTKOutput object
{
writeFrequency 100;
inclusion_filters
{
DomainFilter;
}
writers
{
Velocity;
Density;
}
}
flags // identifier for this VTKOutput object
{
writeFrequency 999999999999999; //once!
writers
{
FlagField;
}
}
domain_decomposition // identifier for this VTKOutput object
{
writeFrequency 999999999999999; //once!
outputDomainDecomposition true;
}
}
\ No newline at end of file
####
#
# OBJ File Generated by Meshlab
#
####
# Object sphere.obj
#
# Vertices: 52
# Faces: 100
#
####
vn 3.203486 0.106207 4.556782
v 0.589717 0.013032 0.847959 0.752941 0.752941 0.752941
vn 5.019849 1.775524 1.684732
v 0.919162 0.323653 0.317881 0.752941 0.752941 0.752941
vn 2.435736 2.603171 4.338618
v 0.454446 0.492016 0.779993 0.752941 0.752941 0.752941
vn 1.166519 4.432512 3.718873
v 0.245629 0.761303 0.617920 0.752941 0.752941 0.752941
vn 3.325176 4.334585 2.054782
v 0.568591 0.771892 0.343297 0.752941 0.752941 0.752941
vn 0.595211 5.541665 1.103712
v 0.110726 0.991360 0.237197 0.752941 0.752941 0.752941
vn -3.776296 0.767626 4.266579
v -0.688569 0.139508 0.738187 0.000000 1.000000 0.000000
vn -1.312800 2.808851 4.706018
v -0.270132 0.525142 0.837286 0.000000 1.000000 0.000000
vn -3.673248 3.342919 3.246579
v -0.616965 0.568913 0.559955 0.000000 1.000000 0.000000
vn -5.184217 1.765921 1.597865
v -0.913888 0.321159 0.322155 0.000000 1.000000 0.000000
vn -1.576481 4.921260 2.246386
v -0.288050 0.891505 0.427122 0.000000 1.000000 0.000000
vn -3.631493 4.235586 0.210513
v -0.677783 0.771802 0.054808 0.000000 1.000000 0.000000
vn 5.347003 -0.730677 2.243891
v 0.939495 -0.137963 0.353373 0.752941 0.752941 0.752941
vn 3.090607 -2.164615 4.376353
v 0.564054 -0.405378 0.749705 0.752941 0.752941 0.752941
vn 4.139648 -3.083573 2.833979
v 0.686938 -0.535204 0.519371 0.752941 0.752941 0.752941
vn 5.547247 -1.363092 0.328926
v 0.988626 -0.269261 0.045694 0.752941 0.752941 0.752941
vn 1.196453 -3.595379 4.241168
v 0.225855 -0.666498 0.743600 0.752941 0.752941 0.752941
vn 3.440788 -4.400445 1.622125
v 0.605470 -0.764079 0.286901 0.752941 0.752941 0.752941
vn 1.483118 -5.448192 -0.612228
v 0.268689 -0.989603 -0.074576 0.752941 0.752941 0.752941
vn -5.131380 -1.139949 2.118813
v -0.938366 -0.205491 0.365196 0.000000 1.000000 0.000000
vn -0.148252 -0.090956 5.329934
v -0.029807 -0.012393 1.044330 0.752941 0.752941 0.752941
vn -2.941041 -1.873027 4.366208
v -0.544021 -0.347070 0.802954 0.752941 0.752941 0.752941
vn -4.510469 -3.611316 0.273923
v -0.799559 -0.630144 0.056333 0.752941 0.752941 0.752941
vn -1.222675 -3.813472 4.059360
v -0.223449 -0.686099 0.721907 0.752941 0.752941 0.752941
vn -3.177381 -4.314878 2.055289
v -0.568591 -0.771892 0.343297 0.752941 0.752941 0.752941
vn 0.555067 -5.357186 2.097567
v 0.103775 -0.959491 0.337408 0.752941 0.752941 0.752941
vn -1.424179 -5.441336 0.261796
v -0.242174 -0.999619 0.061062 0.752941 0.752941 0.752941
vn 0.603496 0.876270 -5.566095
v 0.094800 0.183733 -1.001620 0.752941 0.752941 0.752941
vn 3.764494 0.845602 -4.219594
v 0.688569 0.139508 -0.738187 0.752941 0.752941 0.752941
vn 1.567199 2.909075 -4.657190
v 0.270132 0.525142 -0.837286 0.752941 0.752941 0.752941
vn 3.565448 3.772605 -2.549637
v 0.615553 0.702721 -0.424646 0.752941 0.752941 0.752941
vn 5.162828 1.763767 -1.614322
v 0.913888 0.321159 -0.322155 0.752941 0.752941 0.752941
vn 1.324314 5.031288 -2.331577
v 0.253180 0.897558 -0.437313 0.752941 0.752941 0.752941
vn 3.629731 4.384550 -0.093890
v 0.650335 0.795689 -0.024263 0.752941 0.752941 0.752941
vn -4.043519 0.309797 -4.155685
v -0.705153 0.056764 -0.729210 0.000000 1.000000 0.000000
vn -2.307409 1.462065 -5.138504
v -0.415375 0.253185 -0.890210 0.752941 0.752941 0.752941
vn -3.353315 3.567168 -2.854749
v -0.600441 0.642788 -0.533812 0.000000 1.000000 0.000000
vn -5.130730 1.780599 -1.582083
v -0.919162 0.323653 -0.317881 0.000000 1.000000 0.000000
vn -1.144898 3.843270 -4.171122
v -0.223449 0.686099 -0.721907 0.752941 0.752941 0.752941
vn -0.991535 5.441091 -1.454840
v -0.143287 0.963273 -0.301638 0.000000 1.000000 0.000000
vn 5.131380 -1.139949 -2.118813
v 0.938366 -0.205491 -0.365196 0.752941 0.752941 0.752941
vn 2.875490 -1.819046 -4.391660
v 0.544021 -0.347070 -0.802954 0.752941 0.752941 0.752941
vn 4.525778 -3.601130 -0.274730
v 0.799559 -0.630144 -0.056333 0.752941 0.752941 0.752941
vn 1.250127 -3.837570 -4.049940
v 0.223449 -0.686099 -0.721907 0.752941 0.752941 0.752941
vn 3.198936 -4.303796 -2.086038
v 0.568591 -0.771892 -0.343297 0.752941 0.752941 0.752941
vn -0.857578 -1.469198 -5.294847
v -0.187308 -0.267522 -0.979869 0.752941 0.752941 0.752941
vn -3.158328 -2.247927 -4.280213
v -0.564054 -0.405378 -0.749705 0.752941 0.752941 0.752941
vn -5.397189 -0.800014 -2.176419
v -0.939495 -0.137963 -0.353373 0.000000 1.000000 0.000000
vn -4.099356 -3.088730 -2.858676
v -0.686938 -0.535204 -0.519371 0.752941 0.752941 0.752941
vn -5.547246 -1.363092 -0.328926
v -0.988626 -0.269261 -0.045694 0.000000 1.000000 0.000000
vn -3.407609 -4.424288 -1.578537
v -0.605470 -0.764079 -0.286901 0.752941 0.752941 0.752941
vn -0.843019 -4.558556 -3.151353
v -0.153857 -0.826487 -0.592781 0.752941 0.752941 0.752941
# 52 vertices, 0 vertices normals
f 16//16 2//2 13//13
f 16//16 32//32 2//2
f 2//2 3//3 1//1
f 1//1 3//3 21//21
f 21//21 3//3 8//8
f 2//2 5//5 3//3
f 2//2 34//34 5//5
f 3//3 5//5 4//4
f 3//3 4//4 8//8
f 5//5 6//6 4//4
f 4//4 6//6 11//11
f 5//5 34//34 6//6
f 34//34 33//33 6//6
f 22//22 21//21 7//7
f 7//7 10//10 20//20
f 20//20 10//10 50//50
f 7//7 21//21 8//8
f 7//7 8//8 9//9
f 7//7 9//9 10//10
f 10//10 9//9 12//12
f 10//10 12//12 38//38
f 8//8 11//11 9//9
f 9//9 11//11 12//12
f 8//8 4//4 11//11
f 1//1 13//13 2//2
f 1//1 14//14 13//13
f 1//1 21//21 14//14
f 14//14 15//15 13//13
f 13//13 15//15 16//16
f 21//21 17//17 14//14
f 15//15 18//18 16//16
f 16//16 18//18 43//43
f 14//14 17//17 15//15
f 15//15 17//17 18//18
f 17//17 24//24 26//26
f 17//17 26//26 18//18
f 18//18 19//19 43//43
f 18//18 26//26 19//19
f 7//7 20//20 22//22
f 50//50 23//23 20//20
f 22//22 24//24 21//21
f 21//21 24//24 17//17
f 23//23 25//25 20//20
f 20//20 25//25 22//22
f 22//22 25//25 24//24
f 23//23 27//27 25//25
f 25//25 27//27 24//24
f 24//24 27//27 26//26
f 42//42 28//28 29//29
f 29//29 32//32 41//41
f 41//41 32//32 16//16
f 29//29 28//28 30//30
f 29//29 30//30 31//31
f 29//29 31//31 32//32
f 32//32 31//31 34//34
f 32//32 34//34 2//2
f 30//30 33//33 31//31
f 30//30 39//39 33//33
f 31//31 33//33 34//34
f 33//33 40//40 6//6
f 50//50 38//38 48//48
f 36//36 28//28 46//46
f 50//50 10//10 38//38
f 38//38 37//37 35//35
f 35//35 37//37 36//36
f 36//36 37//37 39//39
f 36//36 39//39 28//28
f 28//28 39//39 30//30
f 38//38 12//12 37//37
f 37//37 12//12 40//40
f 37//37 40//40 39//39
f 39//39 40//40 33//33
f 12//12 11//11 40//40
f 40//40 11//11 6//6
f 29//29 41//41 42//42
f 42//42 46//46 28//28
f 16//16 43//43 41//41
f 42//42 44//44 46//46
f 43//43 45//45 41//41
f 41//41 45//45 42//42
f 42//42 45//45 44//44
f 44//44 52//52 46//46
f 43//43 19//19 45//45
f 45//45 19//19 44//44
f 44//44 19//19 52//52
f 19//19 26//26 27//27
f 36//36 46//46 35//35
f 35//35 48//48 38//38
f 35//35 46//46 47//47
f 35//35 47//47 48//48
f 47//47 49//49 48//48
f 48//48 49//49 50//50
f 49//49 51//51 50//50
f 50//50 51//51 23//23
f 46//46 52//52 47//47
f 47//47 52//52 49//49
f 49//49 52//52 51//51
f 51//51 27//27 23//23
f 52//52 27//27 51//51
f 52//52 19//19 27//27
# 100 faces, 0 coords texture
# End of File
\ No newline at end of file
ComplexGeometry
{
meshFile cube.obj;
coarseDx 0.2;
coarseOmega 1.6;
coarseTimeSteps 1;
numLevels 2;
bodyForce <0.0001, 0, 0>;
blockSize <8,8,8>;
domainBlowUp <5,5,5>; // simulation domain is blow up factor times mesh size per dimension
Boundaries {
}
}
VTK {
fluid // identifier for this VTKOutput object
{
writeFrequency 100;
inclusion_filters
{
DomainFilter;
}
writers
{
Velocity;
Density;
}
}
flags // identifier for this VTKOutput object
{
writeFrequency 999999999999999; //once!
writers
{
FlagField;
}
}
domain_decomposition // identifier for this VTKOutput object
{
writeFrequency 999999999999999; //once!
outputDomainDecomposition true;
}
}
\ No newline at end of file
if ( WALBERLA_BUILD_WITH_OPENMESH )
waLBerla_link_files_to_builddir( "*.obj" )
waLBerla_add_executable( NAME MeshDistanceBenchmark DEPENDS core mesh )
##############
# Some tests #
##############
waLBerla_execute_test( NO_MODULE_LABEL NAME MeshDistanceBenchmark COMMAND $<TARGET_FILE:MeshDistanceBenchmark> bunny.obj 10 2 )
endif()
//======================================================================================================================
//
// This file is part of waLBerla. waLBerla is free software: you can
// redistribute it and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// waLBerla is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
//
//! \file MeshDistanceOctreeTest.cpp
//! \ingroup mesh
//! \author Christian Godenschwager <christian.godenschwager@fau.de>
//
//======================================================================================================================
#include "core/debug/TestSubsystem.h"
#include "core/logging/Logging.h"
#include "core/mpi/Environment.h"
#include "core/timing/Timer.h"
#include "geometry/containment_octree/ContainmentOctree.h"
#include "geometry/mesh/TriangleMesh.h"
#include "geometry/mesh/TriangleMeshIO.h"
#include "mesh/TriangleMeshes.h"
#include "mesh/MeshOperations.h"
#include "mesh/DistanceComputations.h"
#include "mesh/distance_octree/DistanceOctree.h"
#include "mesh/MeshIO.h"
#include <boost/random.hpp>
#include <algorithm>
#include <vector>
#include <string>
namespace mesh_distance_benchmark {
using namespace walberla;
template< typename MeshType >
void runBenchmark( const std::string & meshFile, const uint_t numPoints, const uint_t numRepetitions, const bool testBruteForce )
{
auto mesh = make_shared<MeshType>();;
mesh::readAndBroadcast( meshFile, *mesh);
auto aabb = computeAABB( *mesh );
WALBERLA_LOG_INFO( "Mesh has " << mesh->n_faces() << " triangles" );
WALBERLA_LOG_INFO( "Testing " << numPoints << " Points with " << numRepetitions << " repetitions" )
auto testVolume = aabb.getScaled( typename MeshType::Point::value_type(1.2) ); // AABB containing the test points
WcTimer timer;
WALBERLA_LOG_INFO( "Preparing mesh for distance computations..." );
timer.start();
auto triDist = make_shared< mesh::TriangleDistance<MeshType> >( mesh );
timer.end();
WALBERLA_LOG_INFO( "Mesh preparation took " << timer.last() << "s" );
boost::random::mt19937 rng;
std::vector< typename MeshType::Point > points( numPoints );
for(auto it = points.begin(); it != points.end(); ++it)
{
*it = mesh::toOpenMesh( testVolume.randomPoint( rng ) );
}
if( testBruteForce )
{
WALBERLA_LOG_INFO( "Testing brute force distance computation..." );
timer.reset();
for( uint_t i = 0; i < numRepetitions; ++i )
{
timer.start();
for(auto it = points.begin(); it != points.end(); ++it)
{
triDist->sqSignedDistance( *it );
}
timer.end();
}
WALBERLA_LOG_INFO( "Brute force distance computation took " << timer.min() << "s" );
WALBERLA_LOG_INFO( real_c(points.size()) / timer.min() << " points / s" );
}
WALBERLA_LOG_INFO( "Building distance octree..." );
timer.reset();
timer.start();
mesh::DistanceOctree<MeshType> distanceOctree( triDist );
timer.end();
WALBERLA_LOG_INFO( "Building octree took " << timer.last() << "s" );
WALBERLA_LOG_INFO( "Distance octree has height " << distanceOctree.height() );
WALBERLA_LOG_INFO( "Testing octree distance computation..." );
timer.reset();
for( uint_t i = 0; i < numRepetitions; ++i )
{
timer.start();
for(auto it = points.begin(); it != points.end(); ++it)
{
distanceOctree.sqSignedDistance( *it );
}
timer.end();
}
WALBERLA_LOG_INFO( "Octree distance computation took " << timer.min() << "s" );
WALBERLA_LOG_INFO( real_c( points.size() ) / timer.min() << " points / s" );
WALBERLA_LOG_INFO( "Building containment octree..." );
timer.reset();
timer.start();
geometry::ContainmentOctree< mesh::DistanceOctree<MeshType> > containmentOctree( make_shared<mesh::DistanceOctree<MeshType>>( distanceOctree ) );
timer.end();
WALBERLA_LOG_INFO( "Building octree took " << timer.last() << "s" );
WALBERLA_LOG_INFO( "Containment octree has height " << containmentOctree.height() );
WALBERLA_LOG_INFO( "Testing octree containment computation..." );
timer.reset();
for( uint_t i = 0; i < numRepetitions; ++i )
{
timer.start();
for(auto it = points.begin(); it != points.end(); ++it)
{
containmentOctree.contains( *it );
}
timer.end();
}
WALBERLA_LOG_INFO( "Octree containment computation took " << timer.min() << "s" );
WALBERLA_LOG_INFO( real_c( points.size() ) / timer.min() << " points / s" );
}
int main( int argc, char * argv[] )
{
debug::enterTestMode();
mpi::Environment mpiEnv( argc, argv );
mpi::MPIManager::instance()->useWorldComm();
std::vector<std::string> args( argv, argv + argc );
bool testBruteForce = true;
auto argIt = std::find( args.begin(), args.end(), std::string("--no-brute-force") );
if( argIt != args.end() )
{
testBruteForce = false;
args.erase( argIt );
}
bool forceFloat = false;
argIt = std::find( args.begin(), args.end(), std::string("--force-float") );
if( argIt != args.end() )
{
forceFloat = true;
args.erase( argIt );
}
if( args.size() != 4 )
WALBERLA_ABORT_NO_DEBUG_INFO( "USAGE: " << args[0] << " [--no-brute-force] [--force-float] MESH_FILE NUM_POINTS NUM_REPETITIONS" );
const std::string & meshFile = args[1];
const uint_t numPoints = boost::lexical_cast<uint_t>( args[2] );
const uint_t numRepetitions = boost::lexical_cast<uint_t>( args[3] );
if(forceFloat)
{
runBenchmark< mesh::FloatTriangleMesh >( meshFile, numPoints, numRepetitions, testBruteForce );
}
else
{
runBenchmark< mesh::TriangleMesh >( meshFile, numPoints, numRepetitions, testBruteForce );
}
return EXIT_SUCCESS;
}
} // namespace mesh_distance_benchmark
int main( int argc, char * argv[] )
{
return mesh_distance_benchmark::main( argc, argv );
}
\ No newline at end of file
This diff is collapsed.
......@@ -8,6 +8,10 @@ if ( WALBERLA_BUILD_WITH_PYTHON_MODULE )
set(PYTHON_MODULE_DEPENDENCIES ${PYTHON_MODULE_DEPENDENCIES} cuda)
endif()
if (WALBERLA_BUILD_WITH_OPENMESH)
set(PYTHON_MODULE_DEPENDENCIES ${PYTHON_MODULE_DEPENDENCIES} mesh)
endif()
if( WALBERLA_CXX_COMPILER_IS_MSVC )
set ( pythonModules ${PYTHON_MODULE_DEPENDENCIES})
elseif( APPLE )
......
......@@ -22,6 +22,7 @@
#include "blockforest/python/Exports.h"
#include "field/GhostLayerField.h"
#include "field/python/Exports.h"
#include "mesh/python/Exports.h"
#include "geometry/python/Exports.h"
#include "postprocessing/python/Exports.h"
#include "python_coupling/Manager.h"
......@@ -116,6 +117,10 @@ struct InitObject
// Timeloop
pythonManager->addExporterFunction( timeloop::exportModuleToPython );
#ifdef WALBERLA_BUILD_WITH_OPENMESH
pythonManager->addExporterFunction( mesh::exportModuleToPython<FlagFieldTypes> );
#endif
#ifdef WALBERLA_BUILD_WITH_CUDA
using walberla::cuda::GPUField;
typedef bmpl::vector<GPUField<double>, GPUField<float>, GPUField<int>, GPUField<uint8_t>, GPUField<uint16_t> > GPUFields;
......
......@@ -336,7 +336,7 @@ function ( waLBerla_execute_test )
set( options NO_MODULE_LABEL )
set( oneValueArgs NAME PROCESSES )
set( multiValueArgs COMMAND LABELS CONFIGURATIONS )
set( multiValueArgs COMMAND LABELS CONFIGURATIONS DEPENDS_ON_TARGETS )
cmake_parse_arguments( ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
if( NOT ARG_NAME )
......@@ -344,9 +344,16 @@ function ( waLBerla_execute_test )
endif()
if( NOT ARG_COMMAND AND NOT TARGET ${ARG_NAME} )
message ( STATUS "Skipping ${ARG_NAME} since the corresponding test was not built" )
message ( STATUS "Skipping test ${ARG_NAME} since the corresponding target is not built" )
return()
endif()
endif()
foreach( dependency_target ${ARG_DEPENDS_ON_TARGETS} )
if( NOT TARGET ${dependency_target} )
message ( STATUS "Skipping test ${ARG_NAME} since the target ${dependency_target} is not built" )
return()
endif()
endforeach( dependency_target )
if( NOT ARG_PROCESSES )
set ( numProcesses 1 )
......
This diff is collapsed.
......@@ -172,3 +172,26 @@
pages = {519--581},
owner = {mkuron},
}
@Article{Baerentzen2005,
author = {J. A. Baerentzen and H. Aanaes},
title = {Signed distance computation using the angle weighted pseudonormal},
journal = {IEEE Transactions on Visualization and Computer Graphics},
year = {2005},
volume = {11},
number = {3},
pages = {243-253},
month = {May},
doi = {10.1109/TVCG.2005.49},
issn = {1077-2626},
keywords = {computational geometry;mesh generation;angle weighted pseudonormal;polyhedron;signed distance computation;smooth surfaces;triangle mesh;Geometry;Robustness;Index Terms- Mesh;normal;polyhedron.;pseudonormal;signed distance field;Algorithms;Computer Graphics;Computer Simulation;Image Enhancement;Image Interpretation, Computer-Assisted;Imaging, Three-Dimensional;Information Storage and Retrieval;Numerical Analysis, Computer-Assisted;Pattern Recognition, Automated;Signal Processing, Computer-Assisted},
}
@Article{Jones1995,
author = {Jones, Mark W},
title = {3D distance from a point to a triangle},
journal = {Department of Computer Science, University of Wales Swansea Technical Report CSR-5},
year = {1995},
}