[63a589]: src / _oc_polybool.cc Maximize Restore History

Download this file

_oc_polybool.cc    232 lines (231 with data), 8.9 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/* -*- coding: utf-8 -*- */
/* Copyright (C) 2011 José Luis García Pallero, <jgpallero@gmail.com>
*
* This file is part of OctCLIP.
*
* OctCLIP 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.
*
* This program 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 this software; see the file COPYING. If not, see
* <http://www.gnu.org/licenses/>.
*/
/******************************************************************************/
/******************************************************************************/
#define HELPTEXT "\
-*- texinfo -*-\n\
@deftypefn{Loadable Function}{[@var{X},@var{Y},@var{nInt},@var{nPert}] =}\
_oc_polybool(@var{sub},@var{clip},@var{op})\n\
\n\
@cindex Performs boolean operations between two polygons.\n\
\n\
This function performs boolean operations between two polygons using the\n\
Greiner-Hormann algorithm (http://davis.wpi.edu/~matt/courses/clipping/).\n\
\n\
@var{sub} is a two column matrix containing the X and Y coordinates of the\n\
vertices for the subject polygon.\n\n\
@var{clip} is a two column matrix containing the X and Y coordinates of the\n\
vertices for the clipper polygon.\n\n\
@var{op} is a text string containing the operation to perform between\n\
@var{sub} and @var{clip}. Possible values are:\n\
\n\
@itemize @bullet\n\
@item @var{'AND'}\n\
Intersection of @var{sub} and @var{clip}.\n\n\
@item @var{'OR'}\n\
Union of @var{subt} and @var{clip}.\n\n\
@item @var{'AB'}\n\
Operation @var{sub} - @var{clip}.\n\n\
@item @var{'BA'}\n\
Operation of @var{clip} - @var{sub}.\n\
@end itemize\n\
\n\
For the matrices @var{sub} and @var{clip}, the first point is not needed to\n\
be repeated at the end (but is permitted). Pairs of (NaN,NaN) coordinates in\n\
@var{sub} and/or @var{clip} are ommitted.\n\
\n\
@var{X} is a column vector containing the X coordinates of the vertices for.\n\
resultant polygon(s).\n\n\
@var{Y} is a column vector containing the Y coordinates of the vertices for.\n\
resultant polygon(s).\n\n\
@var{nInt} is the number of intersections between @var{sub} and @var{clip}.\n\n\
@var{nPert} is the number of perturbed points of the @var{clip} polygon in\n\
any particular case (points in the oborder of the other polygon) occurs see\n\
http://davis.wpi.edu/~matt/courses/clipping/ for details.\n\
\n\
@end deftypefn"
/******************************************************************************/
/******************************************************************************/
#include<octave/oct.h>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include"octclip.h"
/******************************************************************************/
/******************************************************************************/
#define ERRORTEXT 1000
/******************************************************************************/
/******************************************************************************/
DEFUN_DLD(_oc_polybool,args,,HELPTEXT)
{
//error message
char errorText[ERRORTEXT+1]="_oc_polybool:\n\t";
//output list
octave_value_list outputList;
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
//checking input arguments
if(args.length()!=3)
{
//error text
sprintf(&errorText[strlen(errorText)],
"Incorrect number of input arguments\n\t"
"See help _oc_polybool");
//error message
error(errorText);
}
else
{
//loop index
size_t i=0;
//operation identifier: intersection by default
enum GEOC_OP_BOOL_POLIG op=GeocOpBoolInter;
//number of intersections and perturbations
size_t nInter=0,nPert=0;
//polygons and operation
Matrix subject=args(0).matrix_value();
Matrix clipper=args(1).matrix_value();
std::string opchar=args(2).string_value();
//number of vertices
size_t subjElem=static_cast<size_t>(subject.rows());
size_t clipElem=static_cast<size_t>(clipper.rows());
//polygon coordinates
ColumnVector xSubj(subjElem),ySubj(subjElem);
ColumnVector xClip(subjElem),yClip(subjElem);
//computation vectors
double* xA=NULL;
double* yA=NULL;
double* xB=NULL;
double* yB=NULL;
//double linked lists
vertPoliClip* polA=NULL;
vertPoliClip* polB=NULL;
//output struct
poligGreiner* result=NULL;
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
//copy subject polygon coordinates
for(i=0;i<subjElem;i++)
{
xSubj(i) = subject(i,0);
ySubj(i) = subject(i,1);
}
//copy clipper polygon coordinates
for(i=0;i<clipElem;i++)
{
xClip(i) = clipper(i,0);
yClip(i) = clipper(i,1);
}
//pointers to data
xA = xSubj.fortran_vec();
yA = ySubj.fortran_vec();
xB = xClip.fortran_vec();
yB = yClip.fortran_vec();
//create double linked list for subject polygon
polA = CreaPoliClip(xA,yA,subjElem,1,1);
//error checking
if(polA==NULL)
{
//error text
sprintf(&errorText[strlen(errorText)],
"Error in memory allocation");
//error message
error(errorText);
//exit
return outputList;
}
//create double linked list for clipper polygon
polB = CreaPoliClip(xB,yB,clipElem,1,1);
//error checking
if(polB==NULL)
{
//free peviously allocated memory
LibMemPoliClip(polA);
//error text
sprintf(&errorText[strlen(errorText)],
"Error in memory allocation");
//error message
error(errorText);
//exit
return outputList;
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
//select operation
if((!strcmp(opchar.c_str(),"OR"))||(!strcmp(opchar.c_str(),"or")))
{
op = GeocOpBoolUnion;
}
else if((!strcmp(opchar.c_str(),"AB"))||(!strcmp(opchar.c_str(),"ab")))
{
op = GeocOpBoolAB;
}
else if((!strcmp(opchar.c_str(),"BA"))||(!strcmp(opchar.c_str(),"ba")))
{
op = GeocOpBoolBA;
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
//clipping
result = PoliBoolGreiner(polA,polB,op,GEOC_GREINER_FAC_EPS_PERTURB,
&nInter,&nPert);
//error checking
if(result==NULL)
{
//free peviously allocated memory
LibMemPoliClip(polA);
LibMemPoliClip(polB);
//error text
sprintf(&errorText[strlen(errorText)],
"Error in memory allocation");
//error message
error(errorText);
//exit
return outputList;
}
//output vectors
ColumnVector xResult(result->nElem);
ColumnVector yResult(result->nElem);
//copy output data
for(i=0;i<result->nElem;i++)
{
xResult(i) = result->x[i];
yResult(i) = result->y[i];
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
//output parameters list
outputList(0) = xResult;
outputList(1) = yResult;
outputList(2) = nInter;
outputList(3) = nPert;
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
//free memory
LibMemPoliClip(polA);
LibMemPoliClip(polB);
LibMemPoligGreiner(result);
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
//exit
return outputList;
}