可以根据输入输出接线递归获取路径上所有模块的句柄批量排布
SubHandle: 模块句柄
DistIn: 输入端的距离
DistOut: 输出端的距离
GetBranch: 递归获取句柄的方法
function PortArrRecur(SubHandle,DistIn,DistOut)
% 变体子系统
Parent = get_param(SubHandle,'Parent');
isVs = false;
try
isVs = strcmp(get_param(Parent,'Variant'),'on');
catch
end
Connect = get_param(SubHandle, 'PortConnectivity');
if isVs
VS_Ports = get_param(SubHandle,'PortHandles');
InP = VS_Ports.Inport;
OutP = VS_Ports.Outport;
for i = 1 : length(InP)
SrcBlock = Connect(i).SrcBlock;
pos = get_param(InP(i),'Position');
set_param(SrcBlock,'Position',[pos(1) - DistIn,pos(2) - 5,pos(1) - DistIn + 10,pos(2) + 5]);
end
%matlab变体子系统的输出有bug
DstBlocks = find_system(Parent,'SearchDepth',1,'BlockType','Outport');
for i = 1 : length(OutP)
pos = get_param(OutP(i),'Position');
try
set_param(DstBlocks{i},'Position',[pos(1) + DistOut,pos(2) - 5,pos(1) + DistOut + 10,pos(2) + 5]);
catch
end
end
return
end
%正常子系统
Trace = java.util.HashSet;
LineHandles = get(SubHandle, 'LineHandles');
InOutLines = union(LineHandles.Inport,LineHandles.Outport);
TraceLines = InOutLines;
Ports = get_param(SubHandle,'PortHandles');
Lines = get_param(SubHandle,'LineHandles');
Moved = java.util.HashSet;
OriBlkPos = get_param(SubHandle,'Position');
%输入
for i = 1 : length(Ports.Inport)
try
sp_pos = get(get(Lines.Inport(i),'SrcPortHandle'),'Position');
catch
continue
end
PointLines = [];
Trace.clear();
Trace.add(SubHandle);
pos = get_param(Ports.Inport(i),'Position');
DltX = pos(1) - sp_pos(1) - DistIn;
DltY = pos(2) - sp_pos(2);
SrcBlock = get(Lines.Inport(i),'SrcBlockHandle');
Trace.add(SrcBlock);
[Trace,PointLines,TraceLines] = GetBranch(SrcBlock,Trace,PointLines,TraceLines);
Trace.remove(SubHandle);
iter = Trace.iterator();
DltX = TouchDetec(OriBlkPos,Trace.iterator(),true,DltX,DltY);
for p = 1 : length(PointLines)
LineArrange(PointLines(p),DltX,DltY);
end
while iter.hasNext()
curBlock = iter.next();
if Moved.contains(curBlock)
continue;
end
curPos = get(curBlock,'Position');
set_param(curBlock,'Position',[curPos(1) + DltX,curPos(2) + DltY, ...
curPos(3) + DltX,curPos(4) + DltY]);
Moved.add(curBlock);
end
end
%输出
for i = 1 : length(Ports.Outport)
try
dp_pos = get(get(Lines.Outport(i),'DstPortHandle'),'Position');
catch
continue
end
PointLines = [];
if ~isempty(get_param(Lines.Outport(i),'LineChildren'))
PointLines = union(PointLines,InOutLines(i));
end
Trace.clear();
Trace.add(SubHandle);
pos = get_param(Ports.Outport(i),'Position');
index = 1;
maxBranch = 0;
DstBlocks = get(Lines.Outport(i),'DstBlockHandle');
%DstBlocks可能不止一个
for j = 1 : length(DstBlocks)
Trace.add(DstBlocks(j));
lastSize = size(Trace);
[Trace,PointLines,TraceLines] = GetBranch(DstBlocks(j),Trace,PointLines,TraceLines);
add = size(Trace) - lastSize;
if strcmp(get_param(DstBlocks(j),'BlockType'),'Outport')
add = add + 2;
end
if add > maxBranch
index = j;
maxBranch = add;
end
end
posSize = size(dp_pos);
if posSize(1) == 1
DltX = dp_pos(1) - pos(1) - DistOut;
DltY = dp_pos(2) - pos(2);
else
DltX = dp_pos{index}(1) - pos(1) - DistOut;
DltY = dp_pos{index}(2) - pos(2);
end
Trace.remove(SubHandle);
iter = Trace.iterator();
DltX = TouchDetec(OriBlkPos,Trace.iterator(),false,DltX,DltY);
for p = 1 : length(PointLines)
LineArrange(PointLines(p),-DltX,-DltY);
end
while iter.hasNext()
curBlock = iter.next();
if Moved.contains(curBlock)
continue;
end
curPos = get(curBlock,'Position');
set(curBlock,'Position',[curPos(1) - DltX,curPos(2) - DltY, ...
curPos(3) - DltX,curPos(4) - DltY]);
Moved.add(curBlock);
end
end
try
Simulink.BlockDiagram.routeLine(TraceLines);
catch
end
end
function DltX = TouchDetec(OriBlkPos, iter,isIn,DltX,DltY)
while iter.hasNext()
curBlock = iter.next();
curPos = get(curBlock,'Position');
margin = 10;
if isIn
safeLine = OriBlkPos(1) - margin;
if ~isempty(intersect((OriBlkPos(1) - margin:OriBlkPos(3) + margin),(curPos(1) + DltX:curPos(3) + DltX)))...
&& ~isempty(intersect((OriBlkPos(2) - margin:OriBlkPos(4) + margin),(curPos(2) + DltY:curPos(4) + DltY)))
DltX = safeLine - curPos(3);
end
else
safeLine = OriBlkPos(3) + margin;
if ~isempty(intersect((OriBlkPos(1) - margin:OriBlkPos(3) + margin),(curPos(1) - DltX:curPos(3) - DltX)))...
&& ~isempty(intersect((OriBlkPos(2) - margin:OriBlkPos(4) + margin),(curPos(2) - DltY:curPos(4) - DltY)))
DltX = curPos(1) - safeLine;
end
end
end
end
function LineArrange(Line,DltX,DltY)
Points = get_param(Line,'Points');
newPoints = [Points(1,1),Points(1,2);Points(end,1) + DltX,Points(end,2) + DltY];
set_param(Line,'Points',newPoints);
children = get_param(Line,'LineChildren');
if ~isempty(children)
for i = 1 : length(children)
LineArrange(children(i),DltX,DltY);
end
else
return
end
end