ビルの量産用のノード2つ作成した
はじめに
ビルの量産に使えるノードを2つ作成しました。
作ったノード2つとPoly Extrudeで簡単なビル。#Houdini pic.twitter.com/TB9ae86Z37
— 折登 いつき (@MatchaChoco010) 2018年12月31日
次の資料を参考に作成しました。
Houdini16にHDAを2つ追加したらビルが量産できた(プロシージャルモデリング事始め)
3分割するノード
次のように3分割するノードを作ります。
作成したネットワークは次のとおりです。 上から順に見ていきます。
nullノードにパラメータを集約しています。
2019/09/19 追記
2019/09/19 追記ここまで
最初のswitchはテスト用のジオメトリと入力とを分岐するものです。 テスト時にしか使いません。
blastノードで与えられたグループ以外を削除しています。 この消されなかった部分について処理を行っていきます。
blastノードで与えられたグループを削除しています。 これらをマージすることでグループの範囲内だけ処理が行われます。
以前作成したisRectangleノードを接続します。 与えられたprimitiveが長方形であることを前提とした処理を書いているので、 長方形以外が渡されたらエラーを出すようにしています。
primitive wrangleを接続します。
次のプログラムを記述します。
int pt[];
vector pos[];
for (int i = 0; i < 4; i++) {
pt[i] = primpoint(geoself(), @primnum, i);
pos[i] = point(geoself(), "P", pt[i]);
}
// sort points
// make 0-1 edge the top side
int tmpPt;
vector tmpPos;
while (
!(
pos[0].y >= pos[3].y &&
pos[1].y >= pos[2].y &&
pos[0].y >= pos[2].y &&
pos[1].y >= pos[3].y
)
) {
// shift
tmpPt = pt[0];
tmpPos = pos[0];
pt[0] = pt[1];
pos[0] = pos[1];
pt[1] = pt[2];
pos[1] = pos[2];
pt[2] = pt[3];
pos[2] = pos[3];
pt[3] = tmpPt;
pos[3] = tmpPos;
}
//end sort points
float sizeA = chf("../null1/sizeA");
float sizeB = chf("../null1/sizeB");
float sizeC = chf("../null1/sizeC");
string groupAName, groupBName, groupCName, groupDName;
string gs[] = split(chs("../null1/group"));
if (chi("../null1/groupPrefix") && len(gs) > 0) {
string g = gs[0];
groupAName = g + "_" + chs("../null1/groupAName");
groupBName = g + "_" + chs("../null1/groupBName");
groupCName = g + "_" + chs("../null1/groupCName");
groupDName = g + "_" + chs("../null1/groupDName");
} else {
groupAName = chs("../null1/groupAName");
groupBName = chs("../null1/groupBName");
groupCName = chs("../null1/groupCName");
groupDName = chs("../null1/groupDName");
}
if (chi("../null1/orient") == 0) {
// vertical
// pt[0], topPtA, topPtB, pt[1]
// *---*-----*---*
// | | C | |
// | A | or | B |
// | | D | |
// *---*-----*---*
// pt[3], bottomPtA, bottomPtB, pt[2]
// A
int topPtA, bottomPtA;
topPtA = addpoint(
geoself(),
pos[0] + normalize(pos[1] - pos[0]) * sizeA
);
bottomPtA = addpoint(
geoself(),
pos[3] + normalize(pos[2] - pos[3]) * sizeA
);
int primA = addprim(
geoself(), "poly",
pt[0], topPtA, bottomPtA, pt[3]
);
if (chi("../null1/groupA")) {
setprimgroup(
geoself(), groupAName,
primA, 1
);
}
// B
int topPtB, bottomPtB;
topPtB = addpoint(
geoself(),
pos[1] + normalize(pos[0] - pos[1]) * sizeB
);
bottomPtB = addpoint(
geoself(),
pos[2] + normalize(pos[3] - pos[2]) * sizeB
);
int primB = addprim(
geoself(), "poly",
topPtB, pt[1], pt[2], bottomPtB
);
if (chi("../null1/groupB")) {
setprimgroup(
geoself(), groupBName,
primB, 1
);
}
// C or D
int primCD = addprim(
geoself(), "poly",
topPtA, topPtB, bottomPtB, bottomPtA
);
if (
length(pos[0] - pos[1]) - sizeA - sizeB >= sizeC &&
chi("../null1/groupC")
) {
setprimgroup(
geoself(), groupCName,
primCD, 1
);
} else if (chi("../null1/groupD")) {
setprimgroup(
geoself(), groupDName,
primCD, 1
);
}
// error flag
setdetailattrib(
geoself(), "errorflag",
length(pos[0] - pos[1]) <= sizeA + sizeB, "max"
);
} else {
// horizontal
// pt[0], pt[1]
// *-----*
// | A |
// *-----* ptA0, ptA1
// | C |
// | or |
// | D |
// *-----* ptB0, ptB1
// | B |
// *-----*
// pt[3], pt[2]
// A
int ptA0, ptA1;
ptA0 = addpoint(
geoself(),
pos[0] + normalize(pos[3] - pos[0]) * sizeA
);
ptA1 = addpoint(
geoself(),
pos[1] + normalize(pos[2] - pos[1]) * sizeA
);
int primA = addprim(
geoself(), "poly",
pt[0], pt[1], ptA1, ptA0
);
if (chi("../null1/groupA")) {
setprimgroup(
geoself(), groupAName,
primA, 1
);
}
// B
int ptB0, ptB1;
ptB0 = addpoint(
geoself(),
pos[3] + normalize(pos[0] - pos[3]) * sizeB
);
ptB1 = addpoint(
geoself(),
pos[2] + normalize(pos[1] - pos[2]) * sizeB
);
int primB = addprim(
geoself(), "poly",
ptB0, ptB1, pt[2], pt[3]
);
if (chi("../null1/groupB")) {
setprimgroup(
geoself(), groupBName,
primB, 1
);
}
// C or D
int primCD = addprim(
geoself(), "poly",
ptA0, ptA1, ptB1, ptB0
);
if (
length(pos[0] - pos[3]) - sizeA - sizeB >= sizeC &&
chi("../null1/groupC")
) {
setprimgroup(
geoself(), groupCName,
primCD, 1
);
} else if (chi("../null1/groupD")) {
setprimgroup(
geoself(), groupDName,
primCD, 1
);
}
// error flag
setdetailattrib(
geoself(), "errorflag",
length(pos[0] - pos[3]) <= sizeA + sizeB, "max"
);
}
removeprim(geoself(), @primnum, 1);
errorノードを接続します。 先のprimitive wrangle内でサイズのエラーが有った場合には detailのerrorflagに1が渡されるようになっています。
必要なくなったerrorflagを削除します。
mergeしてfuseして完了です。
パラメータのGroupに対してMenu Scriptを追加します。
def build_menu_from_group(groups, menu):
if len(groups):
menu.extend(("-", ""))
for group in groups:
name = group.name()
menu.extend((name, name))
return menu
sopnode = hou.pwd()
menu = []
if sopnode.inputs():
geo = sopnode.inputs()[0].geometry()
menu = build_menu_from_group(geo.primGroups(), menu)
return menu
これでグループをドロップダウンメニューから選べるようになります。
等分割するノード
(2019年1月11日:プログラムのミスを修正)
次に当分割するノードを作成します。 メイン領域のサイズを指定する他に、分割数でも指定できるようにしました。
パラメータは次のようになっています。
先ほどと同様にしてグループをドロップダウンリストから指定できるようにしました。
ノードは先の3分割のノードとまったく同じ構成です。
primitive wrangleのプログラムが違っています。
int pt[];
vector pos[];
for (int i = 0; i < 4; i++) {
pt[i] = primpoint(geoself(), @primnum, i);
pos[i] = point(geoself(), "P", pt[i]);
}
// sort points
// make 0-1 edge the top side
int tmpPt;
vector tmpPos;
while (
!(
pos[0].y >= pos[3].y &&
pos[1].y >= pos[2].y &&
pos[0].y >= pos[2].y &&
pos[1].y >= pos[3].y
)
) {
// shift
tmpPt = pt[0];
tmpPos = pos[0];
pt[0] = pt[1];
pos[0] = pos[1];
pt[1] = pt[2];
pos[1] = pos[2];
pt[2] = pt[3];
pos[2] = pos[3];
pt[3] = tmpPt;
pos[3] = tmpPos;
}
//end sort points
int mode = chi("../mode1");
if (mode == 0) {
// size mode
float mainSize = ch("../Controller/mainSize");
float spacerMinSize = ch("../Controller/spacerMinSize");
int spacerMode = chi("../Controller/spaceModeSize");
int pt0, pt1;
vector pos0, pos1, vec;
float length;
if (chi("../Controller/orient") == 0) {
// vertical
pt0 = pt[0];
pos0 = pos[0];
pt1 = pt[3];
pos1 = pos[3];
vec = normalize(pos[1] - pos[0]);
length = length(pos[1] - pos[0]);
} else {
// horizontal
pt0 = pt[1];
pos0 = pos[1];
pt1 = pt[0];
pos1 = pos[0];
vec = normalize(pos[2] - pos[1]);
length = length(pos[2] - pos[1]);
}
string groupMainName, groupSpacerName;
string gs[] = split(chs("../Controller/group"));
if (chi("../Controller/groupPrefix") && len(gs) > 0) {
string g = gs[0];
groupMainName = g + "_" + chs("../Controller/mainGroupSizeName");
groupSpacerName = g + "_" + chs("../Controller/spacerGroupSizeName");
} else {
groupMainName = chs("../Controller/mainGroupSizeName");
groupSpacerName = chs("../Controller/spacerGroupSizeName");
}
if (spacerMode == 0) {
// start
if (spacerMinSize + mainSize > length) {
setdetailattrib(geoself(), "errorflag", 1, "max");
return;
}
int count = floor((length - spacerMinSize) / mainSize);
float spacerSize = length - mainSize * count;
float width = mainSize;
vector newPos0 = pos0 + vec * spacerSize;
vector newPos1 = pos1 + vec * spacerSize;
int newPt0 = addpoint(geoself(), newPos0);
int newPt1 = addpoint(geoself(), newPos1);
int prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/spacerGroupSize")) {
setprimgroup(
geoself(),
groupSpacerName,
prim, 1
);
}
pt0 = newPt0;
pt1 = newPt1;
pos0 = newPos0;
pos1 = newPos1;
for (int i = 0; i < count; i++) {
newPos0 = pos0 + vec * width;
newPos1 = pos1 + vec * width;
newPt0 = addpoint(geoself(), newPos0);
newPt1 = addpoint(geoself(), newPos1);
prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/mainGroupSize")) {
setprimgroup(
geoself(),
groupMainName,
prim, 1
);
}
pt0 = newPt0;
pt1 = newPt1;
pos0 = newPos0;
pos1 = newPos1;
}
} else if (spacerMode == 1) {
// end
if (spacerMinSize + mainSize > length) {
setdetailattrib(geoself(), "errorflag", 1, "max");
return;
}
int count = floor((length - spacerMinSize) / mainSize);
float spacerSize = length - mainSize * count;
float width = mainSize;
vector newPos0, newPos1;
int newPt0, newPt1;
int prim;
for (int i = 0; i < count; i++) {
newPos0 = pos0 + vec * width;
newPos1 = pos1 + vec * width;
newPt0 = addpoint(geoself(), newPos0);
newPt1 = addpoint(geoself(), newPos1);
prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/mainGroupSize")) {
setprimgroup(
geoself(),
groupMainName,
prim, 1
);
}
pt0 = newPt0;
pt1 = newPt1;
pos0 = newPos0;
pos1 = newPos1;
}
newPos0 = pos0 + vec * spacerSize;
newPos1 = pos1 + vec * spacerSize;
newPt0 = addpoint(geoself(), newPos0);
newPt1 = addpoint(geoself(), newPos1);
prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/spacerGroupSize")) {
setprimgroup(
geoself(),
groupSpacerName,
prim, 1
);
}
} else if (spacerMode == 2) {
// center
if (spacerMinSize * 2 + mainSize > length) {
setdetailattrib(geoself(), "errorflag", 1, "max");
return;
}
int count = floor((length - spacerMinSize * 2) / mainSize);
float spacerSize = (length - mainSize * count) / 2;
float width = mainSize;
vector newPos0 = pos0 + vec * spacerSize;
vector newPos1 = pos1 + vec * spacerSize;
int newPt0 = addpoint(geoself(), newPos0);
int newPt1 = addpoint(geoself(), newPos1);
int prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/spacerGroupSize")) {
setprimgroup(
geoself(),
groupSpacerName,
prim, 1
);
}
pt0 = newPt0;
pt1 = newPt1;
pos0 = newPos0;
pos1 = newPos1;
for (int i = 0; i < count; i++) {
newPos0 = pos0 + vec * width;
newPos1 = pos1 + vec * width;
newPt0 = addpoint(geoself(), newPos0);
newPt1 = addpoint(geoself(), newPos1);
prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/mainGroupSize")) {
setprimgroup(
geoself(),
groupMainName,
prim, 1
);
}
pt0 = newPt0;
pt1 = newPt1;
pos0 = newPos0;
pos1 = newPos1;
}
newPos0 = pos0 + vec * spacerSize;
newPos1 = pos1 + vec * spacerSize;
newPt0 = addpoint(geoself(), newPos0);
newPt1 = addpoint(geoself(), newPos1);
prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/spacerGroupSize")) {
setprimgroup(
geoself(),
groupSpacerName,
prim, 1
);
}
} else if (spacerMode == 3) {
// space between
int count = floor((length + spacerMinSize) / (mainSize + spacerMinSize));
float spacerSize = (length - mainSize * count) / (count - 1);
float width = mainSize;
if (spacerMinSize + mainSize * 2 > length) {
setdetailattrib(geoself(), "errorflag", 1, "max");
return;
}
vector newPos0, newPos1;
int newPt0, newPt1;
int prim;
for (int i = 0; i < count; i++) {
newPos0 = pos0 + vec * width;
newPos1 = pos1 + vec * width;
newPt0 = addpoint(geoself(), newPos0);
newPt1 = addpoint(geoself(), newPos1);
prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/mainGroupSize")) {
setprimgroup(
geoself(),
groupMainName,
prim, 1
);
}
pt0 = newPt0;
pt1 = newPt1;
pos0 = newPos0;
pos1 = newPos1;
if (i != count - 1) {
newPos0 = pos0 + vec * spacerSize;
newPos1 = pos1 + vec * spacerSize;
newPt0 = addpoint(geoself(), newPos0);
newPt1 = addpoint(geoself(), newPos1);
prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/spacerGroupSize")) {
setprimgroup(
geoself(),
groupSpacerName,
prim, 1
);
}
pt0 = newPt0;
pt1 = newPt1;
pos0 = newPos0;
pos1 = newPos1;
}
}
} else if (spacerMode == 4) {
// space around
int count = floor(length / (mainSize + spacerMinSize));
float spacerSize = (length - mainSize * count) / count;
float width = mainSize;
if (spacerMinSize + mainSize > length) {
setdetailattrib(geoself(), "errorflag", 1, "max");
return;
}
vector newPos0 = pos0 + vec * spacerSize / 2;
vector newPos1 = pos1 + vec * spacerSize / 2;
int newPt0 = addpoint(geoself(), newPos0);
int newPt1 = addpoint(geoself(), newPos1);
int prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/spacerGroupSize")) {
setprimgroup(
geoself(),
groupSpacerName,
prim, 1
);
}
pt0 = newPt0;
pt1 = newPt1;
pos0 = newPos0;
pos1 = newPos1;
for (int i = 0; i < count; i++) {
newPos0 = pos0 + vec * width;
newPos1 = pos1 + vec * width;
newPt0 = addpoint(geoself(), newPos0);
newPt1 = addpoint(geoself(), newPos1);
prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/mainGroupSize")) {
setprimgroup(
geoself(),
groupMainName,
prim, 1
);
}
pt0 = newPt0;
pt1 = newPt1;
pos0 = newPos0;
pos1 = newPos1;
if (i != count - 1) {
newPos0 = pos0 + vec * spacerSize;
newPos1 = pos1 + vec * spacerSize;
newPt0 = addpoint(geoself(), newPos0);
newPt1 = addpoint(geoself(), newPos1);
prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/spacerGroupSize")) {
setprimgroup(
geoself(),
groupSpacerName,
prim, 1
);
}
pt0 = newPt0;
pt1 = newPt1;
pos0 = newPos0;
pos1 = newPos1;
}
}
newPos0 = pos0 + vec * spacerSize / 2;
newPos1 = pos1 + vec * spacerSize / 2;
newPt0 = addpoint(geoself(), newPos0);
newPt1 = addpoint(geoself(), newPos1);
prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/spacerGroupSize")) {
setprimgroup(
geoself(),
groupSpacerName,
prim, 1
);
}
} else {
// grow
if (mainSize > length) {
setdetailattrib(geoself(), "errorflag", 1, "max");
return;
}
int count = floor(length / mainSize);
float width = length / count;
vector newPos0, newPos1;
int newPt0, newPt1;
int prim;
for (int i = 0; i < count; i++) {
newPos0 = pos0 + vec * width;
newPos1 = pos1 + vec * width;
newPt0 = addpoint(geoself(), newPos0);
newPt1 = addpoint(geoself(), newPos1);
prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/mainGroupSize")) {
setprimgroup(
geoself(),
groupMainName,
prim, 1
);
}
pt0 = newPt0;
pt1 = newPt1;
pos0 = newPos0;
pos1 = newPos1;
}
}
} else {
// count mode
int count = chi("../Controller/count");
float spacerSize = ch("../Controller/spacerSize");
int spacerMode = chi("../Controller/spaceModeCount");
int pt0, pt1;
vector pos0, pos1, vec;
float length;
if (chi("../Controller/orient") == 0) {
// vertical
pt0 = pt[0];
pos0 = pos[0];
pt1 = pt[3];
pos1 = pos[3];
vec = normalize(pos[1] - pos[0]);
length = length(pos[1] - pos[0]);
} else {
// horizontal
pt0 = pt[1];
pos0 = pos[1];
pt1 = pt[0];
pos1 = pos[0];
vec = normalize(pos[2] - pos[1]);
length = length(pos[2] - pos[1]);
}
string groupMainName, groupSpacerName;
string gs[] = split(chs("../Controller/group"));
if (chi("../Controller/groupPrefix") && len(gs) > 0) {
string g = gs[0];
groupMainName = g + "_" + chs("../Controller/mainGroupCountName");
groupSpacerName = g + "_" + chs("../Controller/spacerGroupCountName");
} else {
groupMainName = chs("../Controller/mainGroupCountName");
groupSpacerName = chs("../Controller/spacerGroupCountName");
}
if (spacerSize == 0) {
// non-space
float width = length / (float) count;
for (int i = 0; i < count; i++) {
vector newPos0 = pos0 + vec * width;
vector newPos1 = pos1 + vec * width;
int newPt0 = addpoint(geoself(), newPos0);
int newPt1 = addpoint(geoself(), newPos1);
int prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/mainGroupCount")) {
setprimgroup(
geoself(),
groupMainName,
prim, 1
);
}
pt0 = newPt0;
pt1 = newPt1;
pos0 = newPos0;
pos1 = newPos1;
}
} else {
if (spacerMode == 0) {
// start
if (spacerSize >= length) {
setdetailattrib(geoself(), "errorflag", 1, "max");
return;
}
float width = (length - spacerSize)
/ (float) count;
vector newPos0 = pos0 + vec * spacerSize;
vector newPos1 = pos1 + vec * spacerSize;
int newPt0 = addpoint(geoself(), newPos0);
int newPt1 = addpoint(geoself(), newPos1);
int prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/spacerGroupCount")) {
setprimgroup(
geoself(),
groupSpacerName,
prim, 1
);
}
pt0 = newPt0;
pt1 = newPt1;
pos0 = newPos0;
pos1 = newPos1;
for (int i = 0; i < count; i++) {
newPos0 = pos0 + vec * width;
newPos1 = pos1 + vec * width;
newPt0 = addpoint(geoself(), newPos0);
newPt1 = addpoint(geoself(), newPos1);
prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/mainGroupCount")) {
setprimgroup(
geoself(),
groupMainName,
prim, 1
);
}
pt0 = newPt0;
pt1 = newPt1;
pos0 = newPos0;
pos1 = newPos1;
}
} else if (spacerMode == 1) {
// end
if (spacerSize >= length) {
setdetailattrib(geoself(), "errorflag", 1, "max");
return;
}
float width = (length - spacerSize)
/ (float) count;
vector newPos0, newPos1;
int newPt0, newPt1;
int prim;
for (int i = 0; i < count; i++) {
newPos0 = pos0 + vec * width;
newPos1 = pos1 + vec * width;
newPt0 = addpoint(geoself(), newPos0);
newPt1 = addpoint(geoself(), newPos1);
prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/mainGroupCount")) {
setprimgroup(
geoself(),
groupMainName,
prim, 1
);
}
pt0 = newPt0;
pt1 = newPt1;
pos0 = newPos0;
pos1 = newPos1;
}
newPos0 = pos0 + vec * spacerSize;
newPos1 = pos1 + vec * spacerSize;
newPt0 = addpoint(geoself(), newPos0);
newPt1 = addpoint(geoself(), newPos1);
prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/spacerGroupCount")) {
setprimgroup(
geoself(),
groupSpacerName,
prim, 1
);
}
} else if (spacerMode == 2) {
// center
if (spacerSize >= length / 2) {
setdetailattrib(geoself(), "errorflag", 1, "max");
return;
}
float width = (length - spacerSize * 2)
/ (float) count;
vector newPos0 = pos0 + vec * spacerSize;
vector newPos1 = pos1 + vec * spacerSize;
int newPt0 = addpoint(geoself(), newPos0);
int newPt1 = addpoint(geoself(), newPos1);
int prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/spacerGroupCount")) {
setprimgroup(
geoself(),
groupSpacerName,
prim, 1
);
}
pt0 = newPt0;
pt1 = newPt1;
pos0 = newPos0;
pos1 = newPos1;
for (int i = 0; i < count; i++) {
newPos0 = pos0 + vec * width;
newPos1 = pos1 + vec * width;
newPt0 = addpoint(geoself(), newPos0);
newPt1 = addpoint(geoself(), newPos1);
prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/mainGroupCount")) {
setprimgroup(
geoself(),
groupMainName,
prim, 1
);
}
pt0 = newPt0;
pt1 = newPt1;
pos0 = newPos0;
pos1 = newPos1;
}
newPos0 = pos0 + vec * spacerSize;
newPos1 = pos1 + vec * spacerSize;
newPt0 = addpoint(geoself(), newPos0);
newPt1 = addpoint(geoself(), newPos1);
prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/spacerGroupCount")) {
setprimgroup(
geoself(),
groupSpacerName,
prim, 1
);
}
} else if (spacerMode == 3) {
// space between
if (spacerSize >= length / (float) (count - 1)) {
setdetailattrib(geoself(), "errorflag", 1, "max");
return;
}
float width = (length - spacerSize * (count - 1))
/ (float)count;
vector newPos0, newPos1;
int newPt0, newPt1;
int prim;
for (int i = 0; i < count; i++) {
newPos0 = pos0 + vec * width;
newPos1 = pos1 + vec * width;
newPt0 = addpoint(geoself(), newPos0);
newPt1 = addpoint(geoself(), newPos1);
prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/mainGroupCount")) {
setprimgroup(
geoself(),
groupMainName,
prim, 1
);
}
pt0 = newPt0;
pt1 = newPt1;
pos0 = newPos0;
pos1 = newPos1;
if (i != count - 1) {
newPos0 = pos0 + vec * spacerSize;
newPos1 = pos1 + vec * spacerSize;
newPt0 = addpoint(geoself(), newPos0);
newPt1 = addpoint(geoself(), newPos1);
prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/spacerGroupCount")) {
setprimgroup(
geoself(),
groupSpacerName,
prim, 1
);
}
pt0 = newPt0;
pt1 = newPt1;
pos0 = newPos0;
pos1 = newPos1;
}
}
} else {
// space around
if (spacerSize >= length / (float) (count)) {
setdetailattrib(geoself(), "errorflag", 1, "max");
return;
}
float width = (length - spacerSize * count)
/ (float)count;
vector newPos0 = pos0 + vec * spacerSize / 2;
vector newPos1 = pos1 + vec * spacerSize / 2;
int newPt0 = addpoint(geoself(), newPos0);
int newPt1 = addpoint(geoself(), newPos1);
int prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/spacerGroupCount")) {
setprimgroup(
geoself(),
groupSpacerName,
prim, 1
);
}
pt0 = newPt0;
pt1 = newPt1;
pos0 = newPos0;
pos1 = newPos1;
for (int i = 0; i < count; i++) {
newPos0 = pos0 + vec * width;
newPos1 = pos1 + vec * width;
newPt0 = addpoint(geoself(), newPos0);
newPt1 = addpoint(geoself(), newPos1);
prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/mainGroupCount")) {
setprimgroup(
geoself(),
groupMainName,
prim, 1
);
}
pt0 = newPt0;
pt1 = newPt1;
pos0 = newPos0;
pos1 = newPos1;
if (i != count - 1) {
newPos0 = pos0 + vec * spacerSize;
newPos1 = pos1 + vec * spacerSize;
newPt0 = addpoint(geoself(), newPos0);
newPt1 = addpoint(geoself(), newPos1);
prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/spacerGroupCount")) {
setprimgroup(
geoself(),
groupSpacerName,
prim, 1
);
}
pt0 = newPt0;
pt1 = newPt1;
pos0 = newPos0;
pos1 = newPos1;
}
}
newPos0 = pos0 + vec * spacerSize / 2;
newPos1 = pos1 + vec * spacerSize / 2;
newPt0 = addpoint(geoself(), newPos0);
newPt1 = addpoint(geoself(), newPos1);
prim = addprim(geoself(), "poly",
pt0, newPt0, newPt1, pt1);
if (chi("../Controller/spacerGroupCount")) {
setprimgroup(
geoself(),
groupSpacerName,
prim, 1
);
}
}
}
}
removeprim(geoself(), @primnum, 1);
条件分岐がたくさんあってとても長いプログラムになってしまいました。 サイズ指定と個数指定の場合で分岐をしており、さらにスペースの与え方でも分岐をしています。
使用例
作ったノード2つとPoly Extrudeで簡単なビル。#Houdini pic.twitter.com/TB9ae86Z37
— 折登 いつき (@MatchaChoco010) 2018年12月31日
おわりに
いろいろ分岐を用意していたらプログラムがやたらと長くなってしまいました。 hda化したことで一度書くだけで使いまわしできるので hdaのありがたみを味わっています。