Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,19 @@ Several examples can be watched [HERE](https://youtu.be/pbLVMDj1Zro).

### Windows

Ready to go. The compilation is not required. Use the binary file `bcpd.exe` in the `win` directory.
The binary file was created by GCC included in the 32-bit version of the MinGW system.
Therefore, it might be quite slower than the one compiled in a Mac/Linux system.
Ready to go. The compilation is not required. Use the binary file `bcpd.exe` or `gbcpd.exe` in the `win` directory.

- `bcpd.exe`: Original BCPD executable (32-bit)
- `gbcpd.exe`: Enhanced BCPD executable with PLY support (64-bit)

The `bcpd.exe` binary file was created by GCC included in the 32-bit version of the MinGW system.
The `gbcpd.exe` binary file was created using 64-bit MinGW cross-compiler and includes support for PLY file format.

If you want to compile the Windows version yourself, you can use the following command in a Linux environment with MinGW installed:

```bash
make -f makefile.win
```

### MacOS and Linux

Expand All @@ -154,6 +164,14 @@ For Windows, type the following command in the DOS prompt:

` bcpd -x <target: X> -y <source: Y> (+options) `

Or, if using the enhanced version with PLY support:

` gbcpd -t <target.ply> -s <source.ply> -o <output_prefix> (+options) `

The enhanced version also supports a simplified command format:

` gbcpd <target.ply> <source.ply> <output_prefix> `

Brief instructions are printed by typing `./bcpd -v` (or `bcpd -v` for windows) in the terminal window.
The binary file can also be executed using the `system` function in MATLAB.
See MATLAB scripts in the `demo` folder regarding the usage of the binary file.
Expand All @@ -170,6 +188,9 @@ See MATLAB scripts in the `demo` folder regarding the usage of the binary file.

- `-x [file]`: The target shape represented as a matrix of size N x D.
- `-y [file]`: The source shape represented as a matrix of size M x D.
- `-t [file]`: (Enhanced version) The target shape in PLY format.
- `-s [file]`: (Enhanced version) The source shape in PLY format.
- `-o [prefix]`: (Enhanced version) Output file prefix.

Tab- and comma-separated files are accepted, and the extensions of input files
MUST be `.txt`. If your file is space-delimited, convert it to a tab- or comma-separated file using Excel,
Expand Down
55 changes: 55 additions & 0 deletions base/dummy_lapack.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include <stdio.h>
#include <stdlib.h>

#ifdef USE_DUMMY_LAPACK

// Dummy LAPACK functions
int dgesv_(int *n, int *nrhs, double *a, int *lda, int *ipiv, double *b, int *ldb, int *info) {
*info = -1; // Indicate error
fprintf(stderr, "Error: LAPACK function dgesv_ not available in this build.\n");
return -1;
}

int dsyev_(char *jobz, char *uplo, int *n, double *a, int *lda, double *w, double *work, int *lwork, int *info) {
*info = -1; // Indicate error
fprintf(stderr, "Error: LAPACK function dsyev_ not available in this build.\n");
return -1;
}

int dgesvd_(char *jobu, char *jobvt, int *m, int *n, double *a, int *lda, double *s, double *u, int *ldu, double *vt, int *ldvt, double *work, int *lwork, int *info) {
*info = -1; // Indicate error
fprintf(stderr, "Error: LAPACK function dgesvd_ not available in this build.\n");
return -1;
}

int dposv_(char *uplo, int *n, int *nrhs, double *A, int *lda, double *B, int *ldb, int *info) {
*info = -1; // Indicate error
fprintf(stderr, "Error: LAPACK function dposv_ not available in this build.\n");
return -1;
}

int dpotrs_(char *uplo, int *n, int *nrhs, double *A, int *lda, double *B, int *ldb, int *info) {
*info = -1; // Indicate error
fprintf(stderr, "Error: LAPACK function dpotrs_ not available in this build.\n");
return -1;
}

int dpotrf_(char *uplo, int *n, double *A, int *lda, int *info) {
*info = -1; // Indicate error
fprintf(stderr, "Error: LAPACK function dpotrf_ not available in this build.\n");
return -1;
}

int dpotri_(char *uplo, int *n, double *A, int *lda, int *info) {
*info = -1; // Indicate error
fprintf(stderr, "Error: LAPACK function dpotri_ not available in this build.\n");
return -1;
}

int dgetrf_(int *m, int *n, double *A, int *lda, int *ipiv, int *info) {
*info = -1; // Indicate error
fprintf(stderr, "Error: LAPACK function dgetrf_ not available in this build.\n");
return -1;
}

#endif // USE_DUMMY_LAPACK
38 changes: 38 additions & 0 deletions base/dummy_lapack.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) 2023
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#ifndef DUMMY_LAPACK_H
#define DUMMY_LAPACK_H

#ifdef USE_DUMMY_LAPACK

