use convhull_3d for quicker hull calculation
This commit is contained in:
parent
1191f54ef4
commit
736f89026f
|
|
@ -81,30 +81,6 @@ void convhull_3d_build(/* input arguments */
|
||||||
int** out_faces, /* & of empty int*, output face indices; flat: nOut_faces x 3 */
|
int** out_faces, /* & of empty int*, output face indices; flat: nOut_faces x 3 */
|
||||||
int* nOut_faces); /* & of int, number of output face indices */
|
int* nOut_faces); /* & of int, number of output face indices */
|
||||||
|
|
||||||
/* exports the vertices, face indices, and face normals, as an 'obj' file, ready for GPU */
|
|
||||||
void convhull_3d_export_obj(/* input arguments */
|
|
||||||
ch_vertex* const vertices, /* vector of input vertices; nVert x 1 */
|
|
||||||
const int nVert, /* number of vertices */
|
|
||||||
int* const faces, /* face indices; flat: nFaces x 3 */
|
|
||||||
const int nFaces, /* number of faces in hull */
|
|
||||||
const int keepOnlyUsedVerticesFLAG, /* 0: exports in_vertices, 1: exports only used vertices */
|
|
||||||
char* const obj_filename); /* obj filename, WITHOUT extension */
|
|
||||||
|
|
||||||
/* exports the vertices, face indices, and face normals, as an 'm' file, for MatLab verification */
|
|
||||||
void convhull_3d_export_m(/* input arguments */
|
|
||||||
ch_vertex* const vertices, /* vector of input vertices; nVert x 1 */
|
|
||||||
const int nVert, /* number of vertices */
|
|
||||||
int* const faces, /* face indices; flat: nFaces x 3 */
|
|
||||||
const int nFaces, /* number of faces in hull */
|
|
||||||
char* const m_filename); /* m filename, WITHOUT extension */
|
|
||||||
|
|
||||||
/* reads an 'obj' file and extracts only the vertices */
|
|
||||||
void extractVerticesFromObjFile(/* input arguments */
|
|
||||||
char* const obj_filename, /* obj filename, WITHOUT extension */
|
|
||||||
/* output arguments */
|
|
||||||
ch_vertex** out_vertices, /* & of empty ch_vertex*, output vertices; out_nVert x 1 */
|
|
||||||
int* out_nVert); /* & of int, number of vertices */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /*extern "C"*/
|
} /*extern "C"*/
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -116,22 +92,11 @@ void extractVerticesFromObjFile(/* input arguments */
|
||||||
* INTERNAL:
|
* INTERNAL:
|
||||||
***********/
|
***********/
|
||||||
|
|
||||||
#ifdef CONVHULL_3D_ENABLE
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
|
||||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
|
|
||||||
#define CV_STRNCPY(a,b,c) strncpy_s(a,c+1,b,c);
|
|
||||||
#define CV_STRCAT(a,b) strcat_s(a,sizeof(b),b);
|
|
||||||
#else
|
|
||||||
#define CV_STRNCPY(a,b,c) strncpy(a,b,c);
|
|
||||||
#define CV_STRCAT(a,b) strcat(a,b);
|
|
||||||
#endif
|
|
||||||
#ifdef CONVHULL_3D_USE_FLOAT_PRECISION
|
#ifdef CONVHULL_3D_USE_FLOAT_PRECISION
|
||||||
#define CH_FLT_MIN FLT_MIN
|
#define CH_FLT_MIN FLT_MIN
|
||||||
#define CH_FLT_MAX FLT_MAX
|
#define CH_FLT_MAX FLT_MAX
|
||||||
|
|
@ -167,39 +132,38 @@ static int cmp_asc_int(const void*, const void*);
|
||||||
static int cmp_desc_int(const void*, const void*);
|
static int cmp_desc_int(const void*, const void*);
|
||||||
static void sort_float(CH_FLOAT*, CH_FLOAT*, int*, int, int);
|
static void sort_float(CH_FLOAT*, CH_FLOAT*, int*, int, int);
|
||||||
static void sort_int(int*, int*, int*, int, int);
|
static void sort_int(int*, int*, int*, int, int);
|
||||||
static ch_vec3 cross(ch_vec3*, ch_vec3*);
|
|
||||||
static CH_FLOAT det_4x4(CH_FLOAT*);
|
static CH_FLOAT det_4x4(CH_FLOAT*);
|
||||||
static void plane_3d(CH_FLOAT*, CH_FLOAT*, CH_FLOAT*);
|
static void plane_3d(CH_FLOAT*, CH_FLOAT*, CH_FLOAT*);
|
||||||
static void ismember(int*, int*, int*, int, int);
|
static void ismember(int*, int*, int*, int, int);
|
||||||
|
|
||||||
/* internal functions definitions: */
|
/* internal functions definitions: */
|
||||||
static int cmp_asc_float(const void *a,const void *b) {
|
static int cmp_asc_float(const void *a,const void *b) {
|
||||||
struct float_w_idx *a1 = (struct float_w_idx*)a;
|
const struct float_w_idx *a1 = (const struct float_w_idx*)a;
|
||||||
struct float_w_idx *a2 = (struct float_w_idx*)b;
|
const struct float_w_idx *a2 = (const struct float_w_idx*)b;
|
||||||
if((*a1).val<(*a2).val)return -1;
|
if((*a1).val<(*a2).val)return -1;
|
||||||
else if((*a1).val>(*a2).val)return 1;
|
else if((*a1).val>(*a2).val)return 1;
|
||||||
else return 0;
|
else return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmp_desc_float(const void *a,const void *b) {
|
static int cmp_desc_float(const void *a,const void *b) {
|
||||||
struct float_w_idx *a1 = (struct float_w_idx*)a;
|
const struct float_w_idx *a1 = (const struct float_w_idx*)a;
|
||||||
struct float_w_idx *a2 = (struct float_w_idx*)b;
|
const struct float_w_idx *a2 = (const struct float_w_idx*)b;
|
||||||
if((*a1).val>(*a2).val)return -1;
|
if((*a1).val>(*a2).val)return -1;
|
||||||
else if((*a1).val<(*a2).val)return 1;
|
else if((*a1).val<(*a2).val)return 1;
|
||||||
else return 0;
|
else return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmp_asc_int(const void *a,const void *b) {
|
static int cmp_asc_int(const void *a,const void *b) {
|
||||||
struct int_w_idx *a1 = (struct int_w_idx*)a;
|
const struct int_w_idx *a1 = (const struct int_w_idx*)a;
|
||||||
struct int_w_idx *a2 = (struct int_w_idx*)b;
|
const struct int_w_idx *a2 = (const struct int_w_idx*)b;
|
||||||
if((*a1).val<(*a2).val)return -1;
|
if((*a1).val<(*a2).val)return -1;
|
||||||
else if((*a1).val>(*a2).val)return 1;
|
else if((*a1).val>(*a2).val)return 1;
|
||||||
else return 0;
|
else return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmp_desc_int(const void *a,const void *b) {
|
static int cmp_desc_int(const void *a,const void *b) {
|
||||||
struct int_w_idx *a1 = (struct int_w_idx*)a;
|
const struct int_w_idx *a1 = (const struct int_w_idx*)a;
|
||||||
struct int_w_idx *a2 = (struct int_w_idx*)b;
|
const struct int_w_idx *a2 = (const struct int_w_idx*)b;
|
||||||
if((*a1).val>(*a2).val)return -1;
|
if((*a1).val>(*a2).val)return -1;
|
||||||
else if((*a1).val<(*a2).val)return 1;
|
else if((*a1).val<(*a2).val)return 1;
|
||||||
else return 0;
|
else return 0;
|
||||||
|
|
@ -269,15 +233,6 @@ static void sort_int
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ch_vec3 cross(ch_vec3* v1, ch_vec3* v2)
|
|
||||||
{
|
|
||||||
ch_vec3 cross;
|
|
||||||
cross.x = v1->y * v2->z - v1->z * v2->y;
|
|
||||||
cross.y = v1->z * v2->x - v1->x * v2->z;
|
|
||||||
cross.z = v1->x * v2->y - v1->y * v2->x;
|
|
||||||
return cross;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* calculates the determinent of a 4x4 matrix */
|
/* calculates the determinent of a 4x4 matrix */
|
||||||
static CH_FLOAT det_4x4(CH_FLOAT* m) {
|
static CH_FLOAT det_4x4(CH_FLOAT* m) {
|
||||||
return
|
return
|
||||||
|
|
@ -819,178 +774,5 @@ void convhull_3d_build
|
||||||
free(A);
|
free(A);
|
||||||
}
|
}
|
||||||
|
|
||||||
void convhull_3d_export_obj
|
|
||||||
(
|
|
||||||
ch_vertex* const vertices,
|
|
||||||
const int nVert,
|
|
||||||
int* const faces,
|
|
||||||
const int nFaces,
|
|
||||||
const int keepOnlyUsedVerticesFLAG,
|
|
||||||
char* const obj_filename
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
char path[256] = "\0";
|
|
||||||
CV_STRNCPY(path, obj_filename, strlen(obj_filename));
|
|
||||||
FILE* obj_file;
|
|
||||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
|
|
||||||
CV_STRCAT(path, ".obj");
|
|
||||||
fopen_s(&obj_file, path, "wt");
|
|
||||||
#else
|
|
||||||
obj_file = fopen(strcat(path, ".obj"), "wt");
|
|
||||||
#endif
|
|
||||||
fprintf(obj_file, "o\n");
|
|
||||||
CH_FLOAT scale;
|
|
||||||
ch_vec3 v1, v2, normal;
|
|
||||||
|
|
||||||
/* export vertices */
|
|
||||||
if(keepOnlyUsedVerticesFLAG){
|
|
||||||
for (i = 0; i < nFaces; i++)
|
|
||||||
for(j=0; j<3; j++)
|
|
||||||
fprintf(obj_file, "v %f %f %f\n", vertices[faces[i*3+j]].x,
|
|
||||||
vertices[faces[i*3+j]].y, vertices[faces[i*3+j]].z);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (i = 0; i < nVert; i++)
|
|
||||||
fprintf(obj_file, "v %f %f %f\n", vertices[i].x,
|
|
||||||
vertices[i].y, vertices[i].z);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* export the face normals */
|
|
||||||
for (i = 0; i < nFaces; i++){
|
|
||||||
/* calculate cross product between v1-v0 and v2-v0 */
|
|
||||||
v1 = vertices[faces[i*3+1]];
|
|
||||||
v2 = vertices[faces[i*3+2]];
|
|
||||||
v1.x -= vertices[faces[i*3]].x;
|
|
||||||
v1.y -= vertices[faces[i*3]].y;
|
|
||||||
v1.z -= vertices[faces[i*3]].z;
|
|
||||||
v2.x -= vertices[faces[i*3]].x;
|
|
||||||
v2.y -= vertices[faces[i*3]].y;
|
|
||||||
v2.z -= vertices[faces[i*3]].z;
|
|
||||||
normal = cross(&v1, &v2);
|
|
||||||
|
|
||||||
/* normalise to unit length */
|
|
||||||
scale = 1.0/(sqrt(pow(normal.x, 2.0)+pow(normal.y, 2.0)+pow(normal.z, 2.0))+2.23e-9);
|
|
||||||
normal.x *= scale;
|
|
||||||
normal.y *= scale;
|
|
||||||
normal.z *= scale;
|
|
||||||
fprintf(obj_file, "vn %f %f %f\n", normal.x, normal.y, normal.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* export the face indices */
|
|
||||||
if(keepOnlyUsedVerticesFLAG){
|
|
||||||
for (i = 0; i < nFaces; i++){
|
|
||||||
/* vertices are in same order as the faces, and normals are in order */
|
|
||||||
fprintf(obj_file, "f %u//%u %u//%u %u//%u\n",
|
|
||||||
i*3 + 1, i + 1,
|
|
||||||
i*3+1 + 1, i + 1,
|
|
||||||
i*3+2 + 1, i + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* just normals are in order */
|
|
||||||
for (i = 0; i < nFaces; i++){
|
|
||||||
fprintf(obj_file, "f %u//%u %u//%u %u//%u\n",
|
|
||||||
faces[i*3] + 1, i + 1,
|
|
||||||
faces[i*3+1] + 1, i + 1,
|
|
||||||
faces[i*3+2] + 1, i + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose(obj_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
void convhull_3d_export_m
|
|
||||||
(
|
|
||||||
ch_vertex* const vertices,
|
|
||||||
const int nVert,
|
|
||||||
int* const faces,
|
|
||||||
const int nFaces,
|
|
||||||
char* const m_filename
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
char path[256] = { "\0" };
|
|
||||||
memcpy(path, m_filename, strlen(m_filename));
|
|
||||||
FILE* m_file;
|
|
||||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
|
|
||||||
CV_STRCAT(path, ".m");
|
|
||||||
fopen_s(&m_file, path, "wt");
|
|
||||||
#else
|
|
||||||
m_file = fopen(strcat(path, ".m"), "wt");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* save face indices and vertices for verification in matlab: */
|
|
||||||
fprintf(m_file, "vertices = [\n");
|
|
||||||
for (i = 0; i < nVert; i++)
|
|
||||||
fprintf(m_file, "%f, %f, %f;\n", vertices[i].x, vertices[i].y, vertices[i].z);
|
|
||||||
fprintf(m_file, "];\n\n\n");
|
|
||||||
fprintf(m_file, "faces = [\n");
|
|
||||||
for (int i = 0; i < nFaces; i++) {
|
|
||||||
fprintf(m_file, " %u, %u, %u;\n",
|
|
||||||
faces[3*i+0]+1,
|
|
||||||
faces[3*i+1]+1,
|
|
||||||
faces[3*i+2]+1);
|
|
||||||
}
|
|
||||||
fprintf(m_file, "];\n\n\n");
|
|
||||||
fclose(m_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
void extractVerticesFromObjFile(char* const obj_filename, ch_vertex** out_vertices, int* out_nVert)
|
|
||||||
{
|
|
||||||
FILE* obj_file;
|
|
||||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
|
|
||||||
CV_STRCAT(obj_filename, ".obj");
|
|
||||||
fopen_s(&obj_file, obj_filename, "r");
|
|
||||||
#else
|
|
||||||
obj_file = fopen(strcat(obj_filename, ".obj"), "r");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* determine number of vertices */
|
|
||||||
unsigned int nVert = 0;
|
|
||||||
char line[256];
|
|
||||||
while (fgets(line, sizeof(line), obj_file)) {
|
|
||||||
char* vexists = strstr(line, "v ");
|
|
||||||
if(vexists!=NULL)
|
|
||||||
nVert++;
|
|
||||||
}
|
|
||||||
(*out_nVert) = nVert;
|
|
||||||
(*out_vertices) = (ch_vertex*)malloc(nVert*sizeof(ch_vertex));
|
|
||||||
|
|
||||||
/* extract the vertices */
|
|
||||||
rewind(obj_file);
|
|
||||||
int i=0;
|
|
||||||
int vertID, prev_char_isDigit, current_char_isDigit;
|
|
||||||
char vert_char[256] = { 0 };
|
|
||||||
while (fgets(line, sizeof(line), obj_file)) {
|
|
||||||
char* vexists = strstr(line, "v ");
|
|
||||||
if(vexists!=NULL){
|
|
||||||
prev_char_isDigit = 0;
|
|
||||||
vertID = -1;
|
|
||||||
for(int j=0; j<strlen(line)-1; j++){
|
|
||||||
if(isdigit(line[j])||line[j]=='.'||line[j]=='-'||line[j]=='+'||line[j]=='E'||line[j]=='e'){
|
|
||||||
vert_char[strlen(vert_char)] = line[j];
|
|
||||||
current_char_isDigit = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
current_char_isDigit = 0;
|
|
||||||
if((prev_char_isDigit && !current_char_isDigit) || j ==strlen(line)-2 ){
|
|
||||||
vertID++;
|
|
||||||
if(vertID>4){
|
|
||||||
/* not a valid file */
|
|
||||||
free((*out_vertices));
|
|
||||||
(*out_vertices) = NULL;
|
|
||||||
(*out_nVert) = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
(*out_vertices)[i].v[vertID] = atof(vert_char);
|
|
||||||
memset(vert_char, 0, 256 * sizeof(char));
|
|
||||||
}
|
|
||||||
prev_char_isDigit = current_char_isDigit;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* CONVHULL_3D_ENABLE */
|
|
||||||
|
|
|
||||||
|
|
@ -1012,6 +1012,9 @@ public:
|
||||||
std::size_t size() const {
|
std::size_t size() const {
|
||||||
return m_vertices.size();
|
return m_vertices.size();
|
||||||
}
|
}
|
||||||
|
const Vector3& operator[]( std::size_t i ) const {
|
||||||
|
return m_vertices[i];
|
||||||
|
}
|
||||||
brushsplit_t classify_plane( const Plane3& plane ) const {
|
brushsplit_t classify_plane( const Plane3& plane ) const {
|
||||||
brushsplit_t split;
|
brushsplit_t split;
|
||||||
for( const_iterator i = begin(); i != end(); ++i ){
|
for( const_iterator i = begin(); i != end(); ++i ){
|
||||||
|
|
@ -1084,6 +1087,53 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include "convhull_3d.h"
|
||||||
|
void CSG_build_hull( const MergeVertices& mergeVertices, MergePlanes& mergePlanes ){
|
||||||
|
#if 0
|
||||||
|
/* bruteforce new planes */
|
||||||
|
for( MergeVertices::const_iterator i = mergeVertices.begin() + 0; i != mergeVertices.end() - 2; ++i )
|
||||||
|
for( MergeVertices::const_iterator j = i + 1; j != mergeVertices.end() - 1; ++j )
|
||||||
|
for( MergeVertices::const_iterator k = j + 1; k != mergeVertices.end() - 0; ++k ){
|
||||||
|
const Plane3 plane = plane3_for_points( *i, *j, *k );
|
||||||
|
if( plane3_valid( plane ) ){
|
||||||
|
const brushsplit_t split = mergeVertices.classify_plane( plane );
|
||||||
|
if( ( split.counts[ePlaneFront] == 0 ) != ( split.counts[ePlaneBack] == 0 ) ){
|
||||||
|
if( split.counts[ePlaneFront] != 0 )
|
||||||
|
mergePlanes.insert( MergePlane( plane3_flipped( plane ), *i, *j, *k ) );
|
||||||
|
else
|
||||||
|
mergePlanes.insert( MergePlane( plane, *i, *k, *j ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
const int nVertices = mergeVertices.size();
|
||||||
|
ch_vertex* vertices = ( ch_vertex* )malloc( mergeVertices.size() * sizeof( ch_vertex ) );
|
||||||
|
for( std::size_t i = 0; i < mergeVertices.size(); ++i ){
|
||||||
|
vertices[i].x = static_cast<double>( mergeVertices[i].x() );
|
||||||
|
vertices[i].y = static_cast<double>( mergeVertices[i].y() );
|
||||||
|
vertices[i].z = static_cast<double>( mergeVertices[i].z() );
|
||||||
|
}
|
||||||
|
int* faceIndices = NULL;
|
||||||
|
int nFaces;
|
||||||
|
convhull_3d_build( vertices, nVertices, &faceIndices, &nFaces );
|
||||||
|
/* Where 'faceIndices' is a flat 2D matrix [nFaces x 3] */
|
||||||
|
for( int i = 0; i < nFaces; ++i ){
|
||||||
|
Vector3 p[3];
|
||||||
|
for( int j = 0; j < 3; ++j ){
|
||||||
|
// p[j] = Vector3( vertices[faceIndices[i * 3 + j]].x, vertices[faceIndices[i * 3 + j]].y, vertices[faceIndices[i * 3 + j]].z );
|
||||||
|
p[j] = mergeVertices[faceIndices[i * 3 + j]];
|
||||||
|
}
|
||||||
|
const Plane3 plane = plane3_for_points( p[0], p[1], p[2] );
|
||||||
|
if( plane3_valid( plane ) ){
|
||||||
|
mergePlanes.insert( MergePlane( plane, p[0], p[2], p[1] ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free( vertices );
|
||||||
|
free( faceIndices );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void CSG_WrapMerge( const ClipperPoints& clipperPoints ){
|
void CSG_WrapMerge( const ClipperPoints& clipperPoints ){
|
||||||
const bool primit = ( GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive );
|
const bool primit = ( GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive );
|
||||||
brush_vector_t selected_brushes;
|
brush_vector_t selected_brushes;
|
||||||
|
|
@ -1127,21 +1177,8 @@ void CSG_WrapMerge( const ClipperPoints& clipperPoints ){
|
||||||
mergePlanes.insert( MergePlane( face.getPlane().plane3(), &face ) );
|
mergePlanes.insert( MergePlane( face.getPlane().plane3(), &face ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* bruteforce new planes */
|
|
||||||
for( MergeVertices::const_iterator i = mergeVertices.begin() + 0; i != mergeVertices.end() - 2; ++i )
|
CSG_build_hull( mergeVertices, mergePlanes );
|
||||||
for( MergeVertices::const_iterator j = i + 1; j != mergeVertices.end() - 1; ++j )
|
|
||||||
for( MergeVertices::const_iterator k = j + 1; k != mergeVertices.end() - 0; ++k ){
|
|
||||||
const Plane3 plane = plane3_for_points( *i, *j, *k );
|
|
||||||
if( plane3_valid( plane ) ){
|
|
||||||
const brushsplit_t split = mergeVertices.classify_plane( plane );
|
|
||||||
if( ( split.counts[ePlaneFront] == 0 ) != ( split.counts[ePlaneBack] == 0 ) ){
|
|
||||||
if( split.counts[ePlaneFront] != 0 )
|
|
||||||
mergePlanes.insert( MergePlane( plane3_flipped( plane ), *i, *j, *k ) );
|
|
||||||
else
|
|
||||||
mergePlanes.insert( MergePlane( plane, *i, *k, *j ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//globalOutputStream() << mergePlanes.size() << " mergePlanes.size()\n";
|
//globalOutputStream() << mergePlanes.size() << " mergePlanes.size()\n";
|
||||||
if( mergePlanes.size() < 4 ){
|
if( mergePlanes.size() < 4 ){
|
||||||
|
|
@ -1242,21 +1279,8 @@ void CSG_DeleteComponents(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bruteforce new planes */
|
CSG_build_hull( mergeVertices, mergePlanes );
|
||||||
for( MergeVertices::const_iterator i = mergeVertices.begin() + 0; i != mergeVertices.end() - 2; ++i )
|
|
||||||
for( MergeVertices::const_iterator j = i + 1; j != mergeVertices.end() - 1; ++j )
|
|
||||||
for( MergeVertices::const_iterator k = j + 1; k != mergeVertices.end() - 0; ++k ){
|
|
||||||
const Plane3 plane = plane3_for_points( *i, *j, *k );
|
|
||||||
if( plane3_valid( plane ) ){
|
|
||||||
const brushsplit_t split = mergeVertices.classify_plane( plane );
|
|
||||||
if( ( split.counts[ePlaneFront] == 0 ) != ( split.counts[ePlaneBack] == 0 ) ){
|
|
||||||
if( split.counts[ePlaneFront] != 0 )
|
|
||||||
mergePlanes.insert( MergePlane( plane3_flipped( plane ), *i, *j, *k ) );
|
|
||||||
else
|
|
||||||
mergePlanes.insert( MergePlane( plane, *i, *k, *j ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( mergePlanes.size() < 4 ){
|
if( mergePlanes.size() < 4 ){
|
||||||
globalWarningStream() << "CSG_DeleteComponents: Too few planes left: " << mergePlanes.size() << ".\n";
|
globalWarningStream() << "CSG_DeleteComponents: Too few planes left: " << mergePlanes.size() << ".\n";
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user