0001 function [newnode,newelem,newelem0]=surfboolean(node,elem,varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 allinputs=varargin;
0053 opt=struct;
0054 if(length(allinputs)>0 && isstruct(allinputs{end}))
0055 opt=allinputs{end};
0056 allinputs{end}=[];
0057 end
0058 len=length(varargin);
0059 newnode=node;
0060 newelem=elem;
0061 if(len>0 && mod(len,3)~=0)
0062 error('you must give operator, node and element in a triplet form');
0063 end
0064
0065 try
0066 exename=evalin('caller','ISO2MESH_SURFBOOLEAN');
0067 catch
0068 try
0069 exename=evalin('base','ISO2MESH_SURFBOOLEAN');
0070 catch
0071 exename='cork';
0072 end
0073 end
0074 isgts=0;
0075 if(strcmp(exename,'gtsset'))
0076 isgts=1;
0077 end
0078
0079 exesuff=fallbackexeext(getexeext,exename);
0080 randseed=hex2dec('623F9A9E');
0081 if(~isempty(getvarfrom({'caller','base'},'ISO2MESH_RANDSEED')))
0082 randseed=getvarfrom({'caller','base'},'ISO2MESH_RANDSEED');
0083 end
0084
0085 for i=1:3:len
0086 op=varargin{i};
0087 no=varargin{i+1};
0088 el=varargin{i+2};
0089 opstr=op;
0090 if(strcmp(op,'or')) opstr='union'; end
0091 if(strcmp(op,'xor')) opstr='all'; end
0092 if(strcmp(op,'and'))
0093 if(isgts)
0094 opstr='inter';
0095 else
0096 opstr='isct';
0097 end
0098 end
0099 if(strcmp(op,'-')) opstr='diff'; end
0100 if(strcmp(op,'self')) opstr='inter -s'; end
0101 if(isgts && (strcmp(op,'first') || strcmp(op,'second') || strcmp(op,'+')))
0102 opstr='all';
0103 end
0104 if(strcmp(opstr,'all') && isgts==0)
0105 opstr='resolve';
0106 end
0107 tempsuff='gts';
0108 if(isgts==0)
0109 tempsuff='off';
0110 end
0111 deletemeshfile(mwpath(['pre_surfbool*.' tempsuff]));
0112 deletemeshfile(mwpath('post_surfbool.off'));
0113 if(strcmp(opstr,'all'))
0114 deletemeshfile(mwpath('s1out2.off'));
0115 deletemeshfile(mwpath('s1in2.off'));
0116 deletemeshfile(mwpath('s2out1.off'));
0117 deletemeshfile(mwpath('s2in1.off'));
0118 end
0119 if(strcmp(op,'decouple'))
0120 if(exist('node1','var')==0)
0121 node1=node;
0122 elem1=elem;
0123 newnode(:,4)=1;
0124 newelem(:,4)=1;
0125 end
0126 opstr=[' --decouple-inin 1 --shells 2'];
0127 saveoff(node1(:,1:3),elem1(:,1:3),mwpath('pre_decouple1.off'));
0128 if(size(no,2)~=3)
0129 opstr=['-q --shells ' num2str(no)];
0130 cmd=sprintf('cd "%s" && "%s%s" "%s" %s',mwpath,mcpath('meshfix'),exesuff,...
0131 mwpath('pre_decouple1.off'),opstr);
0132 else
0133 saveoff(no(:,1:3),el(:,1:3),mwpath('pre_decouple2.off'));
0134 cmd=sprintf('cd "%s" && "%s%s" "%s" "%s" %s',mwpath,mcpath('meshfix'),exesuff,...
0135 mwpath('pre_decouple1.off'),mwpath('pre_decouple2.off'),opstr);
0136 end
0137 elseif(strcmp(op,'decoupleout'))
0138 if(exist('node1','var')==0)
0139 node1=node;
0140 elem1=elem;
0141 newnode(:,4)=1;
0142 newelem(:,4)=1;
0143 end
0144 opstr=[' --decouple-outout 1 --shells 2'];
0145 saveoff(node1(:,1:3),elem1(:,1:3),mwpath('pre_decouple1.off'));
0146 if(size(no,2)~=3)
0147 opstr=['-q --shells ' num2str(no)];
0148 cmd=sprintf('cd "%s" && "%s%s" "%s" %s',mwpath,mcpath('meshfix'),exesuff,...
0149 mwpath('pre_decouple1.off'),opstr);
0150 else
0151 saveoff(no(:,1:3),el(:,1:3),mwpath('pre_decouple2.off'));
0152 cmd=sprintf('cd "%s" && "%s%s" "%s" "%s" %s',mwpath,mcpath('meshfix'),exesuff,...
0153 mwpath('pre_decouple1.off'),mwpath('pre_decouple2.off'),opstr);
0154 end
0155 elseif(strcmp(op,'separate'))
0156 if(exist('node1','var')==0)
0157 node1=node;
0158 elem1=elem;
0159 newnode(:,4)=1;
0160 newelem(:,4)=1;
0161 end
0162 opstr=[' --shells 2'];
0163 saveoff(node1(:,1:3),elem1(:,1:3),mwpath('pre_decouple1.off'));
0164 if(size(no,2)~=3)
0165 opstr=['-q --shells ' num2str(no)];
0166 cmd=sprintf('cd "%s" && "%s%s" "%s" %s',mwpath,mcpath('meshfix'),exesuff,...
0167 mwpath('pre_decouple1.off'),opstr);
0168 else
0169 saveoff(no(:,1:3),el(:,1:3),mwpath('pre_decouple2.off'));
0170 cmd=sprintf('cd "%s" && "%s%s" "%s" "%s" %s',mwpath,mcpath('meshfix'),exesuff,...
0171 mwpath('pre_decouple1.off'),mwpath('pre_decouple2.off'),opstr);
0172 end
0173 else
0174 if(isgts)
0175 savegts(newnode(:,1:3),newelem(:,1:3),mwpath(['pre_surfbool1.' tempsuff]));
0176 savegts(no(:,1:3),el(:,1:3),mwpath(['pre_surfbool2.' tempsuff]));
0177 cmd=sprintf('cd "%s" && "%s%s" %s "%s" "%s" -v > "%s"',mwpath,mcpath('gtsset'),exesuff,...
0178 opstr,mwpath('pre_surfbool1.gts'),mwpath('pre_surfbool2.gts'),mwpath('post_surfbool.off'));
0179 else
0180 saveoff(newnode(:,1:3),newelem(:,1:3),mwpath(['pre_surfbool1.' tempsuff]));
0181 saveoff(no(:,1:3),el(:,1:3),mwpath(['pre_surfbool2.' tempsuff]));
0182 cmd=sprintf('cd "%s" && "%s%s" %s%s "%s" "%s" "%s" -%d',mwpath,mcpath(exename),exesuff,'-',...
0183 opstr,mwpath(['pre_surfbool1.' tempsuff]),mwpath(['pre_surfbool2.' tempsuff]),mwpath('post_surfbool.off'),randseed);
0184 end
0185 end
0186 [status outstr]=system(cmd);
0187 if(status~=0 && strcmp(op,'self')==0)
0188 error(sprintf('surface boolean command failed:\n%s\nERROR: %s\n',cmd,outstr));
0189 end
0190 if(status~=0 && strcmp(op,'self') && ~isempty(strfind(outstr,'(new_ear): assertion failed')))
0191 fprintf(1,'no self-intersection was found! (ignore the above error)\n');
0192 newnode=[];
0193 newelem=[];
0194 newelem0=[];
0195 return;
0196 end
0197 if(strcmp(opstr,'all'))
0198
0199 [nnode nelem]=readoff(mwpath('s1out2.off'));
0200 newelem=[nelem ones(size(nelem,1),1)];
0201 newnode=[nnode ones(size(nnode,1),1)];
0202
0203 [nnode nelem]=readoff(mwpath('s1in2.off'));
0204 newelem=[newelem; nelem+size(newnode,1) 3*ones(size(nelem,1),1)];
0205 newnode=[newnode; nnode 3*ones(size(nnode,1),1)];
0206
0207 [nnode nelem]=readoff(mwpath('s2out1.off'));
0208 newelem=[newelem; nelem+size(newnode,1) 2*ones(size(nelem,1),1)];
0209 newnode=[newnode; nnode 2*ones(size(nnode,1),1)];
0210
0211 [nnode nelem]=readoff(mwpath('s2in1.off'));
0212 newelem=[newelem; nelem+size(newnode,1) 4*ones(size(nelem,1),1)];
0213 newnode=[newnode; nnode 4*ones(size(nnode,1),1)];
0214 if(isgts)
0215 if(strcmp(op,'first'))
0216 newelem=newelem(find(mod(newelem(:,4),2)==1),:);
0217 [newnode,nelem]=removeisolatednode(newnode,newelem(:,1:3));
0218 newelem=[nelem newelem(:,4)];
0219 elseif(strcmp(op,'second'))
0220 newelem=newelem(find(mod(newelem(:,4),2)==0),:);
0221 [newnode,nelem]=removeisolatednode(newnode,newelem(:,1:3));
0222 newelem=[nelem,newelem(:,4)];
0223 end
0224 end
0225 elseif(strcmp(op,'decouple'))
0226 [newnode,newelem]=readoff(mwpath('pre_decouple1_fixed.off'));
0227
0228
0229 elseif(strcmp(op,'separate'))
0230 [newnode,newelem]=readoff(mwpath('pre_decouple1_fixed.off'));
0231 elseif(strcmp(op,'decoupleout'))
0232 [newnode,newelem]=readoff(mwpath('pre_decouple1_fixed.off'));
0233 else
0234 [newnode,newelem]=readoff(mwpath('post_surfbool.off'));
0235 if(strcmp(op,'self'))
0236 fprintf(1,'a total of %d self-intersecting elements were found\n',size(newelem,1));
0237 if(nargout>=3)
0238 [found,newelem0]=ismember(newnode,node,'rows');
0239 if(~all(found))
0240 error('self intersecting elements contain new nodes');
0241 end
0242 newelem0=newelem0(newelem);
0243 end
0244 return;
0245 end
0246 end
0247 end