// Function declarations for dummy LAPACK functions
int dgesv_(int *n, int *nrhs, double *a, int *lda, int *ipiv, double *b, int *ldb, int *info);
int dsyev_(char *jobz, char *uplo, int *n, double *a, int *lda, double *w, double *work, int *lwork, int *info);
int dgesvd_(char *jobu, char *jobvt, int *m, int *n, double *a, int *lda, double *s, double *u, int *ldu, double *vt, int *ldvt, double *work, int *lwork, int *info);
int dposv_(char *uplo, int *n, int *nrhs, double *A, int *lda, double *B, int *ldb, int *info);
int dpotrs_(char *uplo, int *n, int *nrhs, double *A, int *lda, double *B, int *ldb, int *info);
int dpotrf_(char *uplo, int *n, double *A, int *lda, int *info);
int dpotri_(char *uplo, int *n, double *A, int *lda, int *info);
int dgetrf_(int *m, int *n, double *A, int *lda, int *ipiv, int *info);

#endif // USE_DUMMY_LAPACK

#endif // DUMMY_LAPACK_H
52 changes: 52 additions & 0 deletions base/getopt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// getopt.c for Windows
#include <string.h>
#include <stdio.h>

char *optarg;
int optind = 1;
int opterr = 1;
int optopt;

int getopt(int argc, char *const argv[], const char *optstring) {
static int sp = 1;
int c;
char *cp;

if (sp == 1) {
if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
return -1;
else if (strcmp(argv[optind], "--") == 0) {
optind++;
return -1;
}
}

optopt = c = argv[optind][sp];

if (c == ':' || (cp = strchr(optstring, c)) == NULL) {
if (argv[optind][++sp] == '\0') {
optind++;
sp = 1;
}
return '?';
}

if (*(cp + 1) == ':') {
if (argv[optind][sp + 1] != '\0')
optarg = &argv[optind++][sp + 1];
else if (++optind >= argc) {
sp = 1;
return '?';
} else
optarg = argv[optind++];
sp = 1;
} else {
if (argv[optind][++sp] == '\0') {
sp = 1;
optind++;
}
optarg = NULL;
}

return c;
}
20 changes: 20 additions & 0 deletions base/getopt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// getopt.h for Windows
#ifndef GETOPT_H
#define GETOPT_H

#ifdef __cplusplus
extern "C" {
#endif

extern char *optarg;
extern int optind;
extern int opterr;
extern int optopt;

int getopt(int argc, char *const argv[], const char *optstring);

#ifdef __cplusplus
}
#endif

#endif /* GETOPT_H */
117 changes: 117 additions & 0 deletions base/plyreader.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// Copyright (c) 2023
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "rply/rply.h"
#include "util.h"
#include "plyreader.h"

// Structure to hold vertex data during PLY parsing
typedef struct {
double **vertices; // Array to store vertex coordinates
int vertex_count; // Total number of vertices
int current_vertex; // Current vertex being processed
int dimension; // Dimension of vertices (usually 3)
} ply_vertex_data;

// Callback function for vertex elements
static int vertex_cb(p_ply_argument argument) {
long coord;
ply_vertex_data *data;

// Get user data and which coordinate (x, y, z) we're processing
ply_get_argument_user_data(argument, (void **)&data, &coord);

// Get the value of the coordinate
double value = ply_get_argument_value(argument);

// Store the value in our vertex array
if (data->current_vertex < data->vertex_count && coord < data->dimension) {
data->vertices[data->current_vertex][coord] = value;

// If we've processed all coordinates for this vertex, move to the next
if (coord == data->dimension - 1) {
data->current_vertex++;
}
}

return 1;
}

// Function to read PLY file and return vertices as a 2D array
double **read_ply(int *nr, int *nc, const char *file, const char *na) {
p_ply ply;
ply_vertex_data data;
long nvertices;
int i;

// Open PLY file
ply = ply_open(file, NULL, 0, NULL);
if (!ply) {
printf("ERROR: Failed to open PLY file: %s\n", file);
exit(EXIT_FAILURE);
}

// Read PLY header
if (!ply_read_header(ply)) {
printf("ERROR: Failed to read PLY header from file: %s\n", file);
ply_close(ply);
exit(EXIT_FAILURE);
}

// Get number of vertices
nvertices = ply_set_read_cb(ply, "vertex", "x", NULL, NULL, 0);
if (nvertices <= 0) {
printf("ERROR: No vertices found in PLY file: %s\n", file);
ply_close(ply);
exit(EXIT_FAILURE);
}

// Initialize vertex data
data.vertex_count = nvertices;
data.current_vertex = 0;
data.dimension = 3; // Assume 3D points (x, y, z)
data.vertices = calloc2d(nvertices, data.dimension);

// Set callbacks for vertex coordinates
ply_set_read_cb(ply, "vertex", "x", vertex_cb, &data, 0);
ply_set_read_cb(ply, "vertex", "y", vertex_cb, &data, 1);
ply_set_read_cb(ply, "vertex", "z", vertex_cb, &data, 2);

// Read PLY data
if (!ply_read(ply)) {
printf("ERROR: Failed to read PLY data from file: %s\n", file);
free2d(data.vertices, nvertices);
ply_close(ply);
exit(EXIT_FAILURE);
}

// Close PLY file
ply_close(ply);

// Set output parameters
*nr = nvertices;
*nc = data.dimension;

return data.vertices;
}
27 changes: 27 additions & 0 deletions base/plyreader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) 2023
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#ifndef PLYREADER_H
#define PLYREADER_H

// Function to read PLY file and return vertices as a 2D array
double **read_ply(int *nr, int *nc, const char *file, const char *na);

#endif // PLYREADER_H
Loading