GDL
About building parametric objects with GDL.
SOLVED!

Multiple nested IF-THEN commands to simulate AND/OR

Jim Allen
Expert

Just when I think I've got the hang of these, I get a really complicated one I can't seem to fix.

 

GDL has no IFS or AND/OR/NOT options, so every condition has to be covered with a separate if statement.

I can make this work - up to a point. More than a couple of combinations and my script fails.

 

I want to script something like:

If option 1 is true, then if option 2 is also true - do x, but if option 1 is true and option 2 is not true - do y.

 

What almost worked is this:

 

if detailOpt_2D_1=1 then 															! if draw chamber selected AND
	if 	detailOpt_2D=1 then															! if draw outer wall also selected AND
		if drawConnectors=1 then ui_pict "GDL_UI_2d_4_1", 240, 60, 210, 190, 1		! if connectors also selected -> ui picture: cover + chamber + wall + connectors **works**
		else		
		if drawConnectors=0 then ui_pict "GDL_UI_2d_4", 240, 60, 210, 190, 1		! if connectors not selected -> ui picture: cover + chamber + wall  **doesn't work**
	if detailOpt_2D=0	then														! OR if draw outer wall not selected  
		if drawConnectors=1 then ui_pict "GDL_UI_2d_2_1", 240, 60, 210, 190, 1		! if connectors also selected -> ui picture: cover + chamber with connectors  **works**		
		if drawConnectors=0 then ui_pict "GDL_UI_2d_2", 240, 60, 210, 190, 1		! if connectors not selected -> ui picture: cover + chamber **works**	
	endif
	endif
endif	

	if detailOpt_2D_1=0 then 															! if draw chamber not selected AND
	if 	detailOpt_2D=1 then															! if draw outer wall selected AND
		if drawConnectors=1 then ui_pict "GDL_UI_2d_3_1", 240, 60, 210, 190, 1		! if connectors selected -> ui picture: cover + wall + connectors **works**
		else		
		if drawConnectors=0 then ui_pict "GDL_UI_2d_3", 240, 60, 210, 190, 1		! if connectors not selected -> ui picture: cover + wall **doesn't work**
	if detailOpt_2D=0	then														! OR if draw wall not selected 
		if drawConnectors=1 then ui_pict "GDL_UI_2d_1_1", 240, 60, 210, 190, 1		! if connectors also selected -> ui picture: cover + connectors **works**
		if drawConnectors=0 then ui_pict "GDL_UI_2d_1", 240, 60, 210, 190, 1		! if connectors not selected -> ui picture: cover **works**
	endif
	endif
endif	

 

 You'll need to paste this into  a document with a wider display to see the structure properly.

 

This is what the dialog looks like:

Screenshot 2024-01-09 at 17.27.11.png

I want to display different UI pictures in the interface depending on a combination of user options.

 

The ELSE lines are screwing it up - everything else seems to work.

 

I've tried breaking it down into distinct separate lines, but the combinations of options are problematic.

 

I've been wrestling with this for hours now and everything I do to it just makes it worse!

 

What am I doing wrong?

 

 

 

 

 

 

Archicad 27 UKI | OS X 12.7.1 Monterey
1 ACCEPTED SOLUTION

Accepted Solutions
Solution
Miha Nahtigal
Advocate

What do you mean by "GDL has no IFS or AND/OR/NOT options"?

 

GDL does have AND, OR and NOT structure (not() is a function).

BIMquants.comBETA - Quantities and Costs Estimation with Archicad AddOn :: rushing to publish a beta preview

View solution in original post

7 REPLIES 7
Solution
Miha Nahtigal
Advocate

What do you mean by "GDL has no IFS or AND/OR/NOT options"?

 

GDL does have AND, OR and NOT structure (not() is a function).

BIMquants.comBETA - Quantities and Costs Estimation with Archicad AddOn :: rushing to publish a beta preview

Really?

For some reason I haven't seen that in the reference, and I've looked at a lot of documentation about   - thanks!

Archicad 27 UKI | OS X 12.7.1 Monterey
MF BIM
Booster

Hi @Jim Allen ,

 

Why not use some kind of bitset ? Seems like you don't have that many options and they all are boolean so you can just create boolean variables that you set at 0 or 1 then you calculate the overall score and according to that total, you display what you need ?

 

 

Option_A = 1
Option_B = 1
Option_C = 0
Option_D = 0

SCORE = Option_A + Option_B*2 + Option_C*4 + Option_D*8

if SCORE = 0 then ui_pict
if SCORE = 1 then ui_pict
! ...
if SCORE = 15 then ui_pict

 

 

Probably more verbose but it's likely cleaner at the end than many IF with AND or OR

You could even use the BITSET function even though in my opinion, the syntax of that function makes it more complicated than flat out using boolean variables.

 

 

SCORE = 0
dim my_list[4]
	my_list[1] = 1	! true 
	my_list[2] = 1	! true
	my_list[3] = 0	! false
	my_list[4] = 0	! false

for option = 1 to vardim1(my_list)
	SCORE = bitset(SCORE, option - 1, my_list[option])
next option

if SCORE = 0 then ui_pict
if SCORE = 1 then ui_pict
! ...
if SCORE = 15 then ui_pict

 

 

https://mfbim.fr | https://youtube.com/@mfbim
AC21 FRA 3005 - AC24 FRA 7600 - AC26 FRA 4027 | MacBook M1 Pro
Lingwisyer
Guru

