Hello,
Is there any way to input convex / concave assets for corners in the built in "Building from patterns" generator ? It used to be the case in the previous building generator, but I don't see how to do that here.
Thanks a lot
Francis
Building from patterns convex / concave corners
4236 9 2- Francis Bievre
- Member
- 13 posts
- Joined: Jan. 2014
- Offline
- Francis Bievre
- Member
- 13 posts
- Joined: Jan. 2014
- Offline
- Francis Bievre
- Member
- 13 posts
- Joined: Jan. 2014
- Offline
About the corners, there is a mistake in the code that does not allow for left and right corners to be used.
To correct this, allow modifications on the building generator node, then go inside and look for the "place pieces" node. Go inside it and look for the "grammar_expansion1" node.
In this node, you'll see this
Left and right corners should work properly
To correct this, allow modifications on the building generator node, then go inside and look for the "place pieces" node. Go inside it and look for the "grammar_expansion1" node.
In this node, you'll see this
CC_L = _corners[0]; CC_R = _corners[0]; Replace by this CC_L = _corners[0]; CC_R = _corners[1];
Left and right corners should work properly
Edited by Francis Bievre - Oct. 31, 2022 14:17:35
- Francis Bievre
- Member
- 13 posts
- Joined: Jan. 2014
- Offline
So I've been trying to modify the building tool to get it to work with convex / concave corners.
I think I'm pretty close, even though my solution is messy, but I started Houdini and Vex like a week ago so ...
I managed to isolate the convex corners, and I want to change their attribute to the right module, but I can't find the proper way to write this in Vex.
I want (in English):
I made an image to explain this clearly.
The code I have now is this and does not work. it copies the last value from the "bonjour" attribute, which is "K" in this case.
Any help would be appreciated. I can share the final set up with you when it works.
Thanks
I think I'm pretty close, even though my solution is messy, but I started Houdini and Vex like a week ago so ...
I managed to isolate the convex corners, and I want to change their attribute to the right module, but I can't find the proper way to write this in Vex.
I want (in English):
If (@group_concave==1) then "getvalue from attribute A (which is the module name)" and "Use it to read a value from this module" then "give this value to this point in the "module_name" attribute"
I made an image to explain this clearly.
The code I have now is this and does not work. it copies the last value from the "bonjour" attribute, which is "K" in this case.
s[]@_bonjour = uniquevals(1, "prim", "module_conc"); foreach(string yo; s[]@_bonjour) { int _refprim = findattribval(1, "prim", "module_conc", yo, 0 ); string _conc[] = prim(1, "module_conc", _refprim); if(@group_concave==1) { setpointattrib(0, "module_name", @ptnum, _conc, "set"); }}
Any help would be appreciated. I can share the final set up with you when it works.
Thanks
Edited by Francis Bievre - Oct. 31, 2022 14:17:20
- Francis Bievre
- Member
- 13 posts
- Joined: Jan. 2014
- Offline
Ok, I don't know how but I did it :p
The labs building system now works with convex and concave corners.
My code is not very good as I began Houdini and vex a week ago, but here it is anyways for anyone having the same issue in the future.
byyyyye
The labs building system now works with convex and concave corners.
My code is not very good as I began Houdini and vex a week ago, but here it is anyways for anyone having the same issue in the future.
// get name of concave modules s[]@_concavenames = uniquevals(1, "prim", "module_conc"); // get name of current floor s[]@etage = pointattrib(0, "floorpattern", @ptnum, 0); // LOOP THROUGH EACH CONCAVE MODULE NAME AND PRINT NAMES foreach(string concavename; s[]@_concavenames) { int _refprim = findattribval(1, "prim", "module_conc", concavename, 0 ); // GET BASE NODE NUMBER (PRIM) foreach(string etage; s[]@etage) { int _refprimconc = findattribval(1, "prim", "module_name", etage, 0 ); // PRINT VALUE RETURNED IN "HELLO" ATTRIBUTE TO TEST i@hello = _refprimconc ; // REPLACE CORNER MODULE BY CONCAVE if(@group_concave==1) { // string value of the concave module for current floor ; last value / number is the primitive number (node where info is)(1=C) string _concaveA[] = prim(1, "module_conc", _refprimconc); string _concaveB[] = prim(1, "module_concave", _refprimconc); // TEST NAME RETURNED AND PRINT IN "ConcaveA" Attribute setpointattrib(0, "concaveA", @ptnum, _concaveA[0], "set"); // TEST IF CONCAVE MODULE IS PRESENT int concavemodulespresent = (_concaveA[0] != "" && _concaveB[1] != "") ? 1 : 0; // REPLACE CONVEX BY CONCAVE IF VALUE OF CONCAVEMODULEPRESENT = 1 if(concavemodulespresent==1) { // REPLACE ATTRIBUTE IN "MODULE_NAME" BY OUR CONCAVE MODULE ATTRIBUTE setpointattrib(0, "module_name", @ptnum, _concaveA[0], "set"); setpointattrib(0, "module_name", @ptnum-1, _concaveB[1], "set"); }}}}
byyyyye
Edited by Francis Bievre - Nov. 1, 2022 11:57:43
- Kosuke
- Member
- 1 posts
- Joined: April 2017
- Offline
Hi Francis,
I have been digging into building generator then I encountered convex, concave corner problem.
That was when I found your approach to solve this.
Thank you so much for dealing with this issue, it is mind blowing that you did it in a matter of a week of learning houdini!
I tried the method you mentioned here.
However I am unable to replicate the same result.
Do you possibly have some bandwidth to explain more or share the hip file by any chance?
Thank you so much for your dedication, and I am looking forward to hearing from you.
I have been digging into building generator then I encountered convex, concave corner problem.
That was when I found your approach to solve this.
Thank you so much for dealing with this issue, it is mind blowing that you did it in a matter of a week of learning houdini!
I tried the method you mentioned here.
However I am unable to replicate the same result.
Do you possibly have some bandwidth to explain more or share the hip file by any chance?
Thank you so much for your dedication, and I am looking forward to hearing from you.
Edited by Kosuke - Jan. 20, 2023 19:27:26
- moferad
- Member
- 19 posts
- Joined: Feb. 2013
- Offline
- Francis Bievre
- Member
- 13 posts
- Joined: Jan. 2014
- Offline
Hey, I don't remember exactly what I did sorry, but the solution above was not right. It replaced corners alright but didn't take into account the relative sizes of corners. Found a new one, much simpler since then.
If you want to trace my steps, what you need to do is :
- create a concave input (besides the corners input) on the building utility node
- into that node, there is a wrangle node defining variables, add concave variables, same way as corners variables are currently added
- into the building generator > place pieces node, add a tree finding out if a corner is concave or convex, write the answer into a point attribute, then convert it to a primitive attribute
- into the grammar expansion node, which is the node defining which point is what, edit the code to replace corners by concave corners if a segment (i.e prim) has a concave attribute. The segments are read from 1 to XXX so if segment 1 is concave and not segment 0, you know which corners are concave, and which are not. In this case, a few if statements should do the trick.
Here is my current code for that node. Please note that it won't work for you, as it uses variables I created as specified above. You should replace my variables by yours.
+ what I've done so far with the tool : https://www.youtube.com/watch?v=Z6ImSSJe9nQ [www.youtube.com]
If you want to trace my steps, what you need to do is :
- create a concave input (besides the corners input) on the building utility node
- into that node, there is a wrangle node defining variables, add concave variables, same way as corners variables are currently added
- into the building generator > place pieces node, add a tree finding out if a corner is concave or convex, write the answer into a point attribute, then convert it to a primitive attribute
- into the grammar expansion node, which is the node defining which point is what, edit the code to replace corners by concave corners if a segment (i.e prim) has a concave attribute. The segments are read from 1 to XXX so if segment 1 is concave and not segment 0, you know which corners are concave, and which are not. In this case, a few if statements should do the trick.
Here is my current code for that node. Please note that it won't work for you, as it uses variables I created as specified above. You should replace my variables by yours.
+ what I've done so far with the tool : https://www.youtube.com/watch?v=Z6ImSSJe9nQ [www.youtube.com]
float seed = chf("seed"); f@__length = primintrinsic(0, "measuredperimeter", @primnum); string pattern = chs("pattern"); string CC_L = chs("cc_l"); string CC_R = chs("cc_r"); string CONC_L = chs("cc_l"); string CONC_R = chs("cc_r"); string GetRandomModule(string input; float seed) { // Gathering data per module int __refpt= findattribval(1, "point", "name", input, 0); string _variations[] = point(1, "variations", __refpt); float _variationsweights[] = point(1, "weights", __refpt); return _variations[sample_discrete(_variationsweights, rand(seed))]; } if (chi("orientation") == 0) { s@name = GetRandomModule(s@name, seed * 482824); s@conc = GetRandomModule(s@concaveA, seed * 482824); int lookup = findattribval(1, "point", "name", s@name, 0); i@lookupname = lookup ; pattern = point(1, "expanded_form", lookup); string _corners[] = point(1, "corners", lookup); string _concaves[] = point(1, "concave", lookup); CC_L = _corners[0]; CC_R = _corners[1]; s@CC_R = CC_R ; // ajouter une condition d'appartenance au groupe concave CONC_L = _concaves[0]; CONC_R = _concaves[1]; s@CONC_R = CONC_R ; s@CONC_L = CONC_L ; //Test if previous segement is concave i@prev_seg = inprimgroup(0, "concavePRIM", @primnum-1); i@curr_seg = inprimgroup(0, "concavePRIM", @primnum); i@next_seg = inprimgroup(0, "concavePRIM", @primnum+1); f@concave_test = @prev_seg + @next_seg + @curr_seg ; i@replace_L = @concave_test-@next_seg ; i@replace_R = @concave_test-@prev_seg ; //f@replace_L = @concave_test ; } s[]@__segments[0] = CC_L; // replace module by LEFT CONCAVE if ( @replace_L == 2) { s[]@__segments[0] = CONC_L ; } //Test if previous segement is concave i@prev_seg = inprimgroup(0, "concavePRIM", @primnum-1); i@curr_seg = inprimgroup(0, "concavePRIM", @primnum); i[]@__repeatable[0] = 0; i[]@__corner; int cornermodulespresent = (CC_L != "" && CC_R != "") ? 1 : 0; int segmentindex = (cornermodulespresent) ? 1 : 0; int repeat = 0; string prevmodule = ""; for (int i = 0; i<len(pattern); i++) { string _token = pattern[i]; if (_token == "<") { if (prevmodule != "" && prevmodule != ">") segmentindex++; repeat = 1; } else if (_token == ">") { segmentindex++; repeat = 0; } else { s@__segments[segmentindex] += _token; i@__repeatable[segmentindex] = repeat; } prevmodule = _token; } // Expand any expressions foreach (int _index; string segment; s[]@__segments){ string _segmentstack = ""; string _segmentsubstack = ""; prevmodule = ""; for (int i = 0; i<len(segment); i++) { string _token = segment[i]; if (_token == "[") { _segmentstack += _segmentsubstack; _segmentsubstack = ""; } else if (_token == "]") { string _nexttoken = segment[clamp(i+1, 0, len(segment))]; if (isdigit(_nexttoken) == 1) { string _out = ""; for (int j=0; j < atoi(_nexttoken); j++) _out += "-"+_segmentsubstack; _segmentstack += _out; _segmentsubstack = ""; } } else { if (prevmodule == "]" && isdigit(_token) == 1 ) { } else { _segmentsubstack += _token; } } prevmodule = _token; } _segmentstack += _segmentsubstack; s[]@__segments[_index] = _segmentstack; } resize(i[]@__corner, len(s[]@__segments)); if (cornermodulespresent == 1) { // replace module by right corner ir corner module present //if (@group_concavePRIM==1) { push(s[]@__segments, CONC_R); } //if (@group_concavePRIM==0){push(s[]@__segments, CC_R);} if ( @replace_R != 2) { push(s[]@__segments, CC_R); } if ( @replace_R == 2) {push(s[]@__segments, CONC_R); } resize(i[]@__corner, len(s[]@__segments)); push(i[]@__repeatable, 0); i[]@__corner[0] = 1; i[]@__corner[-1] = 1; }
Edited by Francis Bievre - May 15, 2023 10:01:37
- byshiyi
- Member
- 1 posts
- Joined: Aug. 2021
- Offline
- Francis Bievre
- Member
- 13 posts
- Joined: Jan. 2014
- Offline
By memory.
Into the place pieces node, you add a specific section designed to determine if a corner is concave or convex. Sides of the buildings are segments, and segments are divided into points. First and last points of a segment are the corners.
You must determine if these points are convex or concave. That will be a point attribute.
The grammar expansion node uses prims to determine where to put corners (in the code already in place). So you convert your point attribute (convex / concave) into a prim attribute and feed that info into the wrangle node (grammar expansion). You then use it to determine what module goes where.
Into the place pieces node, you add a specific section designed to determine if a corner is concave or convex. Sides of the buildings are segments, and segments are divided into points. First and last points of a segment are the corners.
You must determine if these points are convex or concave. That will be a point attribute.
The grammar expansion node uses prims to determine where to put corners (in the code already in place). So you convert your point attribute (convex / concave) into a prim attribute and feed that info into the wrangle node (grammar expansion). You then use it to determine what module goes where.
-
- Quick Links