Simulink递归接口排布

可以根据输入输出接线递归获取路径上所有模块的句柄批量排布

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
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值