Why is the ELSE even there? Your description of the IF statement following it says that it should include "Wall", but it since it is after the ELSE, it only queries when detailOp_2D is 0... This also makes the "IF detailOpt_2d = 0" redundant, unless it is more than just a boolean?

 

if detailOpt_2D_1=1 then 										! Chamber
	if detailOpt_2D=1 then											! Wall
			if drawConnectors=1 then ui_pict "GDL_UI_2d_4_1", 240, 60, 210, 190, 1				! Connector	
			if drawConnectors=0 then ui_pict "GDL_UI_2d_4", 240, 60, 210, 190, 1				! No Connector
		else												! No Wall
			if drawConnectors=1 then ui_pict "GDL_UI_2d_2_1", 240, 60, 210, 190, 1				! Connector		
			if drawConnectors=0 then ui_pict "GDL_UI_2d_2", 240, 60, 210, 190, 1				! No Connector	
	endif
endif	

if detailOpt_2D_1=0 then 										! No Chamber
	if detailOpt_2D=1 then											! Wall
			if drawConnectors=1 then ui_pict "GDL_UI_2d_3_1", 240, 60, 210, 190, 1				! Connector		
			if drawConnectors=0 then ui_pict "GDL_UI_2d_3", 240, 60, 210, 190, 1				! No Connector
		else												! No Wall 
			if drawConnectors=1 then ui_pict "GDL_UI_2d_1_1", 240, 60, 210, 190, 1				! Connector
			if drawConnectors=0 then ui_pict "GDL_UI_2d_1", 240, 60, 210, 190, 1				! No Connector
	endif
endif	




Ling.

AC22-23 AUS 7000Help Those Help You - Add a Signature
Self-taught, bend it till it breaksCreating a Thread
Win11 | i9 10850K | 64GB | RX6600 Win10 | R5 2600 | 16GB | GTX1660

I know  it seems to make no sense, but if I take it out, more things break!

 

I've  never seen any documentation anywhere mentioning using AND/OR in flow control statements, but they work really well and I think are a great solution to complex flow control statements.

 

I made it work properly using this:

	! --------------- select UI picture based on dialog options -----------------------
	if detailOpt_2D_1=0 AND detailOpt_2D=1 AND drawConnectors=1 then ui_pict "GDL_UI_2d_3_1", 240, 60, 210, 190, 1	
	if detailOpt_2D_1=0 AND detailOpt_2D=1 AND drawConnectors=0 then ui_pict "GDL_UI_2d_3", 240, 60, 210, 190, 1	
	if detailOpt_2D_1=0 AND detailOpt_2D=0 AND drawConnectors=1 then ui_pict "GDL_UI_2d_1_1", 240, 60, 210, 190, 1	
	if detailOpt_2D_1=0 AND detailOpt_2D=0 AND drawConnectors=0 then ui_pict "GDL_UI_2d_1", 240, 60, 210, 190, 1	

	if detailOpt_2D_1=1 AND detailOpt_2D=1 AND drawConnectors=1 then ui_pict "GDL_UI_2d_4_1", 240, 60, 210, 190, 1	
	if detailOpt_2D_1=1 AND detailOpt_2D=1 AND drawConnectors=0 then ui_pict "GDL_UI_2d", 240, 60, 210, 190, 1	
	if detailOpt_2D_1=1 AND detailOpt_2D=0 AND drawConnectors=1 then ui_pict "GDL_UI_2d_2_1", 240, 60, 210, 190, 1	
	if detailOpt_2D_1=1 AND detailOpt_2D=0 AND drawConnectors=0 then ui_pict "GDL_UI_2d_2", 240, 60, 210, 190, 1

It's so much easier to read and script - much, much cleaner, and works perfectly.

 

Elsewhere I was able to replace this: 

if ZZYZX<0.901 then	
	if max(numBranches, numBranches2)=3 then 		! if depth>0.9 AND 3 branches on 1 side
		ChamberLength=1.03 
	else											! otherwise if 						
		if  max(numBranches, numBranches2)>3 then	! there are >3 branches on any side
		ChamberLength=1.37							
		else 	
		ChamberLength= 0.8
		endif
	endif
endif

with this:

if ZZYZX<0.901 AND max(numBranches, numBranches2)<3 then ChamberLength=0.8
if ZZYZX<0.901 AND max(numBranches, numBranches2)=3 then ChamberLength=1.03 
if ZZYZX<0.901 AND max(numBranches, numBranches2)>3 then ChamberLength=1.37 
if ZZYZX>0.9 AND max(numBranches, numBranches2)<4 then ChamberLength=1.25 
if ZZYZX>0.9 AND max(numBranches, numBranches2)>3 then ChamberLength=1.37 

Which works much better.

 

However I really like MF BIM's bitset approach - I might be using that for my next object 😀

Archicad 27 UKI | OS X 12.7.1 Monterey

That's a really interesting approach I hadn't thought of - thanks!

Archicad 27 UKI | OS X 12.7.1 Monterey
Peter Baksa
Graphisoft
Graphisoft

Hi,

 

if-else is not as flexible in GDL as in other languages.

There are two kind of if statements: single-line and multi-line.

Multi-line if must have this form (newlines are important, indentation is not):

 

if condition then
statement
[else
statement]
endif

 

When statement is on the same line as if, it is considered a single-line if, and the else might belong to an other if than you intended:

 

if condition1 then
if condition2 then statement1
else ! this belongs to condition1 because the previous line is a one-line if, no matter how you indent this line
statament2
endif

 

 

 

 

Péter Baksa
Software Engineer, Library as a Platform
Graphisoft SE, Budapest