Hi All. I wrote a script to import a CAD part into k-wave, and register it to the grid. It will come in as a binary image, with solid "ones" where the part exists (so you can assign a high density there, for example, if the part is to be used as a hard reflector).
The input is a picture of the part (e.g. PNG file, which you can export directly from SolidWorks). The color should be dark, like black. To register the part, you need to input Cartesian coordinates of the top left point on your part, and the width of the part. You can also enter an offset, to locate the part in your grid (e.g.if the top-left coordinate of the part is not where you'd like it to be in the Cartesian space of your K-wave grid.)
I used "interp2" for this, since it seemed to make smoother surfaces than cart2grid. There are also functions in the imaging toolbox one could use, but not everyone has that toolbox.
Code:
function pic=importpic(kgrid,fname,topleft,wid,varargin)
% xoffset, yoffset
% Function to import a .png (or other pic?) file from CAD program.
% Register to kgrid by giving it Cartesian coords for upper left corner,
% and total width.
% "topleft" are x,y coords of point at lowest x and highest y (of the lowest x points), in meters.
% "wid" is dist from left-most to right-most point.
% xoffset and yoffset are desired displacement of drawing origin to kgrid origin.
xoffset=0;yoffset=0;
if nargin>4
xoffset=varargin{1};
end
if nargin>5
yoffset=varargin{2};
end
im=loadImage(fname);
im=im>.2; %set all points in image with values above .2 to one.
% find upper left point in image. Note that image comes in upside down; i.e. the y indices
% go down when the actual y values go up in the original CAD picture. So we need to flip it.
im=flipud(im);
im=im2double(im); %needed for the interp2 function below, if required.
[y,x]=find(im); %get x,y coordinates of the points on the part. (x are column indices, as per matlab convention)
TopLeftx=min(x);
TopLeftxinds=find(x==TopLeftx); %there could be more than one, if left of part has a vertical wall.
TopLefty=max(y(TopLeftxinds)); %now, the coordinates of the upper left corner of part are TopLeftx, TopLefty (actually, the highest
% ...y value for the left-most edge of the part).
% find width of part
maxx=max(x);
imwid=maxx-TopLeftx;
scale=imwid/wid; %scale, in image pixels per meter
% interpolate into kgrid. Find the cartesian grid of image, and offset it if you want.
% ...Find the cart grid of the kgrid space.
% ...Trim the pic if it's outside the kgrid space.
% ...interpolate it onto the grid, using interp2.
szim=size(im);
X1=topleft(1)-(TopLeftx-1)/scale + xoffset;
Xend=topleft(1)+(szim(2)-TopLeftx)/scale + xoffset;
Y1=topleft(2)-(TopLefty-1)/scale + yoffset;
Yend=topleft(2)+(szim(1)-TopLefty)/scale + yoffset;
cartXvec=linspace(X1,Xend,szim(2));
cartYvec=linspace(Y1,Yend,szim(1));
% now trim the sides to match the kgrid xvec and yvec.
xinds=find(cartXvec>=kgrid.x_vec(1) & cartXvec<=kgrid.x_vec(end));
yinds=find(cartYvec>=kgrid.y_vec(1) & cartYvec<=kgrid.y_vec(end));
im2=im(yinds,xinds);
cartXvec2=cartXvec(xinds);
cartYvec2=cartYvec(yinds);
[cartGridx,cartGridy]=meshgrid(cartXvec2,cartYvec2);
% Do the interpolation. Need to adjust for the fact that k-wave puts x in the vertical direction.
pic=interp2(cartGridx,cartGridy,im2,kgrid.x',kgrid.y');
pic=pic';
pic(pic<.5)=0;pic(pic>=.5)=1;